1 Commits

Author SHA1 Message Date
4e6a782edf An unguessable capability URL is the whole credential (closes #52)
All checks were successful
check / check (push) Successful in 16s
The HTTP hardening section ends with "when in doubt, harden", which as
written authorises adding HMAC signing or a shared secret on top of an
endpoint already gated by an unguessable per-entrypoint UUID URL. That
has been ruled against twice, and inbound signature verification was
removed from webhooker on exactly that reasoning; until now the only
text contradicting the policy was webhooker's own README.

Adds one scoped carve-out immediately after that sentence: such a URL is
a complete credential and gets no second factor, not even as defence in
depth. The consequences that do follow — keep it out of logs and
tickets, rotate by minting a new entrypoint — are stated, as is what to
do with a sender that only supports signed payloads. Nothing in the
surrounding hardening guidance is removed or weakened.
2026-08-25 20:43:48 +00:00
2 changed files with 24 additions and 1 deletions

View File

@@ -21,6 +21,9 @@ fmt-check, and commit.
# Completed Steps
- 2026-08-25: Carved capability-URL services out of "when in doubt, harden" in
REPO_POLICIES.md: an unguessable per-entrypoint UUID URL is a complete
credential and gets no second authentication factor.
- 2026-08-10: Moved every lint run into a container. `script/lint` now runs the
linter directly when `LINT_IN_CONTAINER=1` and otherwise builds
`Dockerfile.lint`, so the linter never runs on a developer host — closing the

View File

@@ -1,6 +1,6 @@
---
title: Repository Policies
last_modified: 2026-08-10
last_modified: 2026-08-25
---
This document covers repository structure, tooling, and workflow standards. Code
@@ -847,6 +847,26 @@ style conventions are in separate documents:
hardening measure exists for HTTP services and is not listed here, it is
still expected. When in doubt, harden.
**One carve-out: capability URLs.** Where a service's credential is an
unguessable URL — a v4 UUID path segment minted per entrypoint — that URL is
the complete credential, not a partial one. Knowing it is authorization.
Such an endpoint does not get a second authentication factor added on top:
no HMAC request signing, no shared secrets, no bearer tokens, not as
defense-in-depth and not as a belt-and-braces extra. This has been
considered and rejected; "when in doubt, harden" is not license to propose
it again.
What does follow from a capability URL is that it is a secret, and is
handled as one:
- Keep it out of logs, error messages, tickets, screenshots, and support
transcripts. Log the entrypoint's internal ID, never its URL.
- Rotate by minting a new entrypoint and retiring the old one. There is no
key to change.
A sender that cannot accept a secret URL and supports only signed payloads
is a constraint on that integration. Raise it — that is not grounds to
reintroduce shared secrets.
- `README.md` is the primary documentation. Required sections:
- **Description**: First line must include the project name, purpose,
category (web server, SPA, CLI tool, etc.), license, and author. Example: