- 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
- 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
- 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
- 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
- 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
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.
- 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.
- 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.
- 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
* 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
* 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
- 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
- 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
* 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
* fixesopenziti/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
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
* 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
* 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
* fixesopenziti/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
* 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
* 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
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.
- 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
* 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