Commit Graph

255 Commits

Author SHA1 Message Date
Paul Lorenz f1264086d4 Restore legacy API session activity marking for REST requests. Fixes #4365
- resolves zt-session tokens eagerly when the request context is created, so every request carrying one marks activity and gets session lifetime headers, regardless of endpoint
- marks last activity in SecurityCtx.resolveZtSession once the session is loaded
- adds SecurityTokenCtx.HasZtSessionHeader, a header-only check that does not parse bearer tokens
- emits only session lifetime headers from the API wrappers and drops the unused session-error header branch, so a stale token on an anonymous endpoint stays silent as it did on 1.6.x
- tests that requests to authenticated and anonymous endpoints with a zt-session mark activity, carry lifetime headers, and are reflected by current-api-session
2026-09-09 17:20:50 -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
Paul Lorenz ae8972bc24 Deliver the router data model to transit routers. For #3743
- Creates a router sender on demand when an untracked router subscribes to the
  data model, so non-edge (transit) routers receive their controller-managed
  configuration without going through the edge connect/sync flow
- Marks on-demand senders as supporting the router data model so they receive
  live model updates, not just the initial sync
- Restricts the legacy api-session/session broadcasts to edge routers, since
  routers register those handlers universally and would otherwise load session
  state they never use. A router counts as edge when an edge router record
  exists for its id, which is how both the connect path and the subscribe path
  classify it; senders carry the result as an atomic edge flag and the fanout
  walks them via RangeEdge. Classification is fixed for the life of a
  connection, so a record added or removed under a live connection takes effect
  on reconnect. Transit routers also never receive the initial session state,
  which only follows a hello
- Adds a race-safe routerTxMap.GetOrCreate keyed on the control channel; the
  subscribe path always routes through it, replacing a sender bound to a stale
  channel instead of enqueueing on a dead one, and resolves edge-router
  membership up front so a replaced edge sender is not demoted to transit
- Adopts an existing sender for the connecting channel in RouterConnected instead
  of rejecting it as a duplicate connect; a subscribe that creates the sender first
  would otherwise leave the router with no server hello, so it never sends a client
  hello and never synchronizes while still being reported online
- Removes routerTxMap.Add, leaving GetOrCreate as the only way a sender is installed
- Classifies a connecting router as edge by id rather than by fingerprint, matching
  the disconnect and subscribe paths, and logs an unexpected store error instead of
  discarding it
- Removes the unused RouterSender.EdgeRouter field and drops the edge router
  argument from the RouterConnected handler
- Generalizes router connect/disconnect logging that previously assumed edge routers
- Updates the strategy flow comment and RouterSender godoc, which described senders
  as edge-only and referenced the removed EdgeRouter field
- Documents that api-session-added events and the legacy session model (API and
  service sessions) are deprecated for removal in OpenZiti 3.0
- Adds unit tests for GetOrCreate (create/reuse/stale-replace/concurrent), the
  edge-only fanout filter, and RouterConnected adopting a subscribe-created sender
2026-08-19 00:51:39 -04:00
Paul Lorenz 2d766accd6 Merge pull request #4147 from openziti/fix/legacy-session-accept
Accept legacy sessions and signal recovery for invalid service tokens
2026-08-13 12:07:24 -04:00
Paul Lorenz d7076430c9 Make ER/T terminator create failures diagnosable. Fixes #4193
- reports edge router policy denials with an access-denied error naming the missing policy,
  replacing the session error reused on the sessionless ER/T and create-circuit-v3 paths
- adds EdgeRouterManager.GetEdgeRouterAccess, which reports which of the two required policy
  links (identity-to-edge-router, service-to-edge-router) is absent, and removes the boolean
  IsAccessToEdgeRouterAllowed it replaces
- logs the controller's rejection on the router at warn level, since it is recoverable and
  retried by the periodic scan; the router previously discarded the error code and message
- delays a new terminator's first create attempt by a fixed 2s so config applied in quick
  succession settles before the router asks, avoiding a 2-3 minute wait for the retry scan; the
  delay is a deliberate stopgap until edge router policy visibility lands in the router data model
- propagates the controller's error code and retry hint to SDK clients on the dial paths, which
  dropped the code and left every refusal classified as unknown
- adds the retry hint header to controller error replies, grouped with the other error-reply
  headers rather than the create-circuit-v3 request headers
- notes that the sync strategy headers alias the edge namespace's 1013-1015 ids and stay
  disjoint only by message content type
- tests the per-policy denial reporting, the error code carried with and without a retry hint,
  the controller-to-SDK error code mapping at both dial relay sites, and the terminator settle
  gate
- waits for terminator establishment in the tunneler dataflow tests instead of a fixed sleep, so
  they no longer race the settle delay
- restores the tproxy multiple-lanIf and multiple-resolver changelog entries with keep markers,
  which regeneration drops because their commits reference pull requests rather than issues
2026-08-03 15:43:30 -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
Paul Lorenz f219e6d035 Accept legacy sessions and signal recovery for invalid service tokens. Fixes #4145
- loadFromBolt now accepts a non-JWT (legacy/durable) service session token by
  looking the session up via Session.ReadByToken and verifying it belongs to the
  api session, so a legacy client's existing session keeps working across a
  controller upgrade instead of failing as a malformed JWT
- classifies service-access token validation failures (malformed, expired, bad
  claims, mismatched api session, revoked) as InvalidSession so the client
  re-creates, while revocation-store/datastore read failures remain internalError
  so a transient controller fault does not make clients discard valid sessions
- adds a typed common.InvalidTokenError so ValidateServiceAccessToken can
  distinguish token-level failures from infrastructure failures
2026-07-23 10:53:22 -04:00
Paul Lorenz 86092a8640 Migrate to the sdk-golang v2 module path. For #3884
Bumps the sdk-golang dependency from v1 to the v2 module
(`github.com/openziti/sdk-golang/v2` at v2.0.0-pre1) and updates all
import paths. This is a no-behavior-change precursor that isolates the
dependency migration from the Connect-V2 feature work in #3884.

- Rewrites `github.com/openziti/sdk-golang/...` imports to
  `github.com/openziti/sdk-golang/v2/...` across the main and zititest
  modules.
- Pins both modules to `github.com/openziti/sdk-golang/v2 v2.0.0-pre1`.
- Adapts `edgeXgressConn.AcceptMessage` to the v2 `MsgSink` signature,
  which now takes an `edge.SdkChannel` argument.
- Replaces the removed `edge.Conn.GetRouterId()` with
  `RemoteAddr().String()` in the loop4 traffic-test logging.

For openziti/sdk-golang#936.
2026-06-23 15:43:39 -04:00
Paul Lorenz ae806045b5 Convert self-describing receive handlers to channel/v5. For #3983
- channel.TypedReceiveHandler -> channel.ContentTypeReceiver
- binding.AddTypedReceiveHandler(h) -> channel.AddReceiveHandlers(binding, h)

channel/v5 repurposes TypedReceiveHandler for the senders-typed handler and replaces the
self-describing pattern with ContentTypeReceiver plus the AddReceiveHandlers free function
(openziti/channel#262). Mechanical conversion; does not build on its own.
2026-06-18 12:51:02 -04:00
Paul Lorenz 1c122af490 Rewrite channel/v4 imports to channel/v5. For #3983
- moves the channel dependency to channel/v5 v5.0.10 and sdk-golang to v1.9.0 in the root and zititest modules
- mechanically rewrites every channel/v4 import path to channel/v5

This is the import-path-only step; the API-level changes the switch requires land in the following commit. This commit does not build on its own.
2026-06-18 12:51:02 -04:00
Paul Lorenz 975a23e5f6 Add a recover mechanism for when a controller cluster can't form a quorum. Fixes #3849
- adds 'ziti ops cluster recover <controller-config>', an offline CLI
  that opens a stopped controller's data directory, forces the raft
  configuration to a single local node via raft.RecoverCluster, and
  aligns the FSM-tracked member list in ctrl-ha.db so stale peers don't
  leak through IsPeerMember or CtrlAddresses on restart
- removes the previous in-process recovery path: the cluster.recover
  config flag and the corresponding RaftConfig.Recover field are gone,
  along with the os.Exit branch in Controller.Init that consumed them
- adds BoltDbFsm.OverwriteServers and GetCachedServers so offline
  tooling can update and inspect the FSM-side server list without a
  live raft instance; OverwriteServers runs before raft.RecoverCluster
  so the snapshot it produces captures the corrected configuration
- updates Broker.AcceptClusterEvent to call DeleteRemovedPeers on every
  ClusterLeadershipGained, making the controllers entity table
  self-healing for any membership change a non-leader missed (offline
  recovery, or a 'cluster remove' applied while another node was leader)
- wires the new subcommand into both V1 and V2 CLI roots so it's
  reachable regardless of ZITI_CLI_LAYOUT
- switches filesystem path joins in the raft package and the recover
  command from path.Join to filepath.Join
- tests bootstrap a two-node configuration, run recoverDataDir, then
  verify the post-recovery snapshot, the FSM-cached server list, and
  Fsm.GetCurrentState (after starting a real raft instance) all report
  the survivor only
2026-05-27 09:23:01 -04:00
Paul Lorenz 82ac2e8060 Rework connect event handling to ensure serialized-per-router handling 2026-04-24 13:22:02 -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
Paul Lorenz 4df6ae564d Update package paths for newly imported storage and ziti-db-explorer packages 2026-04-16 09:18:55 -04:00
Andrew Martinez 6515e3615c fixes #3680 add revocation management API, CLI, and enforcement (#3789)
* fixes #3680 add revocation management API, CLI, and enforcement

- adds Management API endpoints for revocations (POST, GET, LIST) with
  type-aware validation (JTI/API_SESSION require UUID, IDENTITY requires
  existing identity)
- adds CLI commands: ziti edge create revocation identity|api-session|jti
- adds revocation checks to resolveOidcSession in security_ctx.go so the
  REST API returns 401 for revoked OIDC tokens. Previously only
  ValidateAccessToken (router ctrl channel path) checked revocations,
  so revoked tokens still received 200 OK from the management and client
  HTTP APIs
- adds api-session revocation check to ValidateAccessToken, which only
  checked JTI and identity revocations
- adds Type field to Revocation model, store, and protobuf message
- adds integration tests covering CRUD, input validation, and token
  enforcement for all three revocation types
- use release edge-api@v0.28.1
2026-04-14 15:53:03 -04:00
Paul Lorenz f2db0e147d Fix connect events handler goroutine leak. Fixes #3746
- replaces the per-handler goroutine in connectEventsHandler with a shared,
  bounded goroutine pool on AppEnv
- the old design spawned a processEvents goroutine per router connection that
  only exited on application shutdown, leaking a goroutine on every reconnect
- adds ConnectEventsConfig to the controller config with pool tuning options
  (queueSize, minWorkers, maxWorkers, idleTime)
- defaults: queue 16, 0-16 workers, 30s idle timeout
2026-04-02 23:44:43 -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
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 a9dd2fc8f8 fix.openziti.ziti.3597.OIDC.by.default (#3605)
* fixes #3597, enable OIDC by default

- adds ability to have different sets of environment configs for tests
- adds ConfigSet struct as a configuration device for integration tests
  - allows entire environments to be defined as needed
  - original ats config set at "default-ats"
  - tests that do not specify a config set, use "default-ats" as before
- standardizes configuration location, naming, etc.
- adds README.md for the above
- updates testContext to now be config set aware
- add config value to disable, update tests, changelog
- add defense against cached version data for tests
2026-03-04 10:03:14 -05: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
Paul Lorenz c18a594b56 Clustering coordination fixes
* Allow routers to request current cluster membership information. Fixes #3503
* Get cluster membership information from raft directly, rather than trying to cache it in the DB. Fixes #3501
* Set a router data model timeline when initializing a new HA setup, rather than letting it stay blank. Fixes #3500
* Reduce router data model full state updates. Fixes #3504
2026-01-17 02:03:31 -05:00
Paul Lorenz ae8306942c Add permissions list to identity. Fixes #3430. Add read-only permission. Fixes #2109. Add CRUD permissions by entity type. Fixes #3435 2025-12-18 10:54:08 -05:00
Paul Lorenz 701fe9ffd9 Move fabric router/service/terminators rest api code common location 2025-12-05 10:35:25 -05:00
Paul Lorenz a9594966a2 Consolidate circuit rest api code into common location. Fixes #3410 2025-12-05 09:54:10 -05:00
Paul Lorenz d37c721c83 Optimize router data model subscription code. Add additional events. Fixes #3359 2025-12-02 11:37:38 -05:00
dovholuknf caee6124e2 add support for and identity-driven bindPoints in controller (#3315)
* add support for and identity-driven bindPoints in controller

* cannot use ListenOptions as it pulls the go sdk into xweb :(

* more generic log message

* add ziti cli login tests in prep for continuing adding identity support in controller

* updates to tests

* updates to tests

* rebase with main

* allow login testing to external overlay

* more changes to allow a zitified ziti cli. add a test for testing login and ensure it works over a zitified connection

* refactor bindPoints to a module

* rebase with main

* no functional changes, just major refactoring based on PR requests. encapsulated all tests state into loginTestState, moved overlay to testutil

* rework a couple of util funcs to be cleaner per PR feedback

* make the new func more useful

* run tests via github action

* update changelog and remove unnecssary serveTls for now

* update from xweb v2 to v3

* change where factory is added and fix compilation issue of a test

* linting changes, move ascode test to cli_tests and activate via cli_tests

* use proper go build

* forgot to set the bin location

* fix timeout on test

* different errors on linux, windows and on gh runners

* cleanup after self-pr review

* use longer name to prevent codespell issues...

* additional changelog and add addressable terminator support

* fix out of control concatenation in cache file. fix ipv6 checking

* updates based on newer sdk and edge api client

* ensure oidc sessions auth for both older and newer commands

* add better error when url is empty and update changelog

* codespell fixes

* remove extraneous file

* update to 1.3.0 to kick off CI

* PR related changes. add interface enforcer and refactor networkIdentity

* go tidied

* fix golangci-lint and ha quickstart test

* keep fixing golanglint-ci... lol

* golanglint i was sure i'd fixed

* fix login test

* should fix ziti ops verify traffic as well

* fix verify traffic when all login information is supplied as well

* make all the timeouts longer? seems to run fine locally but fail in actions
2025-11-14 11:07:52 -05:00
Andrew Martinez ce83c0fb7c fixes openziti/ziti#2324 add token based enrollment (#3342)
* fixes openziti/ziti#2324 add token based enrollment

- allows enrollment to certificate auth
- allows enrollment to ext jwt token auth
- alters ext jwt claimsProperty (maps identity id) to support JSON
  pointers, defaults to `/sub`
- adds ext jwt enrollToCert, enrollToToken to controller  valid
  enrollment end-authenticator state
- adds ext jwt enrollAuthPolicyId to map end identity auth policy to,
  defaults to `default`
- adds ext jwt enrollAttributeSelector, supports single field name or
  JSON pointer to point to a single string or array of string attributes
  to give the identity, defaults to no selector
- adds ext jwt enrollNameSelector, supports single field name or JSON
  pointer to a string field to use as the name, defaults to `/sub`
- add enrollment errors to determine if enrollment has occurred
- adds CLI support for ext jwt signer enroll flags
2025-11-05 15:43:49 -05:00
Paul Lorenz af09450961 Fix golangci-lint errors 2025-10-17 12:54:25 -04: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
Paul Lorenz f7caf82276 Update for deprecation of HA flag in Go SDK 2025-08-18 19:28:28 -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
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 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
Paul Lorenz e647d67325 Update to channel/v4 2025-04-02 15:28:59 -04:00
Paul Lorenz 5a55aba493 Controller not removed from DB controller store when removed from controller. Fixes #2906 2025-03-29 00:19:52 -04:00
Andrew Martinez 56daae2025 fixes #2796 generated clients for enrollment do not work (#2883)
* fixes #2796 generated clients for enrollment do not work

- default behavior complies with OpenAPI spec, but allows for legacy PEM
  handling through middleware intervention
- adds test for generic enrollment endpoint and for specific enrollment
  endpoints
2025-03-17 10:05:15 -04:00
Paul Lorenz 437634972b Merge pull request #2892 from openziti/fix-restore-panic
Fix restore if db is restored in multiple locations. Fixes #2891
2025-03-14 14:58:02 -04:00
Paul Lorenz bcd62369c6 Fix online/offline status for ER/T identities. Fixes #2889 2025-03-14 13:38:17 -04:00
Paul Lorenz ed6194b333 Fix restore if db is restored in multiple locations. Fixes #2891 2025-03-14 13:00:46 -04:00
Paul Lorenz 50a4cca051 Fix controller online status. Fixes #2854 2025-03-10 09:49:30 -04:00
Paul Lorenz 03870760c3 Ensure restores and migrations work properly with RDM. Add restore from db for HA Clusters. Fixes #2549. Fixes #2649. Fixes #2707 2025-01-31 13:57:43 -05:00
Andrew d761a18881 Merge pull request #2645 from openziti/fix.2644.mismapped.id.ext.jwt
fixes #2644 fixes log output for secondary jwt on mismatched identity
2025-01-21 13:48:40 -05:00
Andrew Martinez 4af95eea6c fixes #2644 fixes log output for secondary jwt on mismatched identity
enhances logging and checks for scenarios where the wrong identity was
configued with the matching external id
2025-01-13 14:44:23 -05:00
Paul Lorenz b1e5a3e811 Remove path from connect events dst addr. Fixes #2624 2025-01-09 16:45:08 -05:00
Paul Lorenz 6517a7c22f Move routers to a subscription model where they subcribe to model data from one controller for a limited time. Fixes #2599 2025-01-07 19:21:53 -05:00