Service accounts
Long-lived access keys for scripts and CI.
Roles
Permissions something else borrows, gated by a trust policy.
Temporary credentials
Assume a role, optionally scoped down further.
Instance identity
A VM that gets credentials with no secret to deploy.
Service accounts
A service account is a non-human identity that holds access keys. Create one, give it permissions, then create a credential on it:- Console
- API
- CLI
- Go
Go to Identity & access → Service accounts and choose Create Service Account.
Under Service Account Details, give it a Name — lowercase letters,
numbers and hyphens, starting with a letter — and optionally a
Description.On the service account itself, the Credentials card has Create
Credential: a Name, and an Expires At you can leave empty for a
credential that does not expire.The secret then appears in a Credential Created dialog, with Copy
access key ID and Copy secret access key. That dialog is the only
place it is ever shown.
access_key_id and secret_access_key.
A service account starts with no permissions. Attach account policies directly;
service accounts do not join groups. Use the separate organization policy table
only when it needs organization access, such as reading billing usage.
- Console
- API
- CLI
- Go
On the service account’s Policies tab, choose Attach account policy
in Account policies. Organization grants use Attach organization
policy in the separate Organization policies table.
Roles
A role is a set of permissions with no credentials of its own. Something else assumes it and gets temporary credentials that authorize as the role. A role has two halves:Permission policies
What the role can do in its account, plus any separately delegated
organization policies.
Trust policy
Who is allowed to assume it. Without this, nobody can.
Trust policies
The trust policy lists CRN patterns matched against the caller’s own CRN:principals gates who; conditions gates under what circumstances.
Both must hold.
Role and service-account principals include their owning account handle.
When you save a concrete named IAM principal, it is bound to that identity’s
immutable UUID. Deleting an identity and recreating its name does not inherit
its trust. Human trust accepts a specific username or crn:workspace:::user/*
for all users in the selected organization. Numeric user IDs remain valid during
initial username selection.
Groups are not principals that can assume a role. Use user trust together with
a group role assignment. Trust only applies within the role’s organization;
cross-organization role assumption is not supported.
* is the only wildcard and the colon/slash layout is compared literally. A
pattern written in any other shape matches nothing — it does not fail loudly,
it simply never matches, so check the shape when a trust policy seems to be
ignored.Assuming a role
AssumeRole has two independent gates: the source must be allowed to performiam:AssumeRole on the target role, and the target’s trust policy must accept
the source. For humans, an account role assignment supplies the source allow.
For service accounts and role sessions, grant the source action in an account
policy.
Use the target account’s full role CRN for cross-account access within your
organization. A source policy can name that role even though it is in a different
account. Changing X-Account-Id alone never grants that access.
The console automatically assumes your single assigned role when you select
an account. Direct and group assignments may grant the same role; conflicting
distinct roles in one account are rejected. For
integrations, IAM’s POST /v1/assume-role accepts role, optional
duration_seconds, and an optional session policy. Use a qualified role CRN
such as crn:iam::production:role/deploy.
The response includes access_token, expiration, account_id,
account_handle, and role_id. Verify the target binding before using
Authorization: Bearer <access_token> for account API requests.
The accompanying access_key_id, secret_access_key, and session_token are
for S3 Signature Version 4. See authentication.
The role session authorizes as the target role. It does not inherit or union
the source principal’s permissions.
900–43200, default 3600
15 minutes to 12 hours, also bounded by the role’s maximum session duration.
Scoping a session down
policy on the assume-role call attaches a session policy to the
credentials being minted:
INVALID_INPUT rather than being
ignored.
Watching sessions
Open Identity & access → STS sessions for the selected account. Sessions show the target account and role, expiry, grant type, and source principal provenance. Older sessions can have missing source fields. The corresponding IAM endpoints areGET /v1/sts-sessions,
GET /v1/sts-sessions/{session_id}, and
DELETE /v1/sts-sessions/{session_id}. Deleting a session revokes it.
Authorization re-checks expiry and revocation. Personal sign-in sessions are
managed through authentication endpoints, not this account resource list.
The session resource returns role, source_principal, source_account, and parent_session as resource references when applicable. Web-identity sessions identify their identity_provider and verified subject instead of a synthetic principal. A reference keeps its identity if the source is deleted; its display name is then absent.
Giving an instance an identity
The role and instance must belong to the same account. The caller attaching it needsiam:PassRole as well as the compute action. If the role has
organization policy grants, passing it also requires organization delegation
authority; account administration alone cannot transfer those grants.
This is the reason roles are worth the setup: an instance can hold credentials
without any secret being deployed to it.
1
Write a trust policy that accepts instances
2
Attach permission policies to the role
Whatever the workload actually needs — and no more, since anything running
on the instance can reach these credentials.
3
Launch the instance with the role
- Console
- API
- CLI
- Go
On Compute → Instances → Create instance, the IAM role card
has a Role select. It defaults to No role.
4
Read credentials from inside the VM
The instance metadata service at
169.254.169.254 mints and serves
temporary credentials for the attached role. They rotate before expiry, so
a process that re-reads them keeps working indefinitely.Nothing secret is ever written to the instance. The metadata service
identifies the caller by which instance it is, mints a session against the
attached role, and hands back credentials that expire on their own.
Which identity to use
CI pipeline
CI pipeline
A service account with an access key, stored in the CI secret store.
Scope it to the account and the actions the pipeline needs. If the pipeline
does several unrelated things, prefer several service accounts over one
broad key.
Software running on an instance
Software running on an instance
An instance role. No secret is deployed, credentials rotate on their
own, and revoking access is a change to the role rather than a redeploy.
A person doing operational work
A person doing operational work
Their personal sign-in and an assigned account role. Use temporary
role credentials for account operations; keep organization work in their
personal Workspace session.
Granting temporary elevated access
Granting temporary elevated access
A role with a trust policy and source permission or human assignment, plus a short
duration_seconds. The assumption is recorded as an STS session, so the
elevation is visible and revocable rather than implicit.Next
Writing policies
What to put in a role’s permission policies.
Permission boundaries
A role’s boundary caps its sessions too.
Trusting an OIDC provider
Register an OIDC provider in the same account as the role that will trust it. A provider has an immutable name and HTTPS issuer URL, plus allowed audiences. Customer providers must publish public OIDC discovery and JWKS endpoints.- Console
- API
Open IAM → OIDC providers → Create provider. Enter a name,
the issuer URL and one allowed audience per line, then save.
basalt:webidentity:Subject to the intended workload.
For GitHub, use the exact sub from your workflow token, including immutable
owner/repository IDs when present. This illustrative subject permits one branch:
basaltic-iam-sts. Exchange it through
POST /v1/assume-role-with-web-identity, without existing Basaltic credentials:
account field.
Provider registration and role trust are separate: the token must pass both.
GitHub trust requires a positive subject restriction to an organization or
repository. Session labels do not change the verified subject.
Use PATCH /v1/oidc-providers/{provider_id} to update audiences, description
or tags. Audience changes affect new exchanges immediately. Deleting a provider
blocks new exchanges; existing sessions remain valid until expiration or
revocation. Recreating its name requires updating role trust. Providers marked
is_system are managed by the platform and cannot be edited or deleted.
