Commit graph

22 commits

Author SHA1 Message Date
Johan Lundberg
8143db5aea
implement ACCR aware authentications 2026-06-29 09:22:16 +02:00
Johan Lundberg
b284cf596b
fix(oidc): return 400 instead of 500 on bad token requests
The token endpoint wrapped parse_request in try/except but
  called process_request and do_response unguarded, so a parseable-but-invalid request (e.g. a refresh_token grant missing client_id, or an
  unknown token) made idpyoidc raise and surfaced as a 500. Wrap both so failures return a clean 400 invalid_request and log the traceback
  server-side. Adds a regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:37:01 +02:00
Johan Lundberg
27763d19ea
fix(security): don't mint new ID tokens on refresh; confirm offline_access gating
idpyoidc already gates refresh-token issuance on the offline_access scope
(verified by test), but the refresh-token grant was configured to also mint
fresh ID tokens. Drop id_token from the refresh_token grant's supports_minting
so refreshing yields only access (and a rotated refresh) token; ID tokens come
from authentication. Refresh-token rotation is retained.

Refs: porchlight-553

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 09:25:49 +02:00
Johan Lundberg
c7550cbf09
fix(security): lock down signing-key file permissions
Private JWK files were written under the default umask (observed 0664 — group
and world readable). Create the key directory 0700, chmod private key files
(private_jwks.json, token_jwks.json) to 0600 after they are written, and
refuse to start if a pre-existing private key is group/world accessible.

Tests now use an isolated per-test key directory.

Refs: porchlight-91i

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:21:27 +02:00
Johan Lundberg
7c4dbf2cd9
fix(security): escape error text in OIDC error pages
OIDC error responses interpolated parse-error/exception and error_description
text straight into HTML. idpyoidc currently emits canned messages, but this is
the same reflected-XSS class as the validation-error fix; relying on upstream
not to echo input is fragile.

Add a shared _error_page() helper that HTML-escapes the message and route all
six dynamic error responses through it.

Refs: porchlight-8iw

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 11:06:08 +02:00
Johan Lundberg
71a7c23bdd
fix(security): verify S256 PKCE when relying parties use it
idpyoidc advertised PKCE support but did not actually verify the code
challenge at the token endpoint, so a sent code_challenge provided no
protection. Enable the PKCE add-on restricted to S256.

Configured as non-essential: relying parties that do not send a
code_challenge continue to work (no breaking change), but any RP that uses
PKCE must use S256, and the code_verifier is verified at token exchange.
Flip essential=True (or per-client pkce_essential) to require PKCE once all
clients have migrated.

Refs: porchlight-s48

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 11:00:30 +02:00
Johan Lundberg
cdde3e3754
fix(security): reject consent scopes outside the original request
The /consent POST handler trusted the scope values submitted in the form,
so a forged consent submission could approve (and persist consent for)
scopes that were never part of the originating authorization request —
a scope-escalation vector.

Intersect the submitted scopes with the originally requested set stored in
the session before saving consent and completing the flow.

Refs: porchlight-a03

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 10:26:55 +02:00
Johan Lundberg
01e3382aaf
fix: resolve all ruff lint errors and type checker warnings
- Use Annotated[str, Form()] for FastAPI dependencies (FAST002)
- Add missing type annotations across src/ and tests/ (ANN001/003/201/202)
- Reduce function arguments via request.form() reads (PLR0913)
- Combine return paths to reduce return statements (PLR0911)
- Use anyio.Path for async-safe filesystem operations (ASYNC240)
- Extract constants, helpers, and dict comprehensions for clarity
- Move inline imports to top-level (PLC0415)
- Use raw strings for regex match patterns (RUF043)
- Fix redundant get_session_user call in delete_user (not-iterable)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 15:48:46 +02:00
Johan Lundberg
1054feb534
fix: reorder imports and use ty-compatible type suppression 2026-02-19 14:29:01 +01:00
Johan Lundberg
f648422227
test: update all tests to include CSRF tokens 2026-02-19 14:19:47 +01:00
Johan Lundberg
b8464284c2
test: update existing tests to handle consent step 2026-02-19 11:13:11 +01:00
Johan Lundberg
1d8fd91f68
feat: add consent check to authorization flow 2026-02-19 09:47:59 +01:00
Johan Lundberg
7cb1adbd06
update all imports in test files: fastapi_oidc_op → porchlight 2026-02-16 15:34:53 +01:00
Johan Lundberg
dbd7449ea1
test: add end-to-end OIDC authorization code flow test 2026-02-16 14:05:11 +01:00
Johan Lundberg
11a76d4ea8
feat: add OIDC userinfo endpoint 2026-02-16 13:57:10 +01:00
Johan Lundberg
e4e7cd237e
feat: add authorization complete and token endpoints 2026-02-16 13:47:48 +01:00
Johan Lundberg
18e9e7f2b5
feat: redirect to OIDC authorization after login when pending 2026-02-16 13:34:06 +01:00
Johan Lundberg
d8c891af89
feat: add OIDC discovery, JWKS, and authorization endpoints 2026-02-16 13:33:40 +01:00
Johan Lundberg
95d184ce0f
feat: integrate idpyoidc server into app lifespan 2026-02-16 13:29:39 +01:00
Johan Lundberg
2426e0675c
feat: add idpyoidc server initialization 2026-02-16 13:24:54 +01:00
Johan Lundberg
02b75a3eca
feat: add OIDC claims mapping and PorchlightUserInfo source 2026-02-16 12:52:43 +01:00
Johan Lundberg
922851b966
chore: create package structure with src layout 2026-02-12 14:39:07 +01:00