Migrate broad API keys through a measured permission inventory
Replace a widely shared workspace credential with scoped workers while keeping recovery, financial reads and revocation under deliberate control.
Build a local authorization matrix for permission inheritance, resource scopes and cross-workspace denials before rolling out delegated credentials.
Child-key safety is transitive: a child cannot grant authority that its parent does not possess, and a grandchild cannot recover authority that an earlier delegation removed. Write this as an invariant over effective permissions and reachable resources. A useful test exercises endpoint behavior, not only the shape of a permission object.
Lupin documents both parts of the ceiling: permissions and resource scope. An explicitly broader map or a scope outside the parent’s project or inbox is rejected. Omitting permissions inherits the parent’s effective authority, so an omission test is essential; otherwise a client can mistake inherited breadth for an empty permission set.
Use a local database fixture with two workspaces, two projects in the first workspace and a second inbox outside the chosen project. Populate only synthetic records. Create a parent policy that has a small known set of permissions and a restricted scope, then exercise child and grandchild creation through the actual authorization path.
Keep fixture identifiers separate from production credentials and resource references. No live registration, inbox creation or paid provider call is needed to evaluate this invariant. The test runner should inject provider stubs and fail if an unexpected network request escapes the local boundary.
First prove that a child with a permitted subset can perform its intended authorized read. Then request an extra permission, another project, another inbox and another workspace. Each denial should leave no credential with broader effective authority. Include the inherited-permissions case as a positive test with the expected parent ceiling.
Continue one level deeper using the restricted child as creator. A grandchild must not regain a permission removed from the child even if the original workspace owner possessed it. That scenario catches implementations that accidentally consult an ancestor’s broad policy instead of the immediate creator’s effective policy.
Financial visibility and key-management operations deserve their own rows in the matrix. Lupin’s budget management requires an appropriate workspace key; inbox scope cannot read financial data. A successful message read therefore does not imply that the same child should enumerate workspace spending or create another broad key.
Also test resource access after a denied lookup. The API may use not_found for a protected resource. Your assertion should verify lack of access without depending on disclosure of another tenant’s existence. Error handling must not then retry with a more privileged ambient credential.
For every row, record creator scope, requested child scope, effective permission expectation and allowed or denied endpoint behavior. Use actual authorization checks rather than a helper that merely repeats the production permission arithmetic. This makes the fixture valuable when a new permission or scope twin is introduced.
Run the matrix before credential migrations and after changes to delegated-key creation. A green local result establishes the tested policy behavior, not proof that a deployed secret reached the correct consumer. Pair it with a read-only inspection of the replacement credential’s returned scope during rollout, and keep bearer values out of test reports.
Reviewed against the checked-in Lupin implementation and official reference documentation on 2026-11-05. Operational examples are illustrative; no live paid action, provider mutation or external message was executed.
Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.