Removing a Baked-In API Key Without Breaking a Running Fleet
Vantage Retail has four compartments - prod, stage, shared-data and sandbox - in a single tenancy. Forty compute instances in prod read objects from a bucket in shared-data and upload logs to a bucket there as well. Because the first deployment was rushed, the application authenticates with an API signing key belonging to a user in the sandbox compartment, baked into a custom image and referenced by a boot-volume script. An auditor also found a tenancy-level policy reading "allow any-user to manage all-resources in tenancy", left over from a proof of concept. The team wants to remove the user and the key without breaking the running fleet - and without widening access in order to do it.
1. Design the credential-free replacement using instance principals and dynamic groups. Where do the policies go, and how narrow can you make them?
Read the worked answer
Dynamic groups let the instances authenticate as themselves, so nothing long-lived is stored on the host.
- Create a dynamic group in the tenancy with a matching rule selecting exactly the prod instances:
instance.compartment.id = 'ocid1.compartment.oc1..prod', or a tag-based rule such astag.project.role.value = 'claims-app'if the prod compartment also hosts unrelated instances. Prefer the tag-based rule when the compartment is not dedicated. - Write policies in the compartment that owns the resources, not the one that owns the instances. Policies are evaluated against where the bucket lives:
allow dynamic-group prod-app-instances to read objects in compartment shared-data(list + get)allow dynamic-group prod-app-instances to manage objects in compartment shared-datafor the log uploads- add
read bucketsonly if the application enumerates buckets
- Place the statement at the tenancy root only if it must span several compartments; otherwise scope it to shared-data to keep the blast radius small.
- The instances then use instance principal authentication through the CLI/SDK - no key file, no config file, no secret in the image.
- Roll out in batches and confirm a canary instance can both read the data bucket and write the log bucket before anything touches the old credential.
2. Give the order of operations for removing the user and key with minimal outage, including what you would do about the compromise itself.
Read the worked answer
Order matters: removing the key first will break the fleet mid-deploy.
- Create the dynamic group and the narrow policies.
- Deploy the instance-principal version to a canary instance in prod; verify the read on the data bucket and the write to the log bucket using the instance's own identity.
- Roll the remainder of the fleet. Leave the old credential in place but unused until the rollout is verified.
- Disable the originating user rather than deleting it immediately - disabling is reversible, stops the credential working instantly, and tells you within minutes whether anything still depends on it.
- Delete the API signing key, plus any auth tokens, customer secret keys and console password for that user; then delete or repurpose the account.
- Rebuild the custom image with the key material removed. If the key stays in the image, every future instance re-introduces the leak.
Treat the key as compromised, not merely misplaced: it was readable from boot volumes and embedded in an image. Pull Audit logs for that user/API key over its whole lifetime, look for calls from unexpected source IPs, for IAM or bucket policy changes, and for resources created under that identity. Then add a preventive control: no credential material in images, and a policy review gate on principals with manage rights.
3. Why is the tenancy-level statement "allow any-user to manage all-resources in tenancy" a serious finding, and what is the correct remediation?
Read the worked answer
- It grants every principal in the tenancy full control of every resource in every compartment - including sandbox users and any federated identity mapped into the tenancy. A low-privilege account becomes a tenancy administrator. It also obscures every application's real permissions, so the effective policy set can no longer be reasoned about.
- OCI IAM is additive and has no explicit deny, so this cannot be neutralised by writing a narrower statement. It must be deleted; the deletion is the control.
Remediation:
- Delete the statement (record who added it and when, from Audit).
- Replace it with group-based statements scoped to a compartment and a resource family, e.g.
allow group app-admins to manage instances in compartment prodandallow group data-scientists to use object-family in compartment sandbox. - If a proof of concept genuinely needs breadth, isolate it in its own compartment or tenancy and keep
any-userfor one narrowly defined resource type, with an expiry date recorded in the change ticket. - Re-review all root-level policies: every subject should be a group, dynamic group or service principal, and every scope should be a compartment rather than the tenancy unless there is a documented reason.
- Check Audit to see whether the statement was ever exercised, and by whom.