p24-audit-log — Operations Reference
Repo:
radieu/p24-audit-log(private) — created 2026-08-06 (see Provisioning status) Origin issue: #2652 — DSA Phase 1A Plan: #2637 Scaffolding tracked by: #3471
Purpose
p24-audit-log is the append-only audit-log repository for the DSA (Digital Services Act)
compliance workstream. Autonomous workers and humans append short, structured notes recording
deployment decisions, workarounds, and open items so there is a durable, PR-reviewed audit trail
outside any single service repo.
Downstream work (issues C #2655 and D #2656) writes to this repo. As of 2026-08-06 this no
longer needs a static AUDIT_LOG_WRITE_TOKEN PAT — see
Write credential — GitHub App, not a static PAT.
Note schema
Every entry is prefixed with exactly one tag:
| Tag | Meaning |
|---|---|
[DEPLOYED] | A change that reached production, with what/when/where |
[DECISION] | An architectural or process decision and its rationale |
[WORKAROUND] | A temporary measure in place until a proper fix lands |
[OPEN ITEM] | A known gap or follow-up not yet resolved |
Provisioning status
Done, 2026-08-06 — resolved in a Class A secret-manager session on the developer workstation
(has a human radieu OAuth gh login with repo+workflow scope, which the bms-4/#3471 worker
never had access to — its blocker analysis below is preserved for context, not because it recurred).
| Step | Status |
|---|---|
1. Create private repo radieu/p24-audit-log | ✅ done |
2. README.md + .github/workflows/auto-merge.yml as initial commit on main | ✅ done |
3. Branch protection on main (require PR, dismiss stale reviews) | ✅ done |
| 4. Repo Settings → enable Allow auto-merge | ✅ done |
| 5. Write credential for issues C/D | ✅ done — not a new PAT, see next section |
Why the earlier blocker doesn’t apply here (historical context, #3471)
The bms-4 infra-task worker could not create the repo — no token reachable from that host has
Administration: write on the radieu user account:
| Credential | Result |
|---|---|
Active worker token (radieu, fine-grained PAT) | Resource not accessible by personal access token |
AI-Dev-BMS4-1 (classic repo scope) | cannot create a repository for radieu (different user namespace) |
N8N_BMS4_GH_TOKEN (SOPS, fine-grained PAT) | Resource not accessible by personal access token |
That blocker is specific to the bms-4 worker’s credentials, not to the GitHub platform. A Class A
p24-infra session’s own gh auth login (human radieu account, classic OAuth token, repo scope)
has Administration: write on its own user namespace by default, so gh repo create radieu/...
works from there without any new credential. Commands actually run (steps 1–4):
gh repo create radieu/p24-audit-log --private \
--description "DSA audit log — deployment decisions, workarounds, open items"
# README.md + .github/workflows/auto-merge.yml pushed as the first two commits on main via
# the Contents API (PUT repos/radieu/p24-audit-log/contents/<path>) — no local clone needed.
gh api --method PUT repos/radieu/p24-audit-log/branches/main/protection \
--input branch-protection.json # required_pull_request_reviews.dismiss_stale_reviews=true
gh repo edit radieu/p24-audit-log --enable-auto-mergePaste-ready artifacts
README.md
# p24-audit-log
Append-only DSA compliance audit log. One note per commit/PR.
## Note schema
Prefix every entry with exactly one tag:
- `[DEPLOYED]` — a change that reached production (what / when / where)
- `[DECISION]` — an architectural or process decision and its rationale
- `[WORKAROUND]`— a temporary measure until a proper fix lands
- `[OPEN ITEM]` — a known gap or follow-up not yet resolved
## Workflow
- Every change lands via PR (branch protection enforced).
- Label a PR `auto-merge` to have it squash-merged automatically once checks pass..github/workflows/auto-merge.yml
name: auto-merge
on:
pull_request:
types: [opened, synchronize]
jobs:
auto-merge:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'auto-merge')
steps:
- run: gh pr merge --auto --squash "${{ github.event.pull_request.number }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}Write credential — GitHub App, not a static PAT
The original plan (#2652, #3471) called for a fine-grained PAT named AUDIT_LOG_WRITE_TOKEN
(contents:write, scoped to this repo only), stored as a static value in
secrets/n8n-bms4.env.sops. GitHub has no API to self-issue a new PAT — creation is UI-only,
2FA-gated — so that step would have stayed a permanent human/Tier-3 dependency.
That step is no longer needed. This repo is already covered by the same GitHub App the
ecosystem uses elsewhere to eliminate PAT consumers (App 2109526, installation 142989418,
installed with all-repositories access on the radieu account — see
docs/playbooks/n8n/github-app-token-n8n.md). A newly
created repo under radieu/* is automatically in scope for an all-repos installation — no
per-repo “add repository” step was needed. The App’s contents: write permission is already
confirmed granted at the installation (audited in
docs/plans/plan-4245-gh-app-token-fleet-migration.md
§3). Its credentials already live in secrets/n8n-bms4.env.sops (GITHUB_APP_ID,
GITHUB_APP_PRIVATE_KEY_B64, GITHUB_APP_INSTALLATION_ID) and are already deployed to bms-4 —
no new SOPS entry was added for this issue.
Any consumer that needs to write to radieu/p24-audit-log (git push, or a REST/Contents-API call)
mints a fresh, narrowly-scoped, 1-hour installation token on demand instead of reading a static
secret:
AUDIT_LOG_WRITE_TOKEN=$(python3 /opt/p24-infra/scripts/gh-app-token --repos p24-audit-log --permissions contents:write)
git remote set-url origin "https://x-access-token:${AUDIT_LOG_WRITE_TOKEN}@github.com/radieu/p24-audit-log.git"
unset AUDIT_LOG_WRITE_TOKENscripts/gh-app-token (built for #4068) reads the App credentials from whichever of
/opt/p24-infra/bms-4/.env or /opt/p24-infra/monitoring/.env carries them, so this works
unchanged on bms-4 or vps-i1. A --repos/--permissions-scoped call is never cached and is
strictly narrower than the originally-proposed PAT (1h TTL vs 90 days, single-repo, no browser/2FA
ever required to mint or rotate it).
Action for whoever (re-)implements scripts/dsa/run-audit.sh (issue #2656 — the draft
implementation in PR #2661 was closed unmerged): use the snippet above instead of
AUDIT_LOG_WRITE_TOKEN=$(grep -m1 '^AUDIT_LOG_WRITE_TOKEN=' "$ENV_FILE" | cut -d= -f2-). The
downstream git remote set-url line does not need to change — an App installation token is a
drop-in replacement for a PAT in the x-access-token:<token>@github.com git-credential form.
Never hardcode any token; both the App private key and any minted installation token are handled only as env vars, never written to a committed file. See secret-manager.md.
Compliance
- Outstanding: register
p24-audit-login Supabasedev_r_services(compliance_workbook='yes',workbook_urlpointing at this doc) — the repo now exists so this can proceed; not done as part of this issue (secret-manager role scope; hand off perdocs/playbooks/dev-r-services-insert.md). - This ops doc satisfies the “ops doc in
docs/” requirement for the new repo.