Don’t delete the credential yet. Let me walk through the complete fix for your IAM policy scoping and service credential permissions issues.
First, verify your service credential’s current access:
ibmcloud iam service-id SERVICE_ID_NAME
ibmcloud iam service-policies SERVICE_ID_NAME
For IAM policy scoping with multiple buckets, you have two approaches:
-
Wildcard approach (simpler for automated backup integration):
Create a policy with resource type ‘bucket’ and use ‘*’ for resource ID. This grants access to all buckets in the instance.
-
Explicit listing (more secure):
Create separate policies for each bucket ARN:
- crn:v1:bluemix:public:cloud-object-storage:global:a/ACCOUNT_ID:instance/INSTANCE_ID:bucket:backup-bucket-prod
- crn:v1:bluemix:public:cloud-object-storage:global:a/ACCOUNT_ID:instance/INSTANCE_ID:bucket:backup-bucket-dr
For service credential permissions, the issue is that instance-level Writer role doesn’t automatically grant bucket access when bucket-level policies exist. Here’s the fix:
-
Remove the instance-level Writer role from the service credential
-
Create bucket-level policies instead:
- Grant ‘Writer’ role on each bucket resource
- Include ‘Object Writer’ role for object operations
-
Add service-to-service authorization:
ibmcloud iam authorization-policy-create \
SERVICE_NAME cloud-object-storage \
Writer --target-service-instance-id INSTANCE_ID
For the automated backup integration, ensure your backup script uses the HMAC credentials correctly. The AccessDenied error often happens when the signature doesn’t match due to clock skew or incorrect endpoint URLs.
Verify your backup script is using:
- Private endpoint if running within IBM Cloud (faster, no egress charges)
- Correct region-specific endpoint
- HMAC credentials from the service credential (not API key directly)
After updating policies, wait 5-10 minutes for propagation. The service credential itself doesn’t need regeneration - the policies control access. Test with a manual backup run before scheduling:
s3cmd put test-file.txt s3://backup-bucket-prod/ \
--access_key=HMAC_ACCESS_KEY \
--secret_key=HMAC_SECRET_KEY
If you still see AccessDenied after policy updates, check the Activity Tracker logs. They’ll show exactly which policy evaluation failed and why. Look for events with action ‘cloud-object-storage.object.create’ and outcome ‘failure’.
One gotcha: if you’re using resource groups, make sure the service credential has Viewer role on the resource group itself, in addition to the bucket policies. This is required for the credential to even see the buckets exist.
The key principle here is that IAM policy scoping for service credentials needs to be explicit about resources. Instance-level roles are convenient but don’t play well with bucket-level policies. For production automated backup integration, always use bucket-level policies with service-to-service authorization.