Identities for CI and servers
Create an identity bound to one environment, and give it a way to prove itself.
Your CI logs in like a person does, with no key to steal. The roster of what it logs in as lives under Machine Identities then All Identities.
The list
Each row names the identity and the project and environment it is bound to. Beside that sit the role it holds and the state of its credentials.
Creating one asks for a name, then for the project and environment it should reach and the role it should hold.
An identity is bound to one environment when it is created and the binding never moves. A request naming any other environment is refused.
Two built-in roles can be given to an identity:
| Role | What it holds |
|---|---|
| Secrets Reader | secret:read, secret:reveal, dynamic:generate |
| Secrets Writer | those, plus secret:write and secret:delete |
A custom role assignable to a machine is how you withhold one of those, such as minting on demand.
Machines never take a seat. An identity costs nothing and no plan counts them, so wiring fifty pipelines costs what wiring one costs.
One identity
Opening an identity shows what it may do and how it proves itself. Four ways to give it a credential sit behind one dialog.
| Tab | What it is |
|---|---|
| Token | A pck_ string you copy once, with an expiry you choose |
| OIDC trust | An issuer plus one exactly matched subject, holding no secret |
| AWS workload | An account id plus a role's immutable id, holding no secret |
| Host keypair | A one-time enrollment secret for a server that can prove nothing else |
A trust is a rule rather than a secret, so adding one hands nothing over. A token and a keypair enrollment both hand something over once, which is why both ask you to confirm it is you.
Every token a trust exchanges lives 15 minutes. How a machine logs in has the exchange itself.
Revoking
| What you revoke | What stops |
|---|---|
| One credential | That credential. The identity can be given another |
| The identity | Everything it holds, at once |
| A cloned keypair | The keypair and every credential it minted, revoked for you the moment a second host presents it |
What each action needs
| Action | Needs | Confirm it is you | Recorded as |
|---|---|---|---|
| Open the roster | machine:read | No | not recorded |
| Create an identity | machine:create at the chosen project and environment | Yes | identity.create |
| Issue a token | machine:issue at its binding | Yes | credential.issue |
| Add an OIDC trust | machine:issue at its binding | No | credential.issue |
| Add an AWS trust | machine:issue at its binding | No | credential.issue |
| Enroll a host keypair | machine:issue at its binding | Yes | credential.issue |
| Revoke one credential | machine:revoke at its binding | No | credential.revoke |
| Revoke the identity | machine:revoke at its binding | No | identity.revoke |
Issuing a credential cannot widen what an identity may do. The role is set when the identity is created, which is why machine:issue and machine:create are separate permissions.
Two more entries land on their own without anybody clicking. credential.drifted says a trust stopped matching the tokens arriving under it. credential.cloned says one host keypair authenticated from two places, which locks the credential.
Next: connect a platform.