PAPERCLIP_AUTH_DISABLE_SIGN_UP=true: the first admin is claimed.
Spec: Claude auth is a Paperclip-managed subscription connection created once via the local sign-in, run as the node user (gosu node), since exec sessions start as root and root-owned 0600 credentials are unreadable to the server. The server-env CLAUDE_CODE_OAUTH_TOKEN was never used (upstream stripAiAuthBindings blanks it; no pasted setup-token path without a Daytona sandbox) and is dropped from the spec.
Owner follow-up (not in git): remove the unused CLAUDE_CODE_OAUTH_TOKEN field from OpenBao homelab/apps/paperclip.
Follow-up to #966.
- `PAPERCLIP_AUTH_DISABLE_SIGN_UP=true`: the first admin is claimed.
- Spec: Claude auth is a Paperclip-managed subscription connection created once via the local sign-in, run as the `node` user (`gosu node`), since exec sessions start as root and root-owned 0600 credentials are unreadable to the server. The server-env `CLAUDE_CODE_OAUTH_TOKEN` was never used (upstream `stripAiAuthBindings` blanks it; no pasted setup-token path without a Daytona sandbox) and is dropped from the spec.
Owner follow-up (not in git): remove the unused `CLAUDE_CODE_OAUTH_TOKEN` field from OpenBao `homelab/apps/paperclip`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The first admin is claimed, so PAPERCLIP_AUTH_DISABLE_SIGN_UP flips to
true.
Spec: Claude auth is a Paperclip-managed subscription connection created
once via the local sign-in. The server-env CLAUDE_CODE_OAUTH_TOKEN was
never used (stripAiAuthBindings blanks it for managed runs; upstream
accepts no pasted setup-token), so it is dropped from the spec. The
login must run as the node user: exec sessions start as root and
root-owned 0600 credentials are unreadable to the server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream derives the agents' PAPERCLIP_API_URL from the public URL, so
agent API calls went out through Traefik to the paperclip-gate outpost.
With intercept_header_auth the outpost treats the agent's Authorization
header as an Authentik credential and returns 401; agents could not
create tasks, post cards or update status.
Agents run in the server pod (option B), so PAPERCLIP_API_URL is set to
http://localhost:3100 (upstream keeps an explicit value and passes it to
every run). Loopback passes the private-hostname guard and agent JWTs
still authenticate each call; the gate stays fully enforced for browser
traffic instead of carving out /api/.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cluster-internal name keeps working when runs move to sandbox pods
(option C), where loopback would not reach the server. The name is
added to PAPERCLIP_ALLOWED_HOSTNAMES because the private-hostname guard
otherwise returns 403 for it. Same-namespace traffic is already allowed
by the baseline CNP in both directions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖Automated review — model CLI default (complexity: unknown), commit 56e30bf065cc1ea73a53c7c0d0a3b1c4ca9fd12a.
Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.
Summary
Follow-up to #966: flips PAPERCLIP_AUTH_DISABLE_SIGN_UP to "true" now that the first
admin is claimed, adds PAPERCLIP_API_URL/PAPERCLIP_ALLOWED_HOSTNAMES so agents reach
the API through the in-cluster Service instead of the public URL (which the Authentik
gate would otherwise reject bearer tokens for), and updates the design spec to match —
including correcting it to say Claude auth is a Paperclip-managed local-login connection
rather than the previously-planned shared CLAUDE_CODE_OAUTH_TOKEN. No blocking issues
found; this is a small, well-scoped docs+manifest change consistent with the plan in docs/superpowers/plans/2026-09-25-paperclip.md (Task 9, Step 7.3) and the network
policy already in place.
🟡 Suggestions
kubernetes/apps/paperclip/paperclip.yaml:57-58 — Flipping PAPERCLIP_AUTH_DISABLE_SIGN_UP to "true" is a one-way door: once merged and
reconciled, nobody can sign up again, so if the admin claim mentioned in the PR
description ("the first admin is claimed") turns out not to have actually completed
successfully, recovery requires a second PR (or a manual kubectl set env) to flip it
back. Worth a final confirmation that /bootstrap/claim was actually exercised on the
live instance before merging, since nothing in this diff can verify that from the repo
side.
Spec doc, ai-local-logins/<id> and the specific behavior of stripAiAuthBindings, intercept_header_auth, and the private-hostname guard's handling of PAPERCLIP_ALLOWED_HOSTNAMES (docs/superpowers/specs/2026-09-25-paperclip-design.md:19,82-86)
are asserted as upstream facts but aren't verifiable from this checkout (no vendored
Paperclip source). The implementation plan's Task 1 calls for reading the actual
upstream source (gh api .../server/src/...) to settle exactly these questions, so
presumably that was done — just flagging that this review couldn't independently
confirm the upstream behavior claims, only that they're internally consistent with the
rest of the spec and with the env vars actually set in the manifest.
Tests
No test suite applies to this docs+manifest change; the repo's CI has a dedicated kubernetes/**-triggered pipeline (.woodpecker/ci-manifests-test.yml) that runs kubectl kustomize across the tree and would catch structural breakage (bad resource
refs, invalid YAML) in paperclip.yaml. Semantic correctness of the new env vars
(whether PAPERCLIP_ALLOWED_HOSTNAMES actually makes the private-hostname guard accept
the Service FQDN, whether flipping sign-up off doesn't lock out the claimed admin) can
only be confirmed by watching the live reconcile and testing a real agent run, per
"Verification" in the spec and Task 9 Step 7.2 in the plan — this is inherent to
infra-as-docs PRs like this one, not a gap introduced here.
Recommendation
Looks reasonable — no blocking issues; comments above are optional.
🤖 **Automated review** — model `CLI default` (complexity: unknown), commit `56e30bf065cc1ea73a53c7c0d0a3b1c4ca9fd12a`.
> Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review.
---
## Summary
Follow-up to #966: flips `PAPERCLIP_AUTH_DISABLE_SIGN_UP` to `"true"` now that the first
admin is claimed, adds `PAPERCLIP_API_URL`/`PAPERCLIP_ALLOWED_HOSTNAMES` so agents reach
the API through the in-cluster Service instead of the public URL (which the Authentik
gate would otherwise reject bearer tokens for), and updates the design spec to match —
including correcting it to say Claude auth is a Paperclip-managed local-login connection
rather than the previously-planned shared `CLAUDE_CODE_OAUTH_TOKEN`. No blocking issues
found; this is a small, well-scoped docs+manifest change consistent with the plan in
`docs/superpowers/plans/2026-09-25-paperclip.md` (Task 9, Step 7.3) and the network
policy already in place.
## 🟡 Suggestions
- **`kubernetes/apps/paperclip/paperclip.yaml:57-58`** — Flipping
`PAPERCLIP_AUTH_DISABLE_SIGN_UP` to `"true"` is a one-way door: once merged and
reconciled, nobody can sign up again, so if the admin claim mentioned in the PR
description ("the first admin is claimed") turns out not to have actually completed
successfully, recovery requires a second PR (or a manual `kubectl set env`) to flip it
back. Worth a final confirmation that `/bootstrap/claim` was actually exercised on the
live instance before merging, since nothing in this diff can verify that from the repo
side.
- Spec doc, `ai-local-logins/<id>` and the specific behavior of `stripAiAuthBindings`,
`intercept_header_auth`, and the private-hostname guard's handling of
`PAPERCLIP_ALLOWED_HOSTNAMES` (`docs/superpowers/specs/2026-09-25-paperclip-design.md:19,82-86`)
are asserted as upstream facts but aren't verifiable from this checkout (no vendored
Paperclip source). The implementation plan's Task 1 calls for reading the actual
upstream source (`gh api .../server/src/...`) to settle exactly these questions, so
presumably that was done — just flagging that this review couldn't independently
confirm the upstream behavior claims, only that they're internally consistent with the
rest of the spec and with the env vars actually set in the manifest.
## Tests
No test suite applies to this docs+manifest change; the repo's CI has a dedicated
`kubernetes/**`-triggered pipeline (`.woodpecker/ci-manifests-test.yml`) that runs
`kubectl kustomize` across the tree and would catch structural breakage (bad resource
refs, invalid YAML) in `paperclip.yaml`. Semantic correctness of the new env vars
(whether `PAPERCLIP_ALLOWED_HOSTNAMES` actually makes the private-hostname guard accept
the Service FQDN, whether flipping sign-up off doesn't lock out the claimed admin) can
only be confirmed by watching the live reconcile and testing a real agent run, per
"Verification" in the spec and Task 9 Step 7.2 in the plan — this is inherent to
infra-as-docs PRs like this one, not a gap introduced here.
## Recommendation
Looks reasonable — no blocking issues; comments above are optional.
<!-- pr-review:sha=56e30bf065cc1ea73a53c7c0d0a3b1c4ca9fd12a -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Follow-up to #966.
PAPERCLIP_AUTH_DISABLE_SIGN_UP=true: the first admin is claimed.nodeuser (gosu node), since exec sessions start as root and root-owned 0600 credentials are unreadable to the server. The server-envCLAUDE_CODE_OAUTH_TOKENwas never used (upstreamstripAiAuthBindingsblanks it; no pasted setup-token path without a Daytona sandbox) and is dropped from the spec.Owner follow-up (not in git): remove the unused
CLAUDE_CODE_OAUTH_TOKENfield from OpenBaohomelab/apps/paperclip.🤖 Generated with Claude Code
🤖 Automated review — model
CLI default(complexity: unknown), commit56e30bf065cc1ea73a53c7c0d0a3b1c4ca9fd12a.Summary
Follow-up to #966: flips
PAPERCLIP_AUTH_DISABLE_SIGN_UPto"true"now that the firstadmin is claimed, adds
PAPERCLIP_API_URL/PAPERCLIP_ALLOWED_HOSTNAMESso agents reachthe API through the in-cluster Service instead of the public URL (which the Authentik
gate would otherwise reject bearer tokens for), and updates the design spec to match —
including correcting it to say Claude auth is a Paperclip-managed local-login connection
rather than the previously-planned shared
CLAUDE_CODE_OAUTH_TOKEN. No blocking issuesfound; this is a small, well-scoped docs+manifest change consistent with the plan in
docs/superpowers/plans/2026-09-25-paperclip.md(Task 9, Step 7.3) and the networkpolicy already in place.
🟡 Suggestions
kubernetes/apps/paperclip/paperclip.yaml:57-58— FlippingPAPERCLIP_AUTH_DISABLE_SIGN_UPto"true"is a one-way door: once merged andreconciled, nobody can sign up again, so if the admin claim mentioned in the PR
description ("the first admin is claimed") turns out not to have actually completed
successfully, recovery requires a second PR (or a manual
kubectl set env) to flip itback. Worth a final confirmation that
/bootstrap/claimwas actually exercised on thelive instance before merging, since nothing in this diff can verify that from the repo
side.
ai-local-logins/<id>and the specific behavior ofstripAiAuthBindings,intercept_header_auth, and the private-hostname guard's handling ofPAPERCLIP_ALLOWED_HOSTNAMES(docs/superpowers/specs/2026-09-25-paperclip-design.md:19,82-86)are asserted as upstream facts but aren't verifiable from this checkout (no vendored
Paperclip source). The implementation plan's Task 1 calls for reading the actual
upstream source (
gh api .../server/src/...) to settle exactly these questions, sopresumably that was done — just flagging that this review couldn't independently
confirm the upstream behavior claims, only that they're internally consistent with the
rest of the spec and with the env vars actually set in the manifest.
Tests
No test suite applies to this docs+manifest change; the repo's CI has a dedicated
kubernetes/**-triggered pipeline (.woodpecker/ci-manifests-test.yml) that runskubectl kustomizeacross the tree and would catch structural breakage (bad resourcerefs, invalid YAML) in
paperclip.yaml. Semantic correctness of the new env vars(whether
PAPERCLIP_ALLOWED_HOSTNAMESactually makes the private-hostname guard acceptthe Service FQDN, whether flipping sign-up off doesn't lock out the claimed admin) can
only be confirmed by watching the live reconcile and testing a real agent run, per
"Verification" in the spec and Task 9 Step 7.2 in the plan — this is inherent to
infra-as-docs PRs like this one, not a gap introduced here.
Recommendation
Looks reasonable — no blocking issues; comments above are optional.