nginx: allow /.well-known/* to reach the app (RFC 8615)#9
Merged
Conversation
The catch-all dotfile block (`location ~ /\.`) was 404'ing every
request whose path started with `/.well-known/` before nginx ever
forwarded it to PHP. That broke OIDC discovery, OAuth authorization-
server metadata, security.txt, and ACME http-01 challenges — anything
RFC 8615 says belongs in the well-known namespace.
Symptom that surfaced this: id.cbox.systems/.well-known/jwks.json
returned `<center>nginx</center>` 404 even though Laravel had the
route registered (`oauth.jwks → JwksController`). Vault's OIDC
backend can't be configured without id's discovery endpoint
reachable, so this is a hard prerequisite for vault bootstrap.
Fix:
* Add `location ^~ /.well-known/` BEFORE the regex catch-all in
both `default.conf` and `default-rootless.conf`. The `^~`
modifier short-circuits regex evaluation when the prefix matches,
so the dotfile block stops winning for this specific path. Apps
that don't register a /.well-known/* route still get a Laravel
404 (404-from-app), not a 403-from-nginx.
* Three new test-security.sh assertions:
- /.well-known/openid-configuration must NOT return 403
- response body must NOT be the nginx default-error page
- /.env must STILL be blocked (regression guard against the
well-known allow over-broadening into other dotfiles)
Verified via `docker run nginx:1.27-alpine nginx -t` against both
configs — syntax clean.
sylvesterdamgaard
added a commit
that referenced
this pull request
May 10, 2026
PR #9 fixed default.conf and default-rootless.conf — the static, baked- into-image versions. But the running container generates its config from default.conf.template via envsubst at startup, overwriting the baked default.conf with the templated output. The fix needs to live on the template path or it never reaches running pods. Verified live: a fresh id pod showed the correct `location ^~ /.well-known/` in default.conf (baked) but a regenerated runtime default.conf without the block. /.well-known/openid-configuration remained 404. Adding the well-known allow to the template, with ${NGINX_TRY_FILES} for the framework's index target, so the runtime config gets it. Build-and-push needs another workflow_dispatch since the workflow doesn't auto-trigger on path changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The catch-all `location ~ /\.` block was 404'ing every `/.well-known/*` request before forwarding to PHP. That breaks OIDC discovery, OAuth metadata, security.txt and ACME http-01 — exactly the paths RFC 8615 reserves.
Surfaced while preparing vault bootstrap: `id.cbox.systems/.well-known/jwks.json` returned the nginx default-error page despite Laravel having `oauth.jwks` registered. Vault's OIDC backend can't be configured without id's discovery endpoint reachable.
Summary
Test plan