I’ve implemented OCIR authentication for Container Engine multiple times. Here’s the complete solution addressing all the IAM components:
Dynamic Group OCID: Your dynamic group matching rule needs to correctly identify Container Engine worker nodes. The rule should match on the cluster or instance pool:
Any {instance.compartment.id = 'ocid1.compartment.oc1..xxxxx',
resource.type = 'cluster'}
Or if you want to be more specific, match the exact cluster OCID:
Any {resource.id = 'ocid1.cluster.oc1.iad.xxxxx'}
Verify your dynamic group is correctly identifying instances by checking the “Matching Resources” section in the OCI Console.
IAM Policy Syntax: The policy needs the correct verb and resource type. For pulling images from OCIR, use:
Allow dynamic-group container-instances to read repos in tenancy
Or scope it to a specific compartment:
Allow dynamic-group container-instances to read repos in compartment MyCompartment where target.repo.name='myapp'
The key points:
- Use
read repos not read repositories - the resource type is `repos
- If images are in the root compartment or a different compartment than your cluster, use `in tenancy
- The verb
read is sufficient for pulling images; manage is only needed for pushing
OCI Registry Permissions: OCIR requires authentication even with IAM policies. Container Engine automatically uses instance principal authentication, but you need to ensure:
- The dynamic group is created BEFORE deploying pods
- The policy grants access to the specific repository or all repos
- The image path in your deployment matches exactly: `.ocir.io//:
Audit Log Review: Check what’s actually being denied:
oci audit event list --compartment-id <tenancy-ocid> \
--start-time 2025-04-28T00:00:00Z \
--end-time 2025-04-28T23:59:59Z \
--query "data[?contains(response-payload, '403')]" \
--all
Look for events with eventName like GetRepository or ReadRepository. The audit log will show:
- The actual identity making the request (should be your dynamic group)
- The exact resource being accessed
- The specific permission that was denied
In your case, the issue is likely that your policy uses read repos in compartment but OCIR repositories might be in a different compartment or at the tenancy level. Change your policy to:
Allow dynamic-group container-instances to read repos in tenancy
This grants access to all repositories across all compartments. If you want to restrict access, use the where clause to limit by repository name.
After updating the policy, wait 1-2 minutes for it to propagate, then delete and recreate your pods to retry the image pull. The 403 errors should resolve once the dynamic group and policy are correctly configured.