Check scope before adding permissions
1
Check the credential's account
Service account and role tokens belong to an account. Confirm that it
matches the requested account. Changing
X-Account-Id does not move the
identity; use an explicit AssumeRole exchange for another account.A non-owner human must choose an assigned account role. Their personal
Workspace policies do not grant ordinary account operations.2
Check the policy domain
Organization actions (
workspace:*, billing:*, quota:*, and audit:*)
need organization policies. Account service actions need account policies.
A wildcard in the wrong domain is ineffective.A role session uses the role’s own account policies and organization
grants, not the source principal’s permissions.3
Check explicit deny and allow
A matching explicit deny wins in the evaluated domain. Without a matching
allow, access is denied. For a user, organization policies include group
policies. Service accounts never inherit group policies.
4
Check the resource CRN
Account IAM resources contain the account handle. Workspace resources
contain the organization UUID in the path. Global means an empty region
slot; it does not mean an empty account slot.Resource CRNs use immutable names for roles, service accounts, and policies.
Trust principals bind concrete machine identities to immutable UUIDs.
Copy the appropriate returned identity instead of guessing its shape.
5
Check conditions, boundaries, and session policy
A session policy can only narrow permissions. Account boundaries cap
account permissions, while Workspace user boundaries cap organization
permissions. Neither policy domain can be used to widen the other.Check condition keys, values, and whether a requested resource has the tags
the policy expects. A missing value can make an otherwise matching allow
ineffective.
An assigned role cannot be assumed
Check both gates. The user needs a direct or group assignment for the target role, and the role’s trust must accept their Workspace user principal CRN. For a machine source, replace the assignment check withiam:AssumeRole on the
target role in the source account policy.
For cross-account assumption, use the target account’s full role CRN. Trust
must identify the source account and immutable source principal correctly.
Cross-organization role assumption is not supported.
Organization delegation is denied
Attaching an organization policy requires Workspace permission on the policy and IAM permission to update the target role or service account. Both must be held by the same caller. An account administrator with no organization grants cannot grant those to itself. The same protection applies to sensitive changes to an identity that already carries organization grants. See organization delegation.Errors that can be misleading
404 where you expected 403
404 where you expected 403
A resource outside your organization or selected account can return
404
to avoid confirming its existence. Check scope as well as the UUID.A revocation succeeds and still returns 403
A revocation succeeds and still returns 403
The session revoke endpoint checks
iam:RevokeSession, then reads the
session for its response with iam:GetSTSSession. Grant both. With only
the first permission, revocation can succeed before the read is denied.An attachment grants access to only one side
An attachment grants access to only one side
Managed policy attachment requires both policy and target resource
permission. A grant on only policy CRNs or only identity CRNs is incomplete.
See IAM attachments
and Workspace permissions.
A condition typo broadens a deny
A condition typo broadens a deny
Unknown operators do not match allow statements. For a deny with matching
action and resource, an unknown operator fails closed. Check operator
spelling when a deny is broader than expected.
Collection access and membership reads
A top-level list authorizes a collection CRN, not individual rows. A policy on one role does not grantListRoles. Relationship lists instead authorize
their parent. See listing.
The region catalog is public. Token exchange verifies credentials. Humans can
read organizations they belong to through membership; machines need
workspace:GetOrganization. These checks differ from ordinary account
resource permissions.
What the audit log does and does not show
The audit log records successful IAM and Workspace mutations — who attached which policy to whom, who created a role, who removed a user. That is what you want for an access review, and it is queryable throughGET /v1/audit-logs.
Sign-in events are the exception that does record failures — a failed
two-factor enrolment or a removed security key is audited either way, because
the failure is the interesting half.
Read event identities
Audit logs have no console page. Use the API to inspect the event identities and retained labels. The event’scrn identifies the audit record itself, in the authenticated
organization. Its final segment is the event’s id.
actor_crn and resource_crn identify the actor and target as they were at
event time. These snapshots do not change when a name changes or a resource
is deleted.
actor_name, actor_email and resource_name are optional retained labels.
Use them for display, not to construct an identity. They can remain available
after the actor or target has been deleted; handle absent or null labels.
For example, an API response can contain this audit record:
null CRNs. A target
that could not be resolved from event-time data also has a null resource_crn,
such as a password reset for an unknown email address. When a target UUID is
known, it is retained in details.resource_id; do not substitute that UUID or
a display label for a missing CRN.
An API record without snapshots or retained labels can look like this:
actor_crn identifies the role, such as
crn:iam::production:role/deployer. The optional details.actor_session_crn, shaped as
crn:iam::production:sts-session/<id>, correlates the event with its AssumeRole call.
Next
Permissions
Every action, and the resource each is checked against.
Writing policies
Conditions, operators, and what a missing key does.