Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6618de9c9f | ||
|
|
82c4b07fea | ||
|
|
2f1ae61b06 | ||
|
|
03c2bef880 |
@@ -92,6 +92,7 @@ jobs:
|
|||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
run: bash "$SCRIPTS/route.sh"
|
run: bash "$SCRIPTS/route.sh"
|
||||||
|
|
||||||
- name: Install opencode + provider config (+ Playwright MCP for browser agents)
|
- name: Install opencode + provider config (+ Playwright MCP for browser agents)
|
||||||
@@ -198,6 +199,7 @@ jobs:
|
|||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
NAME: ${{ steps.prep.outputs.name }}
|
NAME: ${{ steps.prep.outputs.name }}
|
||||||
MODE: ${{ steps.prep.outputs.mode }}
|
MODE: ${{ steps.prep.outputs.mode }}
|
||||||
NUM: ${{ github.event.issue.number }}
|
NUM: ${{ github.event.issue.number }}
|
||||||
@@ -223,6 +225,7 @@ jobs:
|
|||||||
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
TOKEN_JUNIOR: ${{ secrets.TOKEN_JUNIOR }}
|
||||||
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
TOKEN_LEAD: ${{ secrets.TOKEN_LEAD }}
|
||||||
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
TOKEN_QA: ${{ secrets.TOKEN_QA }}
|
||||||
|
TOKEN_OPS: ${{ secrets.TOKEN_OPS }}
|
||||||
NAME: ${{ steps.prep.outputs.name }}
|
NAME: ${{ steps.prep.outputs.name }}
|
||||||
MODE: ${{ steps.prep.outputs.mode }}
|
MODE: ${{ steps.prep.outputs.mode }}
|
||||||
NUM: ${{ github.event.issue.number }}
|
NUM: ${{ github.event.issue.number }}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ set +e # publish is best-effort: a grep-no-match / curl non-zero must NOT kill
|
|||||||
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
# Post/PR as the agent's OWN Gitea user when its token is configured; else the built-in bot.
|
||||||
case "$NAME" in
|
case "$NAME" in
|
||||||
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
git config user.name "$NAME"
|
git config user.name "$NAME"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ cp "$AGENTS_JSON" /tmp/agents.json
|
|||||||
# here — see agent.yml: this reusable workflow sees it as 'workflow_call'.)
|
# here — see agent.yml: this reusable workflow sees it as 'workflow_call'.)
|
||||||
if [ -n "$CID" ]; then scan="$BODY"; else scan="$IBODY"; fi
|
if [ -n "$CID" ]; then scan="$BODY"; else scan="$IBODY"; fi
|
||||||
name=""
|
name=""
|
||||||
for a in pm junior senior lead qa; do
|
for a in pm junior senior lead qa ops; do
|
||||||
case "$scan" in *"@$a"*) name=$a; break;; esac
|
case "$scan" in *"@$a"*) name=$a; break;; esac
|
||||||
done
|
done
|
||||||
if [ -z "$name" ]; then
|
if [ -z "$name" ]; then
|
||||||
@@ -44,7 +44,7 @@ echo "Routing to @$name (model=$model vision=$vision mode=$mode skills=$skills)"
|
|||||||
# Act as the agent's own Gitea user when its token is set; else the built-in bot.
|
# Act as the agent's own Gitea user when its token is set; else the built-in bot.
|
||||||
case "$name" in
|
case "$name" in
|
||||||
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
pm) TOK="$TOKEN_PM";; senior) TOK="$TOKEN_SENIOR";; junior) TOK="$TOKEN_JUNIOR";;
|
||||||
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; *) TOK="";;
|
lead) TOK="$TOKEN_LEAD";; qa) TOK="$TOKEN_QA";; ops) TOK="$TOKEN_OPS";; *) TOK="";;
|
||||||
esac
|
esac
|
||||||
[ -z "$TOK" ] && TOK="$GT"
|
[ -z "$TOK" ] && TOK="$GT"
|
||||||
git config user.name "$name"
|
git config user.name "$name"
|
||||||
|
|||||||
@@ -59,20 +59,24 @@ curl -sS -X POST -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: applic
|
|||||||
# 2) mint a scoped token AS that user (pick the narrowest scopes needed)
|
# 2) mint a scoped token AS that user (pick the narrowest scopes needed)
|
||||||
tok=$(curl -sS -u "inter:$PW" -H "Content-Type: application/json" -X POST "$API/users/inter/tokens" \
|
tok=$(curl -sS -u "inter:$PW" -H "Content-Type: application/json" -X POST "$API/users/inter/tokens" \
|
||||||
-d '{"name":"inter","scopes":["read:repository","write:issue"]}' | jq -r '.sha1')
|
-d '{"name":"inter","scopes":["read:repository","write:issue"]}' | jq -r '.sha1')
|
||||||
# 3) store it as a secret (org / repo / user level) — never print $tok
|
# 3) store the value in BOTH places (see "Secret storage" below) — never print $tok
|
||||||
curl -sS -X PUT -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: application/json" \
|
curl -sS -X PUT -H "Authorization: token $AGENT_TOKEN" -H "Content-Type: application/json" \
|
||||||
"$API/orgs/gitea/actions/secrets/TOKEN_INTER" -d "$(jq -nc --arg d "$tok" '{data:$d}')"
|
"$API/orgs/gitea/actions/secrets/TOKEN_INTER" -d "$(jq -nc --arg d "$tok" '{data:$d}')"
|
||||||
```
|
```
|
||||||
Token **scopes** are groups of `read:`/`write:` on: `repository`, `issue`, `organization`, `user`,
|
Token **scopes** are groups of `read:`/`write:` on: `repository`, `issue`, `organization`, `user`,
|
||||||
`package`, `notification`, `misc`, and (only for a privileged token) `admin`.
|
`package`, `notification`, `misc`, and (only for a privileged token) `admin`.
|
||||||
|
|
||||||
## Token inventory — record everything in `gitea/secrets`
|
## Secret storage — `gitea/secrets/.env` is the SOURCE OF TRUTH
|
||||||
The private repo **`gitea/secrets`** (readable only by @ffaerber and @ops) is the source of truth for
|
Every token/secret value MUST live in **`gitea/secrets/.env`** (private, readable only by @ffaerber and
|
||||||
tokens. Whenever you mint, rotate, or re-scope a token, append/update a row in its `tokens.md` via the
|
@ops) as a `KEY=value` line. That file is the master; the workflows only get a secret because `.env` is
|
||||||
contents API (`GET` the file for its `sha`, then `PUT` the updated base64 content with that `sha`):
|
mirrored into the org Actions secrets. So whenever you mint, rotate, or re-scope a token you MUST do
|
||||||
`| <token/secret name> | <owner user> | <scopes> | <Actions secret it is stored in> | <notes> |`.
|
BOTH, in sync:
|
||||||
Storing the live value in the matching Actions secret is what workflows use; the `gitea/secrets` row
|
1. **`.env`**: `GET /repos/gitea/secrets/contents/.env` for its `sha`, add or replace the `KEY=value`
|
||||||
is the human-readable inventory. Never paste a token value into any issue/PR/comment/log.
|
line, then `PUT` the updated base64 content with that `sha`.
|
||||||
|
2. **Actions secret**: `PUT /orgs/gitea/actions/secrets/{KEY}` with the same value (what runs use).
|
||||||
|
When you DELETE a token, remove it from BOTH. Keep `gitea/secrets/README.md` (the table describing what
|
||||||
|
each KEY is) up to date. Do NOT use `tokens.md` — the values live in `.env`. NEVER paste a token value
|
||||||
|
into any issue/PR/comment/log; it only ever goes into `.env` and the Actions secret.
|
||||||
|
|
||||||
## Change a user's token scope (the "update my token" flow)
|
## Change a user's token scope (the "update my token" flow)
|
||||||
Tokens are immutable — you can't edit scopes. Re-mint: delete the old token and create a new one,
|
Tokens are immutable — you can't edit scopes. Re-mint: delete the old token and create a new one,
|
||||||
|
|||||||
Reference in New Issue
Block a user