C0: rotate-fly-deploy-token — fish+bash one-shot, op validator gotcha

Combine mint+store into a single command with both fish and bash
forms (the doc previously only showed manual paste). Document the
1Password CLI "Password item requires ps value" validator error and
the placeholder-password workaround for Password-category items with
empty primary password fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erich Blume 2026-05-04 13:42:57 -07:00
commit a2c61b625d
2 changed files with 27 additions and 12 deletions

View file

@ -0,0 +1 @@
rotate-fly-deploy-token: combine mint+store into one command with both fish and bash forms; document the `op item edit` "Password item requires ps value" validator gotcha and the placeholder-password workaround.

View file

@ -1,7 +1,7 @@
--- ---
title: Rotate the Fly.io API Token title: Rotate the Fly.io API Token
modified: 2026-04-30 modified: 2026-05-04
last-reviewed: 2026-04-30 last-reviewed: 2026-05-04
tags: tags:
- how-to - how-to
- fly-io - fly-io
@ -45,24 +45,38 @@ fly auth login
(Browser-based. Required to mint a new token, since the existing deploy token can't create tokens.) (Browser-based. Required to mint a new token, since the existing deploy token can't create tokens.)
### 2. Mint the new token ### 2. Mint the new token and store it
The token is shown only once at creation, so combine the mint and the 1Password write into a single command. Pick the form for your shell.
`fish`:
```fish ```fish
fly tokens create org \ op item edit on5slfaygtdjrxmdwezyhfmqsq "add more.deploy-token=(fly tokens create org --org personal --name 'blumeops-proxy deploy '(date +%Y-%m-%d) --expiry 2160h)" --vault vg6xf6vvfmoh5hqjjhlhbeoaie
--org personal \
--name "blumeops-proxy deploy $(date +%Y-%m-%d)" \
--expiry 2160h
``` ```
(`2160h` = 90 days, paired with the 75-day rotation cadence for a 15-day buffer. Capture the output — it's the only time the token is shown.) `bash` / `zsh`:
### 3. Update 1Password ```bash
op item edit on5slfaygtdjrxmdwezyhfmqsq "add more.deploy-token=$(fly tokens create org --org personal --name "blumeops-proxy deploy $(date +%Y-%m-%d)" --expiry 2160h)" --vault vg6xf6vvfmoh5hqjjhlhbeoaie
```
(`2160h` = 90 days, paired with the 75-day rotation cadence for a 15-day buffer.)
If you'd rather paste manually:
```fish ```fish
fly tokens create org --org personal --name "blumeops-proxy deploy $(date +%Y-%m-%d)" --expiry 2160h
op item edit on5slfaygtdjrxmdwezyhfmqsq 'add more.deploy-token=<paste-new-token>' --vault vg6xf6vvfmoh5hqjjhlhbeoaie op item edit on5slfaygtdjrxmdwezyhfmqsq 'add more.deploy-token=<paste-new-token>' --vault vg6xf6vvfmoh5hqjjhlhbeoaie
``` ```
### 4. Sync to Forgejo Actions > **op validator gotcha:** If `op item edit` returns `Password item requires ps value`, the item's primary `password` field is empty. The 1Password CLI validator rejects edits to a Password-category item with no primary password, even when you're only touching a section field. Set a placeholder once and future rotations will work:
>
> ```fish
> op item edit on5slfaygtdjrxmdwezyhfmqsq 'password=unused - see deploy-token field' --vault vg6xf6vvfmoh5hqjjhlhbeoaie
> ```
### 3. Sync to Forgejo Actions
The `deploy-fly` workflow reads the same token from a Forgejo Actions secret named `FLY_DEPLOY_TOKEN`, populated by the `forgejo_actions_secrets` ansible role: The `deploy-fly` workflow reads the same token from a Forgejo Actions secret named `FLY_DEPLOY_TOKEN`, populated by the `forgejo_actions_secrets` ansible role:
@ -70,7 +84,7 @@ The `deploy-fly` workflow reads the same token from a Forgejo Actions secret nam
mise run provision-indri -- --tags forgejo_actions_secrets mise run provision-indri -- --tags forgejo_actions_secrets
``` ```
### 5. Verify ### 4. Verify
```fish ```fish
mise run fly-deploy mise run fly-deploy
@ -80,7 +94,7 @@ A successful deploy confirms the new token works locally. Watch for the metrics-
Then trigger the CI workflow (push a no-op commit touching `fly/`, or dispatch manually) to confirm Forgejo Actions has the new secret. Then trigger the CI workflow (push a no-op commit touching `fly/`, or dispatch manually) to confirm Forgejo Actions has the new secret.
### 6. Revoke the old token ### 5. Revoke the old token
```fish ```fish
fly tokens list fly tokens list