feat: [12] Branch-Protection per Authorized Integration (JWT) mit PAT-Fallback #53

Merged
hobbypunk merged 3 commits from enhancement/12_protection_pat into main 2026-09-27 16:20:49 +00:00
Owner

Der erste Live-Run des Reconcile-Jobs scheiterte mit 403 ("user should be an owner or a collaborator with admin write of a repository") – der ephemeral secrets.GITHUB_TOKEN darf die Branch-Protection-API nicht.

Lösung: Authorized Integration (bevorzugt) statt breitem PAT

Forgejo-Doku-Empfehlung wörtlich: "Authorized Integrations are preferred over using Access Tokens whenever possible."

  • Kurzlebiges JWT (default 1h) statt langlebigem Static-Credential
  • Zuschnittgenau beschränkt auf: Source Repository, Workflow-Datei (branch-protection.yml), Git-Ref (refs/heads/main), Event
  • Capability: write:repository (deckt /repos/* inkl. branch_protections)
  • Audience ist nicht vertraulich → committbar, kein Secret-Management

Implementiert

  • enable-openid-connect: true im Workflow (JWT-Mint durch den Runner)
  • Action-Input audience: gesetzt → Skript holt JWT per OIDC und authentifiziert mit Authorization: bearer; leer → Fallback auf statischen Token (secrets.FORGEJO_TOKEN || secrets.GITHUB_TOKEN) – hält Template-Repos ohne Integration lauffähig
  • 403-Fehlermeldung erklärt beide Wege

To-do (einmalig, in deinen User-Settings)

  1. Settings → Authorized Integrations → Neu, Typ "Forgejo Actions (Local)"
  2. Beschränken: Source Repository = hobbypunk/rails-base_app, Workflow file = branch-protection.yml, Git ref = refs/heads/main, Event = push (oder leer)
  3. Capability: write:repository
  4. Die erzeugte Audience in die Workflow-Datei beim audience:-Input eintragen (PR-Feedback oder nach dem Merge – leer lassen funktioniert bis dahin über den Fallback)
Der erste Live-Run des Reconcile-Jobs scheiterte mit **403** ("user should be an owner or a collaborator with admin write of a repository") – der ephemeral `secrets.GITHUB_TOKEN` darf die Branch-Protection-API nicht. ## Lösung: Authorized Integration (bevorzugt) statt breitem PAT Forgejo-Doku-Empfehlung wörtlich: *"Authorized Integrations are preferred over using Access Tokens whenever possible."* - **Kurzlebiges JWT** (default 1h) statt langlebigem Static-Credential - **Zuschnittgenau beschränkt** auf: Source Repository, Workflow-Datei (`branch-protection.yml`), Git-Ref (`refs/heads/main`), Event - Capability: `write:repository` (deckt `/repos/*` inkl. `branch_protections`) - Audience ist **nicht vertraulich** → committbar, kein Secret-Management ### Implementiert - `enable-openid-connect: true` im Workflow (JWT-Mint durch den Runner) - Action-Input `audience`: gesetzt → Skript holt JWT per OIDC und authentifiziert mit `Authorization: bearer`; leer → Fallback auf statischen Token (`secrets.FORGEJO_TOKEN || secrets.GITHUB_TOKEN`) – hält Template-Repos ohne Integration lauffähig - 403-Fehlermeldung erklärt beide Wege ### To-do (einmalig, in deinen User-Settings) 1. **Settings → Authorized Integrations → Neu**, Typ **"Forgejo Actions (Local)"** 2. Beschränken: Source Repository = `hobbypunk/rails-base_app`, Workflow file = `branch-protection.yml`, Git ref = `refs/heads/main`, Event = `push` (oder leer) 3. Capability: **`write:repository`** 4. Die erzeugte **Audience** in die Workflow-Datei beim `audience:`-Input eintragen (PR-Feedback oder nach dem Merge – leer lassen funktioniert bis dahin über den Fallback)
[12] Branch-Protection: PAT fuer Admin-API (FORGEJO_TOKEN)
Some checks failed
PR Triage / triage (pull_request) Successful in 15s
CI / scan_ruby (pull_request) Successful in 1m16s
CI / lint (pull_request) Successful in 1m26s
CI / test (pull_request) Successful in 1m47s
CI / system-test (pull_request) Successful in 1m57s
CI / coverage (pull_request) Has been cancelled
589f5ef53b
---------

Co-Authored-By: opencode (Mistral GLM) <opencode-agent[bot]@hoppe-dev.eu>
forgejo-actions changed title from [12] Branch-Protection: PAT fuer Admin-API (FORGEJO_TOKEN) to feat: [12] Branch-Protection: PAT fuer Admin-API (FORGEJO_TOKEN) 2026-09-27 16:01:21 +00:00
[12] Branch-Protection: Authorized Integration (JWT) mit PAT-Fallback
All checks were successful
PR Triage / triage (pull_request) Successful in 1m5s
CI / scan_ruby (pull_request) Successful in 1m28s
CI / lint (pull_request) Successful in 1m31s
CI / test (pull_request) Successful in 1m50s
CI / system-test (pull_request) Successful in 1m56s
CI / coverage (pull_request) Successful in 29s
6eb4c36f86
---------

Co-Authored-By: opencode (Mistral GLM) <opencode-agent[bot]@hoppe-dev.eu>
hobbypunk changed title from feat: [12] Branch-Protection: PAT fuer Admin-API (FORGEJO_TOKEN) to feat: [12] Branch-Protection per Authorized Integration (JWT) mit PAT-Fallback 2026-09-27 16:04:04 +00:00
hobbypunk scheduled this pull request to auto merge when all checks succeed 2026-09-27 16:04:19 +00:00
hobbypunk canceled auto merging this pull request when all checks succeed 2026-09-27 16:04:59 +00:00
hobbypunk scheduled this pull request to auto merge when all checks succeed 2026-09-27 16:05:39 +00:00
hobbypunk canceled auto merging this pull request when all checks succeed 2026-09-27 16:05:45 +00:00

📊 Coverage

Metrik Abdeckung
Zeilen 97.69% (2619/2681)
Branches 81.46% (637/782)
Methoden 96.71% (412/426)

Patch-Coverage: keine getrackten Zeilen geändert

Schwächste Dateien im Projekt

Datei Abdeckung
app/models/concerns/has_uuid_v7.rb 54.55%
app/components/form/select.rb 72.41%
app/components/layout/flash.rb 84.0%
app/components/concerns/actionable.rb 86.67%
app/components/layout/sidebar.rb 89.47%
app/controllers/settings/security_controller.rb 90.24%
app/controllers/sessions_controller.rb 90.32%
app/components/concerns/inferrable.rb 90.63%
app/components/users/avatar.rb 91.23%
app/controllers/settings/security/otps_controller.rb 91.67%

🔍 Report im Browser ansehen · 📄 Run-Artifact „coverage-report“

<!-- coverage-report --> ## 📊 Coverage | Metrik | Abdeckung | |---|---| | Zeilen | 97.69% (2619/2681) | | Branches | 81.46% (637/782) | | Methoden | 96.71% (412/426) | **Patch-Coverage**: keine getrackten Zeilen geändert **Schwächste Dateien im Projekt** | Datei | Abdeckung | |---|---| | app/models/concerns/has_uuid_v7.rb | 54.55% | | app/components/form/select.rb | 72.41% | | app/components/layout/flash.rb | 84.0% | | app/components/concerns/actionable.rb | 86.67% | | app/components/layout/sidebar.rb | 89.47% | | app/controllers/settings/security_controller.rb | 90.24% | | app/controllers/sessions_controller.rb | 90.32% | | app/components/concerns/inferrable.rb | 90.63% | | app/components/users/avatar.rb | 91.23% | | app/controllers/settings/security/otps_controller.rb | 91.67% | [🔍 Report im Browser ansehen](https://pages.hoppe-dev.eu/hobbypunk/rails-base_app/pr-53/coverage) · [📄 Run-Artifact „coverage-report“](https://code.hoppe-dev.eu/hobbypunk/rails-base_app/actions/runs/1555/artifacts/coverage-report)
[12] Branch-Protection: Audience der Authorized Integration eintragen
All checks were successful
PR Triage / triage (pull_request) Successful in 27s
CI / lint (pull_request) Successful in 47s
CI / scan_ruby (pull_request) Successful in 55s
CI / test (pull_request) Successful in 1m11s
CI / system-test (pull_request) Successful in 44s
CI / coverage (pull_request) Successful in 33s
ddb0481127
---------

Co-Authored-By: opencode (Mistral GLM) <opencode-agent[bot]@hoppe-dev.eu>
hobbypunk scheduled this pull request to auto merge when all checks succeed 2026-09-27 16:14:41 +00:00
hobbypunk deleted branch enhancement/12_protection_pat 2026-09-27 16:20:49 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
hobbypunk/rails-base_app!53
No description provided.