| index 22a5c3dca..4704ca9b9 100644 |
| --- a/README.md |
| +++ b/README.md |
| @@ -167,12 +167,28 @@ refused** — the console names itself in the refusal, because moving `stable` |
| needs a passkey step-up only a browser can do. Finish it at the URL the |
| refusal prints. |
| |
| -CI and operators keep the existing path unchanged: set |
| -`CARLOS_DEPLOYMENT_BUCKET` (or `_DIR`) and every verb goes straight at the |
| -bucket, exactly as before — logging in is for a human at a laptop, never a box |
| -or a pipeline. Note the modes carry different authority: a scoped |
| -`CARLOS_RELEASE_KEY` constrains the direct path only — in API mode it is |
| -ignored and your console membership (plus the rung gates) is what decides. |
| +**CI uses the console too.** Mint a deploy credential for the app, limited |
| +to the rungs CI may move, and give CI the secret and the console's address: |
| + |
| + carlos services create --role deploy --app blog --rungs canary,edge ci |
| + # in CI: |
| + export CARLOS_SERVICE_TOKEN=... CARLOS_CONSOLE=https://console.example.com |
| + carlos deploy --app blog --version "$GITHUB_SHA" --channel edge blog-linux-arm64 |
| + |
| +`carlos deploy` ships, promotes and watches the app's hosts, the same as |
| +from a laptop. The first deploy of a new app still needs a person: a deploy |
| +credential cannot create the app or set up its first host. Every promote is |
| +audited in the console and reaches the boxes within seconds. A deploy |
| +credential can ship, and promote or roll back only its rungs. It cannot |
| +reach stable, hotfix, delete the app, or change retention or domains. |
| + |
| +**Direct bucket mode is for operators.** With `CARLOS_DEPLOYMENT_BUCKET` |
| +(or `_DIR`) set, every verb goes straight to the bucket and the console |
| +never sees it. Use it to set up a deployment before its console exists, to |
| +run one that has no console, to recover when the console is down, and for |
| +the platform's own releases. A scoped `CARLOS_RELEASE_KEY` limits that path |
| +only. The CLI refuses to run with both `CARLOS_SERVICE_TOKEN` and a bucket |
| +variable set. |
| |
| **On a box, or in CI, don't log in.** There is no browser and no human, and a |
| long-lived token sitting on a box is a standing credential nobody is watching. |