Commit Graph

1648 Commits

Author SHA1 Message Date
Paul Lorenz 158e52b60e Merge pull request #4013 from openziti/issue-4010-enrollment-priv-escalation
Prevent enrollment-based privilege escalation to admin identities. Fixes #4010
2026-06-26 13:13:18 -04:00
Paul Lorenz 5fb197935d Deny enrollment access on identity read error. For #4010
- returns false (denies) instead of true when reading the target
  identity fails, so an error cannot be treated as a non-admin identity
2026-06-26 12:07:31 -04:00
Paul Lorenz 2dc4075446 Make listener ctrl channels multi-underlay-capable. For #3983
- gives ListenerCtrlChannel Min: 0 constraints per underlay type plus
  MinTotalUnderlays: 1 in its configs, so the controller accepts the
  high/low-priority grouped underlays the router dials while still closing the
  channel only when its last underlay is lost
- restores the multi-underlay behavior the v4 listener-side SetMinTotal(1)
  provided, which the channel/v5 migration dropped
- works around channel/v5 not yet treating MinTotalUnderlays alone as a
  multi-underlay signal
2026-06-22 14:53:47 -04:00
Paul Lorenz 3027fdffd3 Prevent enrollment-based privilege escalation to admin identities. Fixes #4010
- blocks non-admins from creating an enrollment that targets an admin identity
- blocks non-admins from reading, refreshing, or deleting an admin identity's enrollment
- filters admin identity enrollments out of enrollment lists for non-admin callers
- adds a permissions test covering the escalation paths and admin-allowed behavior
2026-06-19 12:27:53 -04:00
Paul Lorenz 1c877e2501 Migrate to channel/v5 deferred-ack accept API. For #3983
- switches the xlink transport and router ctrl listeners to NewClassicListenerWithAcceptor, passing the MultiListener as a HelloAcceptor
- replaces the controller ctrl channel's NewClassicListener/UnderlayDispatcher wiring with NewClassicListenerWithAcceptor and a TypeRoutingAcceptor, adapting the mesh acceptor via AsHelloAcceptor
- removes the multiListenerAcceptor wrapper now that MultiListener implements HelloAcceptor directly
- removes the xgress_edge Acceptor.Run Create-loop, handing underlays to the MultiListener through the acceptor-based listener
- moves the controller ctrl connect handler into ListenerConfig.ConnectionHandlers
- updates ctrlchan channel tests to the new constructor
2026-06-18 12:51:02 -04:00
Paul Lorenz d481224c9b Decompose multi-underlay channels onto the channel/v5 API. Fixes #3983
- decomposes the ctrlchan, xlink and edge-listener channels onto the v5 Senders, MessageSourceProvider and UnderlayEventListener interfaces, replacing the v4 UnderlayHandler god-interface
- replaces the hand-rolled dial/grouping/backoff machinery with channel.BackoffDialPolicy and declarative Constraints; ctrl keeps survive-to-zero (Min: 0) with MinStableDuration: 0 for prompt reconnect, while xlink and edge default underlays keep Min: 1 so loss closes the channel
- builds grouped channels via channel.NewChannel(*Config) and moves handler retrieval to GetSenders()
- records the channel via InitChannel from each bind handler, before underlay events fire, so handlers registered during bind do not dereference a nil channel
- generates a group secret for ungrouped inbound ctrl underlays on the router accept path, matching the controller, since NewChannel requires one
- preserves link-id-as-channel-id (the link dial policy wraps the cloned link-id identity dialer) and adds a test asserting dialed underlays present the link id
- registers the latency handler explicitly, as it is no longer a self-describing receiver in v5
2026-06-18 12:51:02 -04:00
Paul Lorenz ee8ad78e3b Rename MultiChannel to the unified Channel for channel/v5. For #3983
- channel.MultiChannel -> channel.Channel
- channel.MultiChannelConfig -> channel.Config
- channel.NewMultiChannel(...) -> channel.NewChannel(...)

channel/v5 unifies Channel and MultiChannel into a single Channel abstraction. This is the
mechanical token rename; the Config field changes and handler retrieval that the unification
requires land in the following commit. The two channel.go files that are fully rewritten for
v5 (common/ctrlchan, router/xlink_transport) are excluded here and rewritten in that commit.
Does not build on its own.
2026-06-18 12:51:02 -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 08aa26a051 Rename single-underlay channel constructors for channel/v5. For #3983
- channel.NewChannel(name, factory, bindHandler, opts) -> channel.NewSingleChannel(...)
- channel.NewChannelWithUnderlay(...) -> channel.NewSingleChannelWithUnderlay(...)

channel/v5 repurposes NewChannel for the unified multi-underlay constructor, so the
single-underlay call sites move to the renamed helpers. Mechanical rename only; like the
preceding import commit it 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 0ee288ecbf Distribute routers and router-target configs through the RDM. Fixes #3976 (#3977)
- adds a `DataState.Router` event variant (id, name, fingerprint,
  configs) to the RDM protobuf and the matching ConfigType.Target field
  flows
- loads routers into `RouterDataModelSender` at startup and registers
  entity-change listeners so router create/update/delete and config
  reassignment emit RDM events
- filters `Config` events per-router at `RouterSender`: each router
  sees the full `Router` set but only its own router-target Configs
- receiver-side: parses and stores `Router` entities; GCs router-target
  Configs locally when they drop off the router's `Configs` list, so
  no synthetic remove events are needed on the wire
- extends the `router-data-model-test` fablab model with router-config
  distribution scenarios (assignment, reassignment, controller
  restart, RDM cache miss)
- updates `validate-router-data-model` to recognize the new event
  shape
- refreshes the design doc to describe per-router filtering and the
  change-notification flow
2026-06-16 22:31:43 -04:00
Paul Lorenz 1d6333a6c0 Add router.link.v1 config type. Fixes #3974 (#3975)
* Add router.link.v1 config type. Fixes #3974

- adds the built-in `router.link.v1` ConfigType with a JSON schema
  covering listeners, dialers, heartbeats, payload/ack sender queue
  sizes, and `gcMode` for auto-GC of stale links
- targets routers (`Target=router`) via the field added in #3743
- registers it for new databases via `createConfigType` in
  `initialize`, and for existing databases via a migration step that
  bumps the schema version 46 -> 47
- adds config-type-store tests covering registration, the router
  target, and migration-driven creation on existing databases
- documents the Phase 1c step in the controller-managed router
  configuration design doc

* Address review feedback on router.link.v1 config type. For #3974

- broadens the duration schema pattern to accept compound and fractional values (e.g. 1h30m, 1.5h) matching time.ParseDuration
- adds the gcMode schema property (enum preserve/orphaned/changed) to the built-in config type so its definition is complete where the type is created
- adds duration-format and gcMode validation test cases
- removes the now-unnecessary per-iteration loop variable copy in the reject-cases test
2026-06-16 16:38:13 -04:00
Paul Lorenz f18ce1b580 Collapse fabric and edge services at the db level. Fixes #3934
- collapses the edge service boltz child store into the unified service store:
  EdgeService becomes a type alias for Service, and RoleAttributes, Configs, and
  EncryptionRequired become top-level Service fields
- adds an IsFabricOnly discriminator separating pure-fabric ("management")
  services from edge services
- adds a forward-only, irreversible migration that moves edge service data out of
  the edge child bucket, classifies pre-existing services (fabric -> IsFabricOnly
  with encryptionRequired=false; edge -> IsFabricOnly=false), deletes the old edge
  bucket and its index, and rebuilds the role-attributes index via CheckIntegrity
- guards every edge-facing path on the unified store against fabric-only services
  so they stay invisible to the edge API: by-id Read/ReadByName/Delete, list/query
  and the detail lister, ReadForIdentity, identity service-config overrides,
  service policy / SERP @id and #all/role denormalization, the association-list
  routes (terminators, policies, configs), and the router data-model sync
- rejects edge-surface updates of fabric-only services, and preserves edge fields
  on fabric-surface updates of edge services
- marks the fabric-only guards TEMPORARY(fabric-edge-collapse): they exist only to
  keep seldom-used management services hidden, and are removed when the fabric/edge
  distinction is erased
- adds in-CI migration tests (forward plus a round-trip asserting FK sub-bucket
  relocation and forward/reverse refcount preservation), durable fabric-only
  behavior tests, and store-level policy-exclusion tests
- adds one-time authentic-migration gate tooling under zititest/migration-test
  (create-model.sh, query, verify) and its operator runbook
2026-06-16 13:04:13 -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
Paul Lorenz 9483c39bbd Consolidate agent channel plumbing into common/agent. Fixes #3894
- adds HandleChannelConnection (server-side conn-to-channel upgrade) and the
  client-side NewChannel/ConnToChannel/MakeChannelRequest helpers to common/agent;
  these import channel/v4 + identity, which are already root-module deps, so there
  is no go.mod or Go-version change
- replaces the duplicated agent channel-upgrade handlers in controller, router,
  tunnel, and demo with one-line delegations to common/agent.HandleChannelConnection
- moves the CLI-side channel dialer (was NewAgentChannel/connToChannelMapper/
  MakeAgentChannelRequest in agentcli) into common/agent and repoints the agentcli
  and demo callers
- normalizes the demo echo-server to accept the AppIdAny wildcard, matching the
  other agent servers; previously it rejected it
- preserves the wire protocol (leading app-id byte, "agent" channel, 1s connect
  timeout), so existing channel-based agent commands are unchanged
2026-06-12 15:47:03 -04:00
Andrew Martinez 9470c1f126 fixes #3952 reject invalid externalIdClaim and stop enrollment panic (#3953)
* fixes #3952 reject invalid externalIdClaim and stop enrollment panic

- moves the error check before the locator assignment in Ca.GetExternalId
  so an unsupported matcher/parser no longer nil-derefs and returns HTTP 500
- guards the claim index against negative and out-of-range values and errors
  when a matched claim resolves to an empty string, so an empty externalId is
  never silently accepted nor mapped to an identity
- adds validateExternalIdClaim, rejecting unsupported locations, unsupported
  matcher/parser combos, missing matcher/parser criteria, and negative indexes
  with HTTP 400 at CA create and update time
- applies the validation to both CA create and update, which previously had
  no externalIdClaim validation on the update path
- tests GetExternalId across the matcher/parser matrix for no-panic and
  correct error/value behavior
- tests CA create and update reject invalid externalIdClaim configurations
- tests that an externalIdClaim resolving to empty fails enrollment cleanly

* address pr review

- treats an externalIdClaim with no location as no claim in GetExternalId so an
  empty stored claim (e.g. the empty bucket older CLIs leave behind) falls back to
  fingerprint enrollment instead of erroring
- validates the merged result on CA update rather than the raw request: a partial
  patch overlays only its supplied subfields onto the stored claim, an empty {}
  object preserves the stored claim, and a full replace validates as-is
- skips externalIdClaim validation on update when no claim is supplied, fixing a
  spurious rejection of updates to CAs that have no claim
- reports the offending location/matcher/parser in the externalIdClaim validation
  error instead of the raw struct
- adds a --clear-external-id-claim flag to update ca and only sends the claim object
  when a claim flag changed, so existing updates preserve the claim and clearing is
  explicit
- tests externalIdClaim patch merge, preserve, and clear behavior, and that an
  unconfigured claim reads as no claim
2026-06-12 13:52:54 -04:00
Paul Lorenz cdc5d89885 Add configs field to routers. Fixes #3780 2026-06-11 13:45:58 -04:00
Paul Lorenz 0ba057e1bf Merge pull request #3918 from openziti/extend-attribute-search
Add role-attribute usage queries. Fixes #1593
2026-06-10 13:00:40 -04:00
Paul Lorenz a582fe5d0f Add role-attribute usage queries. Fixes #1593
- adds management API endpoints listing role-attribute usage for identities,
  edge routers, services, and posture checks, reporting per-source counts
  (and optionally ids via withIds) across home-entity collections and the
  policies that reference each attribute
- adds RoleAttributeUsage model with QueryRoleAttributeUsage, mapping each
  RoleAttributeKind to its contributing sources, with all reads in a single
  transaction so counts stay consistent with the attribute list; returns an
  empty result (not a panic) for kinds with no attributes and an error for
  unknown kinds
- adds boltz.SetIndexValueTransform and AddSetIndexWithTransform, letting a
  SetIndex filter and rewrite symbol values without persisting a derived field
- adds derived role-attribute set indexes to the service policy, edge router
  policy, and service edge router policy stores, built from existing role
  fields via a role-attribute-only transform that excludes the #all wildcard
- adds a db migration that backfills the new indexes via each index's own
  CheckIntegrity(fix=true), scoped to the role-attribute indexes only, with a
  per-index summary log, stopping at the first error
- tests the new endpoints via the typed edge-api management client
2026-06-10 12:39:26 -04:00
Paul Lorenz df2054e003 Merge pull request #3950 from openziti/fix-delete-trigger-err-return
Return event-firing error in DeleteById instead of swallowing it
2026-06-09 23:38:03 -04:00
Clint Dovholuk 929bd5670f Merge pull request #3913 from openziti/wildcard-oidc-updates
fix oidc auth fails with wildcard server-cert SANs
2026-06-09 15:34:15 -04:00
Paul Lorenz 83bed76574 Return event-firing error in DeleteById instead of swallowing it. Fixes #3949
- returns the error from changeFlow.fireEvents() so a failed delete rolls back the transaction instead of reporting success
2026-06-09 12:49:24 -04:00
Paul Lorenz b5eaeefdb3 Prep for channel v5: bind handler invocation, send priorities. Fixes #3942
- invokes bind handlers via h.BindChannel(binding) instead of binding.Bind(h), which channel v5 removes from the Binding interface
- removes WithPriority from edge dial and state message sends; priority was already a no-op on grouped channels and channel v5 removes the priority API
2026-06-05 15:24:45 -04:00
dovholuknf 4af10297d3 rework wildcard oidc per PR comments 2026-06-03 13:15:49 -04:00
dovholuknf 92fa63adaa fix openziti/ziti#3891: oidc auth fails with wildcard server-cert SANs. add wildcard-cert discovery test + keep wildcard SANs as issuers 2026-06-01 11:07:05 -04:00
Paul Lorenz 2bf9808df6 Add target field to config types. Fixes #3744 2026-05-27 13:17:06 -04:00
Paul Lorenz ba809e4d26 Keep controller mesh fully connected, as much as possible. Fixes #3684 2026-05-27 10:21:34 -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 91edc68409 Set fsm.startIndex on FSM init. Fixes #3860
- adds the missing self.startIndex assignment in BoltDbFsm.Init so
  GetStartRaftIndex() returns the persisted raft index instead of 0,
  which was leaving the RDM's RaftIndexProvider seeded at 0 on every
  restart and reporting a stale index until the next command applied
- adds a regression test that opens an FSM, persists a raft index,
  reopens it, and asserts GetStartIndex reflects the persisted value
- notes the fix in CHANGELOG.md under the ziti/v2 issue list
2026-05-11 19:12:16 -04:00
Paul Lorenz c73ea941dd Tidy duplicate permission types. Remove vestigial info message. Update changelog 2026-05-08 11:34:20 -04:00
Paul Lorenz 7c82e2d2c1 Filter current api session certs by current api session id. Fixes #3855 2026-05-07 14:28:43 -04:00
Paul Lorenz 67d34ef829 Fix permissions check on list controllers in management API. Fixes #3838 2026-05-07 14:28:43 -04:00
Paul Lorenz 8a3ad21365 Fix incorrect permissions check on create db snapshot with path. Fixes #3837 2026-05-07 14:28:43 -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
Paul Lorenz 82ac2e8060 Rework connect event handling to ensure serialized-per-router handling 2026-04-24 13:22:02 -04:00
Paul Lorenz c44350b3a7 Support ziti agent inspect so ziti processes can be inspected via IPC. Fixes #3824. Fixes #2049
- adds `ziti agent inspect <value>...` CLI that sends an InspectRequest directly to a ziti process over its agent IPC channel and pretty-prints JSON values in the response
- accepts app id 0 on controller and router agent channels so a single inspect command works against any process type
- adds Controller.agentOpInspect, backed by a new InspectionsManager.InspectLocal that runs inspect processing on the local controller only, without fanning out to routers or peer controllers
- extracts the router inspect handler into a new router/inspect package and stores a single shared instance on Router, reused by both the control channel and the agent IPC channel
- adds RouterEnv.GetInspectHandler and RouterEnv.GetXgressListeners so the control channel bind pulls the shared handler from env
- removes the now-redundant InspectRouterEnv interface from handler_ctrl/bind.go
- adds tunnel HandleAgentAsyncOp with support for stackdump and sdk inspect keys
2026-04-24 12:12: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
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
Paul Lorenz 0042f6a345 Merge pull request #3810 from openziti/db-explorer-import-pr
Import the storage and ziti-db-explorer repos into the ziti repo
2026-04-21 09:54:19 -04:00
Paul Lorenz 9ac9a4f17a Filter service policies by type="Dial"/type="Bind" in queries. Fixes #3818
- registers the service policy type symbol as a string, so queries match the
  API's "Dial" and "Bind" names rather than the internal int32 ids
- adds a symbol mapper that converts the stored int32 to its PolicyType name
  at query eval time
- updates the posture-checks lookup in EdgeServiceManager, the only direct
  caller that went through GetSymbol, to read the mapped string form
- adds a store test covering type = "Dial" and type = "Bind" filtering
- notes the breaking removal of the undocumented type = 1/type = 2 form in
  the 2.0 deprecation cleanup list
2026-04-20 15:25:37 -04:00
Paul Lorenz 040016993e Fix codespell errors 2026-04-16 09:43:49 -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
Paul Lorenz 9efd930fbd Merge storage project into controller/storage 2026-04-15 16:17:42 -04:00
Paul Lorenz 596e018e25 Merge pull request #3792 from openziti/specific-router-error-types
Add specific circuit failure error codes. Fixes #3717, #3543, #3364, #2888, #2859, #1580
2026-04-14 17:26:31 -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 90f32affda Address review comments 2026-04-14 16:09:19 -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 538623ceb6 Add specific circuit failure error codes. Fixes #3717, fixes #3543, fixes #3364, fixes #2888, fixes #2859, fixes #1580
- adds ErrorType constants for rejected-by-application, DNS resolution failed,
  port not allowed, invalid link destination, and resources not available
- adds corresponding CircuitFailureCause strings reported in circuit events
- extracts classifyDialError() in route handler to map dial errors to specific
  error codes using typed errors, syscall constants, and string matching
- detects DNS errors via *net.DNSError and string fallback for ER/T hosted
  services where errors are serialized through the SDK message protocol
- detects resource exhaustion via EMFILE, ENFILE, ENOBUFS syscall errors
- introduces InvalidLinkDestinationError typed error in forwarder package
- adds unit tests covering all 16 classification cases
- adds integration tests for rejected-by-application (SDK host),
  DNS resolution failed, connection refused, and port not allowed
  (ER/T host mode) with circuit event verification
- adds CreateEnrollAndStartTunnelerEdgeRouterWithCfgTweaks to test context
2026-04-14 15:52:49 -04:00