Commit Graph

74 Commits

Author SHA1 Message Date
Andrew Martinez 991ccffbdd fixes openziti/ziti#4222 report isCertExtendable correctly for OIDC cert auth (#4224)
- removes a stray assignment that overwrote isCertExtendable with a literal true on every OIDC certificate authentication
- reports isCertExtendable as false over OIDC for cert authenticators not issued by the network, matching legacy cert auth
- adds coverage asserting the z_ice claim and current-api-session both report a 3rd party CA certificate as not extendable
2026-08-26 15:59:17 -04:00
Paul Lorenz 97a0208c8b Merge commit from fork
fixes GHSA-q8g9-jc4c-jp6q limit pre-auth request body buffering
2026-08-20 14:13:21 -04:00
Andrew Martinez 472b32c668 fixes GHSA-q8g9-jc4c-jp6q limit pre-auth request body buffering
- caps buffered HTTP request bodies at 1 MiB across the client, management, fabric management, and OIDC web APIs
- rejects oversized bodies with 413 REQUEST_ENTITY_TOO_LARGE before authentication
- surfaces request body read errors instead of ignoring them
- returns after writing the request context error response in the client API handler
- adds integration coverage for oversized bodies with and without Content-Length
2026-07-23 17:04:43 -04:00
Andrew Martinez e7d23ef0ae fixes openziti/ziti#3990 push service and posture changes to subscrib… (#4057)
* fixes openziti/ziti#3990 push service and posture state to subscribed SDKs

- pushes indexed atomic ServiceChangeSet envelopes to subscribed SDK connections: a full snapshot on subscribe, incremental service changes per RDM scan pass, posture check definition changes as their own entries, and identity-resolved config bodies, all serialized so envelopes hit the wire in index order
- pushes per-connection PostureStateChange state (monotonic seq, resync on request) for posture pass/fail, including flips caused by definition edits that mutate no posture data
- registers pending RDM identity subscriptions for identities not yet synced to the router and sends an authoritative full sync plus full posture state when the identity arrives; an active push subscription pins the connection's RDM listener
- advertises service subscriptions and router data model support on the control-channel capability bitmask; the controller persists each router's capabilities mask and version on the EdgeRouter entity via raft and renders them on the edge APIs, so SDKs can select capable routers before connecting
- submits posture per router and corrects MFA posture semantics: pushed expiry is the earliest of timeout and pending wake/unlock grace deadlines, wake/unlock re-pass satisfies the re-prompt, api session tokens whose amr attests TOTP seed the MFA baseline from auth_time only (never iat), and token exchange carries the subject token's auth_time
- sends structured denials on dial and bind refusals: posture failures carry the failing check ids, no-policy denials are access denied, unknown services are invalid service, and session token failures are invalid session; the denial's cause no longer rides the wire as an unserializable error
- hard-closes accepted SDK connections on edge listener shutdown so clients observe a router going away immediately
- adds integration coverage: subscription snapshots and change delivery, poll and push reconciliation as capable routers come and go, posture state and definition-change push, router views over the public SDK API, typed dial errors, MFA baseline seeding, and OIDC token-exchange auth_time preservation
- removed RDM capability from SDK, router/controller only
2026-07-22 11:52:39 -04:00
Björn Mage 4a8b63d99d fix(oidc_auth): hex-encode peer signer kid in KeySet() (#4068)
KeySet() formatted a peer controller's SHA1 cert fingerprint with %s
instead of %x, producing an undecodable raw-byte kid in the /oidc/keys
JWKS response for every entry sourced from GetPeerSigners(). The
error-path logging four lines below this already used %x correctly.

In a multi-controller raft HA deployment, each controller signs
OIDC/OTT JWTs with its own root ctrl-plane-identity key. A JWKS lookup
landing on a controller other than the signer sees the true signer's
key advertised under this corrupt kid and cannot match it against the
token's kid header, failing verification.

Fixes #4067

Co-authored-by: Björn Mage <4495532+bjornmage@users.noreply.github.com>
2026-07-07 20:23:06 -04:00
Paul Lorenz ff619272ba Enforce api-session and identity revocations on the router. Fixes #3927
The router's CheckConnections reaper enforced only JWT expiry, so a revoked OIDC
api-session, or a disabled/deleted identity, kept its live circuits and hosted
terminators until the access token expired. The router now enforces the
RouterDataModel revocations directly, tightening access-loss propagation to the
reaper interval.

- adds a Type field to DataState_Revocation and the raft Revocation command
  proto, mirroring rest_model.RevocationTypeEnum (API_SESSION/IDENTITY/JTI) so the
  management API, OIDC producers, sync, and router enforcement share one
  vocabulary; the common.RevocationType* constants are compile-time bound to the
  enum to prevent drift
- adds an IssuedBefore cutoff so an identity revocation invalidates only sessions
  issued before it; a session re-authenticated after the cutoff survives the
  still-lingering revocation. Persists IssuedBefore on the db and model Revocation
  and carries it (plus the Type) through the single and batched raft marshalling
- adds RouterDataModel.IsApiSessionRevoked and IsIdentityRevoked and enforces both
  in CheckConnections, closing a revoked session's connections
- revokes a deleted or disabled identity's live OIDC sessions via an
  IdentityRevocationConstraint in the db package, run as a store pre-commit
  constraint so the revocation is written in the same transaction as the identity
  change and cannot be skipped (self-contained OIDC JWTs aren't otherwise
  reachable). NewIdentityManager installs it with the revocation type and lifetime
- has the OIDC end-session (TerminateSessionFromRequest) revoke the specific
  api-session named by the z_asid claim, with an identity-scoped fallback; sets
  IssuedBefore on the identity fallback and the management revocation API; adds
  RevocationManager.CreateOrReplace, routed through by both the OIDC paths and the
  management revocation API, so a repeat logout/termination/revocation refreshes
  the cutoff rather than colliding on the reused id. Expiry derives from the
  longest configured token duration via a shared common.MaxTokenDuration helper
- adds tests/revocation_enforcement_oidc_test.go covering api-session revocation
  (and a fresh session staying unaffected), identity disable and delete, and the
  identity cutoff (a post-cutoff session surviving the lingering revocation)
2026-06-13 01:36:12 -04:00
Andrew Martinez 949de99ee4 fixes #3809 support CSR submission during OIDC authentication (#3840)
* fixes #3809 support CSR submission during OIDC authentication

- accepts an optional CSR during OIDC login (all auth methods) and
  signs it into a session-bound certificate with a SPIFFE ID derived
  from the identity and API session
- returns the signed certificate PEM as a top-level "session_cert"
  field in the token endpoint JSON response (CodeExchange, RefreshToken,
  TokenExchange)
- adds cert-binding verification on RefreshToken and TokenExchange:
  if z_cfs is present the peer cert fingerprint must match (strict),
  otherwise falls back to SPIFFE ID verification
- supports cert rotation via csr_pem form parameter on refresh and
  token exchange; replaces the session cert fingerprint while
  preserving the authenticating cert fingerprint
- adds AuthCertFingerprints (z_acfs) claim to track permanent auth
  cert fingerprints separately from rotatable session cert fingerprints
- only the leaf certificate fingerprint is added to z_cfs and z_acfs,
  intermediates are never included
- invalid CSR returns 400 Bad Request in OIDC error format
- propagates updated CustomClaims (including CertFingerprints) from
  access token to renewed refresh token so rotated fingerprints are
  enforced on subsequent refreshes
- adds CertGenerated field to ApiSessionEvent
- advertises OIDC_AUTH_WITH_CSR controller capability when OIDC is
  enabled
- adds unit tests for verifyCertBinding (fingerprint, SPIFFE ID,
  edge cases) and CsrPem field parsing
- adds integration tests for initial CSR auth (updb, cert, ext-jwt),
  cert-binding on refresh/exchange, CSR rotation with cert auth,
  SPIFFE fallback and z_cfs transition, and CSR property forging
  resistance

* address pr concerns

* add z_cfs len tests on junk chain certs

* strip csr subject info, replace w/ santized values

* fix csr rotation rejection/paths during token exchange/refresh
2026-05-07 13:56:48 -04:00
Andrew Martinez 767ff11cfc fixes #3846 OIDC tokens from non-cert auth no longer bind incidental TLS certs (#3848)
- gates OIDC `z_cfs` claim on cert-based primary auth so non-cert sessions don't bind TLS-presented certs
- reorders router api session validation: fingerprint match first, then SPIFFE-on-first-party as fallback
- accepts first-party SPIFFE-Identity match as an acceptance signal (previously fell through to fingerprint check)
2026-05-06 21:41:19 -04:00
dovholuknf 7a6da85fdd add generic 'binding: spa', fix quickstart --home, lint cleanup 2026-05-03 11:08:40 -04:00
Andrew Martinez 8297a817b7 fixes #3734 enforce client certificate proof-of-possession for OIDC sessions (#3805)
* fixes #3734 enforce client certificate proof-of-possession for OIDC sessions

- adds verifyCertProofOfPossession() in resolveOidcSession() to require
  TLS client cert matching a z_cfs fingerprint or SPIFFE ID when the
  OIDC token was issued with cert bindings
- adds z_cae (CertAllowExpired) claim from auth policy, propagated
  through token issuance and refresh
- adds TrustCache.VerifyClientCert() with tiered pool matching
  (first-party roots, trust anchors, third-party) and TTL cache
- adds WrapIdentityWithCertValidation() on the router to verify client
  certs at the TLS level against RDM PublicKeys
- adds IsFirstPartyCert() on the router to gate SPIFFE ID matching by
  checking whether the cert chains to the controller root CA
- adds VerifySpiffeId() in common/spiffehlp with SpiffeMatchApiSession,
  SpiffeMatchIdentity, and SpiffeMatchNone return types
- adds SPIFFE IDs to OTT and token enrollment certs (/identity/<id>)
- enforces cert expiry by match type: API session certs must be valid,
  fingerprint-matched certs respect z_cae, legacy sessions skip checks
- shallow-copies leaf certs before overriding time fields in all cert
  verification paths to avoid races on shared x509.Certificate pointers
- fixes controllerRootCache setting inited=true before the ctrl channel
  is available, which permanently cached the failure
2026-04-23 12:00:46 -04:00
Andrew Martinez 82e9870cd6 fixes #3806 expose OpenZiti endpoints in OIDC discovery document (#3808)
* fixes #3806 expose OpenZiti endpoints in OIDC discovery document

- adds vendor-specific "openziti_endpoints" field to the
  /.well-known/openid-configuration response
- overrides Discovery() on the OIDC server to wrap the standard config
  with OpenZiti login and MFA endpoint URLs
- advertises password, cert, ext-jwt, totp, totp enrollment, and
  auth query endpoints as absolute URLs derived from the issuer
- adds integration test verifying all openziti_endpoints fields
- adds dual-server integration test confirming endpoint URLs reflect
  the correct issuer when edge-oidc is hosted on multiple bind points

* changelog
2026-04-22 10:54:53 -04:00
Andrew Martinez 69885639d3 fixes #3788 return proper OIDC error codes and HTTP status codes (#3790)
- migrates from op.NewProvider() to LegacyServer/RegisterLegacyServer,
  routing all OIDC endpoint errors through op.WriteError which maps
  server_error to HTTP 500 and supports custom status codes via
  op.StatusError
- returns oidc.ErrInvalidClient() from AuthorizeClientIDSecret for
  unknown clients and bad secrets (HTTP 400 with invalid_client)
- returns oidc.ErrInvalidGrant() from parseRefreshToken,
  parseAccessToken, createAccessToken, and renewRefreshToken for
  client-supplied token errors (HTTP 400 with invalid_grant)
- fixes copy-paste bug in parseAccessToken that reported "invalid
  refresh_token" for access token errors
- plain Go errors from server-side failures (identity read, JSON
  marshal, token signing, Raft dispatch) now correctly surface as
  HTTP 500 via WriteError's DefaultToServerError handling
- adds integration tests covering error codes for token endpoint,
  login endpoint, userinfo endpoint, and end_session endpoint
2026-04-14 16:44:06 -04:00
Paul Lorenz be641e99b2 Merge pull request #3576 from dmuensterer/fix/oidc-token-refresh-bugs
fix openziti/ziti#3575 OIDC token endpoint code bugs possibly resulting in panics/eof errors
2026-04-01 13:18:06 -04:00
Paul Lorenz 62e29169c2 Coalesce OIDC JWT revocations to reduce controller write pressure. Fixes #3681
- adds DeleteRevocationsBatchCommand so expired-revocation cleanup goes
  through raft as a single log entry per batch
- adds CreateRevocationsBatchCommand for batched revocation creation
  through raft
- moves refresh-token revocations from synchronous inline creation to a
  background batcher that flushes on a configurable interval, removing
  the database and raft as a bottleneck on token refreshes
- skips revocation creation for tokens expiring within a configurable
  threshold (revocationMinTokenLifetime), since they become invalid on
  their own
- validates that revocationMinTokenLifetime is less than 50% of the
  configured refresh token lifetime
- makes the revocation enforcer frequency configurable and restricts it
  to run only on the raft leader
- adds tests for multi-batch delete, batched create with router RDM
  propagation, and skip-threshold behavior
- adds new configuration tunables under edge.oidc: revocationBucketInterval,
  revocationMinTokenLifetime, revocationBucketMaxSize, revocationMaxQueued,
  revocationEnforcerFrequency
2026-03-19 08:35:00 -04:00
Andrew Martinez dbeb5c9f46 fixes openziti/ziti#3673 purge expired revocations, fix revocation bugs (#3679)
- fixes RevokeToken double-write: adds return after JWTID-keyed revocation
    save, preventing fallthrough write with raw JWT string as unreachable key
  - fixes TerminateSession key mismatch: stores revocation by identityId alone,
    matching the Subject-based lookup in ValidateAccessToken
  - fixes RevocationDelete sync action: passes DataState_Delete instead of
    DataState_Create so routers evict the entry from their data model
  - adds RevocationManager.DeleteExpired: batch-deletes expired revocations in
    batches of 500 until none remain
  - adds RevocationEnforcer: periodic policy runner (every 1 minute) that calls
    DeleteExpired and records metrics

before test fixes
2026-03-11 20:33:38 -04:00
Andrew Martinez 82a22e43b9 fixes #3496 allow TOTP enroll mid OIDC (#3656)
* fixes #3496 allow TOTP enroll mid OIDC

- detects unenrolled TOTP mid-OIDC flow and redirects to enroll endpoints
- adds enroll/verify endpoints in oidc_auth/login.go
- centralizes auth query storage rendering in oidc_auth/storage.go
- adds SDK integration tests for enrollment success, re-auth, cancelled
  enrollment, empty/alpha/wrong codes, and missing provider
- removes reduce rp server usage in tests
- refactors some oidc tests to new style where possible
- fixes amr regression in 2.0
- adds test for amr and auth_time
2026-03-11 16:27:31 -04:00
Andrew Martinez fb2034245d fixes openziti/ziti#3356 adds www-authenticate headers (#3561)
* fixes openziti/ziti#3356 adds www-authenticate headers

- www-authenticate headers are returned on 401s from API requests
- www-authenticate headers are returned during authentication to signal
  addtional JWT bearer tokens needed (secondary ext jwt)
- adds support for additional headers on API errors
- adds SecurityTokenCtx for centralized security header processing
  (legacy, jwt, etc.)
- adds SecurityCtx for centralized identity, auth policy, MFA handling
- refactors existing JWT authentication methods (oidc, legacy) to use
  centralized processing where possible
2026-02-24 10:01:36 -05:00
Dominik Münsterer 919218618d fix openziti/ziti#3575
Harden OIDC token endpoint against panics and silent failures

- Wrap OIDC handler with TimeoutHandler to match all other API handlers
- Fix GetRootTlsJwtSigner using rootCerts[0] instead of resolved rootCert
- Propagate Generate() errors in createRefreshClaims and renewRefreshToken
- Use safe type assertion for kid header in JwtSignerKeyFunc
2026-02-12 23:25:46 +02:00
Paul Lorenz da9ef76d19 Optimize imports 2026-01-28 15:01:35 -05:00
Paul Lorenz 2ffc6e1151 Update ziti version to 2.0 2026-01-28 12:34:10 -05:00
Andrew Martinez 5341bfe0b7 fixes openziti/ziti#3349 wrong content type for application/json accept (#3350) 2025-11-05 15:44:11 -05:00
Andrew Martinez bb5cc51a97 adds posture cache, instance, instance data, and event hooks (#3267)
* adds posture cache, instance, instance data, and event hooks

- reworks router security
- abstracts api session and service sessions
- use connection tracker instead of various maps
- doc
- adds service sessions as always JWTs
- addes token logging fields
- removes multiple connection tracking fields
- adds support for router specific posture data/respones
- adds support for router posture check evaluation
- defer dial/bind posture checking for legacy to controller
- fix double session event emitting
- fix session event missing id
2025-10-15 14:01:56 -04:00
Andrew Martinez f116212ed4 fix #3231 use root controller server certs for OIDC signing (#3236)
* fix #3231 use root controller server certs for OIDC signing

- addresses HA vs non-HA signing
- fixes issue where APIs server w/ difference certs than the root
  identity
- adds documentation for env/appenv
- adds a new composite type for TLSCert JWT signers

* address possible nil reference

* remove ineff assignment on jwt signing method
2025-08-26 09:29:50 -04:00
Andrew Martinez 423dff3d92 fix #3236 SDK/ENV info is not saved on OIDC auth (#3137) 2025-08-05 09:51:00 -04:00
Andrew Martinez 87c9ce3718 fix #3178 apis missing from controllers (#3180)
* fix #3178 apis missing from controllers, fixes #3193 adds totp auth query enrollment flag

- fixed controller store to no longer blank apis on all CUD actions
- controllers now report their current config state on leader change to
  avoid stale information
- fixes peer disconnect to only set online state
- adds enrollment state flags to auth queries
- adds test for OIDC MFA enrollment/recovery/delete
- adds controller store unit tests
2025-08-05 09:15:27 -04:00
Paul Lorenz b21db0faa1 Implement circuit validation API and CLI. Fixes #3098 2025-06-16 13:57:42 -04:00
Andrew Martinez 0506ef251b fix.3048.auth.events.impropert.chain.flag (#3050)
fixes #3084 adds events and improper chain flag

- splits cert resolution into root, legacy root + intermediate,
  and third-party pool. Allowing the detection of client authentication
  with incomplete chains if root + intermediate succeeds after root only fails
- adds `improperClientCertChain` to API Sessions and Current API Session.
  Added for OIDC and legacy auth. Set to true when a client certificate is used
  that was issued by the network and did not pass the root-only pool.
2025-05-21 11:49:39 -04:00
Andrew Martinez 0b8d674884 fix #2996 oidc extend and roll values not set (#3039) 2025-05-05 17:13:24 -04:00
Andrew Martinez 0ca892060f fix #2996 add ability to flag cert authenticators for extension/key roll (#3025)
* fix #2996 add ability to flag cert authenticators for extension/key roll
2025-05-01 17:41:00 -04:00
Andrew Martinez d410b74e66 fixes #2997 adds authenticator ids for OIDC jwts (#2998)
- updates current-api session logic to use new value
- sets z_authid in access/refresh tokens
- updates tests to ensure authenticator id is set on access/refres
2025-04-14 13:13:14 -04:00
Andrew Martinez aaaa875d44 fixes #2737 open-id config issuer mismatch (#2782)
* fixes #2737 open-id config issuer mismatch

- scans all SANs for possible supported hostname/ips
- add copyright, add better accept handling
- re-arrange where issuers are determined
- removes support for root openid-config
- fixes issuer mapping
- fixes endpoint tests
- add support for wild card certificates influencing issuers
2025-02-11 16:59:03 -05:00
dovholuknf 0a75dc68ac fix a typo 2025-01-27 15:30:13 -05:00
Andrew Martinez cd26cbf150 fixes #2689 form data doesn't respect query string authRequestID 2025-01-24 10:50:34 -05:00
Andrew Martinez f6bd0b394d fix ipv6 hostnames from URLs 2025-01-23 10:51:29 -05:00
Andrew Martinez 9100391c1b fixes #2674 default port and local address routing for oidc auth
- fixes :443 default port calls from clients (e.g. https and :443 left
  off)
- fixes localhost vs 127.0.0.1 vs ::1 bindings
2025-01-23 09:45:27 -05:00
Andrew Martinez 9f0d048114 fixes #2659 OIDC login panics on invalid media types 2025-01-17 10:25:25 -05:00
Paul Lorenz 71c7f6bb00 Add event source id to all events. Fixes #2619 2025-01-14 12:17:48 -05:00
Andrew Martinez d757798764 removes unused field 2024-11-04 09:19:27 -05:00
dovholuknf 8458b544ef linter issue? 2024-10-31 08:26:06 -04:00
Andrew Martinez b840291c58 makes OIDC issuer dynamic based on xweb bind point address 2024-10-18 09:55:15 -04:00
Andrew Martinez c2a62c9a8e Merge branch 'main' into fix.2354.auth.query.support.oidc 2024-10-04 11:22:16 -04:00
Andrew Martinez d0e0c6008a use new edge-api constants 2024-10-04 11:14:39 -04:00
Paul Lorenz b8294a98b1 Fix JWT refresh panic. Fixes #2460 2024-10-01 09:43:35 -04:00
Paul Lorenz 694b9dc18d Add events for JWT session for create/refresh/exchange. Fixes #2119 2024-09-30 15:32:48 -04:00
Andrew Martinez d96913df7a error with proper status code and do not read empty jwt signer ids 2024-09-30 10:34:36 -04:00
Andrew Martinez d2571413ad fix unused method 2024-09-23 10:39:58 -04:00
Andrew Martinez f8346be9cd fixes #2354 adds oidc AuthhQuery support 2024-09-23 10:14:31 -04:00
Andrew Martinez ada215b261 Merge branch 'main' into fix.2345.isCertExtendable 2024-09-03 10:00:51 -04:00
Andrew Martinez 7351c12412 fix #2353 update oidc dep which fixes down stream go-jose dep 2024-09-03 09:41:33 -04:00
Andrew Martinez 0ef6f03570 updates authenticator/api session logic for isCertExtendable
- updates legacy and oidc authentication for isCertExtendable
- updates authenticators REST responses to include isIsssuedByNetwork
2024-08-29 10:13:47 -04:00