Service Identities for Integrations
Applies to CoCoCo platform v1.0.0-rc.31. Every step below was run on that version.
An integration should never run under a person’s account. If it does, its writes are attributed to that person, they stop working when the person leaves, and the integration holds every right that person happens to have.
CoCoCo has service accounts for this. Setting one up correctly takes four steps — and the second one is the step everyone skips.
1. Create the service account
Section titled “1. Create the service account”Create a user of kind BOT for the integration. The name should say what the account does, not who set it up: MIS Import, Shipping Sync, Press 1 Telemetry.
One identity per integration, not one for everything. It costs nothing and it pays back the first time you need to know which system wrote a record, or need to revoke exactly one connection.
2. Give it a policy — a fresh account has no rights at all
Section titled “2. Give it a policy — a fresh account has no rights at all”This is the step that surprises people: a newly created service account can do nothing. It is not a reduced version of an admin; it starts with an empty set of permissions. Every call that needs a permission is refused until a policy is attached. Only questions about the account itself still answer: myEffectivePermissions returns an empty list.
So: create a policy listing exactly the actions the integration performs, then attach it to the account. For a MIS import that reads orders and writes production feedback, that is roughly:
customer:read, customer:list, customer:writeorder:read, order:list, order:writejob:read, job:list, job:writeoperation:read, operation:list, operation:writeprogressPoint:writeNothing else — no deletes, no configuration, no user management. Start from what the integration does today and add when it grows; that is far easier than trimming a broad policy later.
3. Issue a token — and copy it once
Section titled “3. Issue a token — and copy it once”Create an API token on behalf of the service account, not on your own account. When you request it, the token value is returned exactly once and can never be read again. Store it wherever your integration keeps its secrets before you close the response.
If you lose it, create a second token and revoke the first.
4. Verify what the account actually got
Section titled “4. Verify what the account actually got”Do not trust the policy document — call myEffectivePermissions with the account’s own token from step 3 and compare the result with your list.
This catches the two mistakes that are otherwise invisible: a statement that was accepted but grants nothing, and a permission you assumed was included in another. Two minutes here saves an afternoon of authorization errors that look like bugs.
If the integration runs inside the platform as an Integration with timers, it needs no token: the instance runs as the service account it is bound to (
botUserId). That account still needs its policy from step 2 — attach it before you start the instance. Tokens are for code running outside — an on-premise job, a middleware, a script on your own server.
Good practice
Section titled “Good practice”| Do | Why |
|---|---|
| One account per integration | Traceability, and revoking one thing does not break another |
| Name it after its function | MIS Import, not api-user-2 |
| Least privilege, grown over time | The policy documents what the integration is allowed to do |
Verify with myEffectivePermissions | It shows what really applies, not what the document says |
| Keep the token in your secret store | It is shown once, and it is a full credential |
Where to go next
Section titled “Where to go next”- Understanding IAM: Policies, Permissions and Roles — the model behind this
- How to Create an IAM Policy and How to Assign a Policy to a User — the mechanics
- Permission Errors: How to Diagnose — when a call is refused anyway
- How to Create and Manage API Tokens — token handling in detail