* Refcount shared intercept hostnames so iptables rules are installed for every service. Fixes#3868
- modifies getDnsIp to invoke addrCB and register a cleanup action when the hostname already has an allocated IP, so each service sharing the hostname gets its per-service iptables rule installed
- adds a reference count on hostname allocations so the resolver entry is removed and the CGNAT IP recycled only when the last service using the hostname is cleaned up
- canonicalizes the refcount key by lowercasing so case variants of the same hostname share one allocation, matching the resolver's case-insensitive view
- adds tests covering shared-hostname rule installation, refcounted cleanup, out-of-order cleanup, and case-insensitive sharing
* Address review comments
* Refcount wildcard-allocated intercept hostnames. Fixes#3957
- moves hostname registration into allocateDnsIp, under the allocation mutex, so every allocation (fresh or reused) takes one reference through the refcounting resolver and closes the lookup/registration race between wildcard DNS queries and service updates
- removes the direct AddHostname call in getAddress, which bypassed the refcounting layer and let one service's cleanup remove a hostname still used by an overlapping wildcard or literal intercept
- documents the AddDomain callback contract: the callback registers the hostname mapping itself
- updates tests to match the production wiring and adds coverage for overlapping wildcard/literal intercepts in both removal orders
- adds a dns package test pinning the getAddress callback contract
- adds local ai tooling files to .gitignore
* backport openziti/ziti#3952 to v1.6 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
* backport openziti/ziti#3952 to v1.6 address pr review
- adds an explicit jwtToken.Valid check to ParseJwt in the router state
manager, mirroring the ParseApiSessionJwt/ParseServiceSessionJwt split on
main; invalid tokens are already rejected by jwt.ParseWithClaims, so this is
defense in depth that closes the SAST finding
- adds Test_Router_ParseJwt_TokenValidation, an apitests integration test that
boots a controller and edge router and drives the router's ParseJwt: accepts a
properly signed, unexpired access token and rejects tokens signed by an unknown
key or carrying an expired claim
- reads the meta-package nfpm arch field from NFPM_ARCH instead of TARGETARCH,
so the meta packages produce noarch RPMs and arch-independent (all) DEBs
- matches what the refreshed promote workflow expects for meta packages, so a
1.6.17 release can be promoted from the test repo to stable
- 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
- closes channel when token update contains an unparseable bearer token
- closes channel when token update fails JWT signature validation
- closes channel when token update fails to build an api session from token
- closes channel when token update fails to update the channel api session
- uses SendAndWaitForWire with timeouts for error replies
- fixes error replies that were constructed but never sent
- 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
- 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
- deletes proxyXgressConnection and transportXgressConn duplicate types
- adds ConnType enum (Tunnel, Transport, EdgeTransport, Proxy) to xgress_common
- replaces boolean isTransport parameter in NewXgressConn with ConnType
- updates HandleControlMsg to derive traceroute hop type from ConnType
- adds halfClose field to xgress_transport listener based on transport type
- updates all NewXgressConn call sites with appropriate ConnType values
Backport of #3642