A service account is a non-interactive credential for automation such as CI pipelines, scripts and infrastructure-as-code tools. It belongs to one organization and acts as its own principal, service_account:<service-account-id>. Its access is checked exactly like a user’s: it can do what its role assignments allow, and nothing else.
A service account authenticates with an OAuth 2.0 client ID and client secret, using the client credentials grant against the platform’s identity provider. The resulting access token is sent to the API like a user’s.
Before you begin
Create a service account
-
Create the service account with a name that tells you what uses it.
terminal origin iam create-service-account --org-id <org-id> --name ci-deployThe output contains the service account’s
id, itsprincipal, and the credential:clientIdandclientSecret. -
Grant the service account the roles it needs. A new service account holds no roles and can’t do anything until you assign one. Use the
principalfrom the previous step.terminal origin iam assign-role --org-id <org-id> \ --project-id <project-id> \ --principal service_account:<service-account-id> \ --role-urn urn:origin:cloud:iam::::tc/role/roles/viewerGrant the smallest role and scope that does the job. See Assign and revoke roles.
-
Verify that the service account is listed as active. An active service account has no
revokedAtvalue.terminal origin iam list-service-accounts --org-id <org-id>
Get an access token
The origin CLI logs in people only. Automation that runs as a service account calls the GraphQL API directly.
-
Request an access token from the token endpoint with the client credentials grant.
terminal curl -s \ https://auth.origincloud.eu/realms/origincloud/protocol/openid-connect/token \ -d grant_type=client_credentials \ -d client_id=<client-id> \ -d client_secret=<client-secret>The response is JSON with an
access_tokenand its lifetime in seconds,expires_in. Request a new token when it expires. -
Send the token as a bearer token with each API request.
terminal curl -s https://api.origincloud.eu/graphql \ -H "Authorization: Bearer <access-token>" \ -H "Content-Type: application/json" \ -d '{"query":"{ iam { permissions { key } } }"}' -
Verify that the token is accepted: the response contains a
dataobject rather than an authentication error.
Revoke a service account
Revoking a service account disables its credential. From that moment, every request for a new access token is refused. An access token issued before the revocation stays valid until it expires.
-
Find the service account’s ID with
list-service-accounts. -
Revoke it.
terminal origin iam revoke-service-account --org-id <org-id> \ --service-account-id <service-account-id> -
Revoke its role assignments as well. Revoking the service account leaves them in place, and removing them cuts off any access token that is still valid, because roles are checked on every request.
terminal origin iam remove-member --org-id <org-id> \ --principal service_account:<service-account-id> -
Run
list-service-accountsagain and check that the service account has arevokedAttime. Revoked service accounts stay in the list. A revoked service account can’t be reactivated.
Rotate a client secret
A client secret can’t be changed or shown again. To rotate it, replace the service account with a new one:
-
Create a new service account, as in Create a service account, and store its client secret.
-
List the old service account’s role assignments, with their project scope:
terminal origin iam principal-grants --org-id <org-id> \ --principal service_account:<old-service-account-id> -
Assign the same roles, at the same scopes, to the new service account’s principal with
origin iam assign-role. -
Switch your automation to the new client ID and secret.
-
Revoke the old service account and remove its role assignments, as in Revoke a service account.
Using the API
The mutations are createServiceAccount and revokeServiceAccount; the query is serviceAccounts, all in the iam namespace. serviceAccounts never returns a client secret.
mutation {
iam {
createServiceAccount(input: { orgId: "<org-id>", name: "ci-deploy" }) {
id
principal
clientId
clientSecret
}
}
}Related
- Access model
- Built-in roles
- API access
create-service-accountandrevoke-service-accountcommands- Audit log – creation and revocation are recorded