Release 1.8.0
What's New
- controllers can now optionally bind APIs using a OpenZiti identity
ziti edge loginnow supports the--network-identityflag to authenticate and establish connections through the Ziti overlay networkziti edge loginnow supports using a bearer token with--tokenfor authentication. The token is expected to be
provided as just the JWT, not with the "Bearer " prefix- identity configuration can now be loaded from files or environment variables for flexible deployment scenarios
- OIDC/JWT Token-based Enrollment
- Clustering Performance Improvements
Binding Controller APIs With Identity
Controller APIs can now be bound to an OpenZiti overlay network identity, allowing secure communication through
the Ziti network. This is useful for scenarios where you want to expose controller APIs only through the overlay
network rather than on a standard network interface.
Configuration Structure
A standard bindPoint configuration looks like this:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
To bind controller APIs to an OpenZiti identity, add an additional identity block to your bindPoints. The
identity configuration specifies where to load the Ziti identity file and which service to bind it to:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
- identity:
file: "c:/temp/ctrl.testing/ctrl.identity.json"
service: "mgmt"
Supported Configuration Options
file: Path to a Ziti identity JSON file containing the controller's identity and enrollment certificateenv: Name of an environment variable containing a base64-encoded Ziti identity (alternative tofile)service: The name of the Ziti service to bind the controller API to
Using Environment Variables
For deployments where storing identity files on disk is not preferred, you can reference a base64-encoded
identity file from an environment variable. The environment variable should contain the base64-encoded contents
of the identity JSON file.
For example, if an environment variable named ZITI_CTRL_IDENTITY contains a base64-encoded identity file:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
- identity:
env: ZITI_CTRL_IDENTITY
service: "mgmt"
IPv6 Support
Both IPv4 and IPv6 addresses are supported for standard bind points. IPv6 addresses should be specified in bracket
notation with a port number:
bindPoints:
- interface: "[::1]:18441"
address: "[::1]:18441"
- identity:
file: "/path/to/identity.json"
service: "mgmt"
CLI Enhancements for Identity-Based Connections
The ziti edge login command and REST client utilities have been enhanced to support identity-based connections
through the Ziti overlay network.
New --network-identity Flag for ziti edge login
The ziti edge login command now includes a --network-identity flag that allows you to authenticate to a Ziti
controller through the overlay network using a Ziti identity:
ziti edge login https://ziti.mgmt.apis.local:1280 \
--username myuser \
--password mypass \
--network-identity /path/to/identity.jsonThis is useful when the controller is only accessible through the Ziti overlay network or when you want to ensure
all communication to the controller flows through the overlay for security purposes.
Identity Resolution Order
When establishing connections, identities are resolved in the following order:
- Command-line flag: The
--network-identityflag takes precedence - Environment variable: If
ZITI_CLI_NETWORK_IDis set and contains a base64-encoded identity, it is used - Cached identity file: If a network identity was saved from a previous login in the Ziti config directory, it may be used
This layered approach allows for flexibility in deployment scenarios:
- Development: Use command-line flags for quick testing
- Automation: Use environment variables in CI/CD pipelines
- Production: Cache identities securely for repeated access
Dialing Modes When Authenticating
The CLI supports two dialing modes:
Intercept-based Dialing (Default)
By default, URLs are expected to leverage intercepts. Create a service with an appropriate intercept config and use
the intercept address when dialing. This is the standard mode for most use cases. For example, given a service with
the intercept ziti.mgmt.apis.local
ziti edge login https://ziti.mgmt.apis.local:1280 \
--username myuser \
--password mypass \
--network-identity /path/to/identity.jsonIdentity-aware Dialing (Addressable Terminators)
To support addressable terminators-based dialing, specify a user in the URL. This activates dial-by-identity
functionality. The URL format should be identity-to-dial@service-name-to-dial. For example:
ziti edge login https://my-identity@my-service:1280 \
--username myuser \
--password mypass \
--network-identity /path/to/identity.jsonIn this mode, the transport extracts the identity from the URL and uses it to establish a direct connection to
the specified service via the addressable terminator.
Binding Controller APIs With Identity
It's now possible to bind controller APIs to an OpenZiti overlay network identity. To bind a given controller
API to an OpenZiti identity, add a section to the desired bindPoint section. For example a common bindPoint
configuration might look like:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
To bind any declared APIs to a given OpenZiti identity add an identity block:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
- identity:
file: "c:/temp/ctrl.testing/clint.ctrl.json"
service: "mgmt"
It's possible to refer to an environment variable for the identity file if desired. Add an environment variable with
the contents of the environment variable the identity file base64 encoded. For example if an environment is defined
with the name ZITI_ID_EXAMPLE and contains a base64 encoded identity file, the following bindPoint block can be used:
bindPoints:
- interface: 127.0.0.1:18441
address: 127.0.0.1:18441
- identity:
env: ZITI_ID_EXAMPLE
service: "mgmt"
OIDC/JWT Token-based Enrollment
OpenZiti now supports provisioning identities just-in-time through OIDC/JWT token enrollment. External identity
providers can be configured to allow identities to enroll using JWT tokens, with support for the resulting
identities to use certificate or token authentication.
External JWT Signer Configuration
External JWT signers are configured via the Edge Management API to define enrollment behavior with the following new
enrollment-specific properties:
-
enrollToCertEnabled - When enabled, identities can exchange a JWT token and a certificate signing request (CSR)
for a client certificate during enrollment. The certificate can then be used for standard certificate-based
authentication. -
enrollToTokenEnabled - When enabled, identities can use a JWT token to enroll. The current token or future tokens
may be used for authentication. -
enrollNameClaimsSelector - Specifies which JWT claim contains the identity name. Accepts a JSON pointer
(e.g.,/preferred_username) or a simple property name (e.g.,preferred_username, automatically converted to
/preferred_username). Defaults to/subif not specified. The extracted value becomes the identity name in Ziti. -
enrollAttributeClaimsSelector - Specifies which JWT claims to extract as identity attributes during enrollment.
Accepts a JSON pointer (e.g.,/roles) or a simple property name (e.g.,roles). Extracted attributes are
applied to the newly enrolled identity for use in authorization policies. -
enrollAuthPolicyId - Specifies the authentication policy to apply to newly enrolled identities. This determines
what authentication methods are available for the identity post-enrollment.
Additionally the existing property named claimsProperty that specifies external id to match identities to:
- now supports a JSON pointer (e.g.,
/id) or a simple property name (e.g.,id) - is used to populate the
externalIdfield of the identity
Enrollment Paths
Certificate Enrollment (enrollToCertEnabled)
When certificate enrollment is enabled, unauthenticated users can:
- Obtain a list of available IdPs from the public Edge Client API
GET /external-jwt-signersendpoint, where
enrollToCertEnabledis set totrue - Obtain a JWT from the configured OIDC provider
- Generate a certificate signing request (CSR)
- Submit an enrollment request with the JWT and CSR
- Have their identity created in Ziti with attributes extracted from JWT claims
- Receive a signed client certificate for certificate-based authentication
Token Enrollment (enrollToTokenEnabled)
When token enrollment is enabled, unauthenticated users can:
- Obtain a list of available IdPs from the public Edge Client API
GET /external-jwt-signersendpoint, where
enrollToTokenEnabledis set totrue - Obtain a JWT from the configured OIDC provider
- Submit an enrollment request with the JWT
- Have their identity created in Ziti with attributes extracted from JWT claims
- Receive a Ziti API token for token-based authentication
Edge Management API
The Edge Management API provides full CRUD operations for configuring external JWT signers:
POST /external-jwt-signers- Create a new external JWT signer with all configuration optionsGET /external-jwt-signers- List all configured external JWT signersGET /external-jwt-signers/{id}- Retrieve a specific signer configurationPUT /external-jwt-signers/{id}- Update all fields of a signerPATCH /external-jwt-signers/{id}- Partially update a signerDELETE /external-jwt-signers/{id}- Delete a signer
Edge Client API
The Edge Client API exposes a reduced set of external JWT signer information for unauthenticated enrollment requests:
GET /external-jwt-signers- List available JWT signers with enrollment capabilities
The client API response includes the following fields for each signer:
name- Signer nameexternalAuthUrl- URL where users obtain JWT tokensclientId- OIDC client IDscopes- Requested OIDC scopesopenIdConfigurationUrl- OIDC discovery endpointaudience- Expected token audiencetargetToken- Token type to use (ACCESS or ID)enrollToCertEnabled- Flag indicating certificate enrollment is availableenrollToTokenEnabled- Flag indicating token enrollment is available
CLI Commands
Create an external JWT signer with enrollment options:
ziti edge controller create ext-jwt-signer <name> <issuer> \
--jwks-endpoint <url> \
--audience <audience> \
--enroll-to-cert \
--enroll-to-token=false \
--enroll-name-claims-selector preferred_username \
--enroll-attr-claims-selector roles \
--enroll-auth-policy <policy-id-or-name>
Update enrollment options on an existing signer:
ziti edge controller update ext-jwt-signer <name|id> \
--enroll-to-cert \
--enroll-auth-policy <policy-id-or-name>
List external JWT signers:
ziti edge controller list ext-jwt-signers
Clustering Performance Improvements
In previous releases, model updates were submitted to raft one at at time. This prevented
raft from being efficient by allowing command batching. This release allows multiple
model updates to be in-flight at the same time.
New Configuration Options
- Raft Apply Timeout (raft.applyTimeout)
Location: Controller configuration file, under raft section
Type: Duration
Default: 5s
Description: Timeout for applying commands to the Raft distributed log. Commands that exceed this timeout will trigger adaptive rate limiter backoff.
Example:
raft:
applyTimeout: 10s
- Raft Rate Limiter Configuration (raft.rateLimiter)
A new adaptive rate limiter that controls the submission of commands to the Raft cluster. Unlike the existing command rate limiter, this specifically manages in-flight Raft operations with adaptive window sizing.
Configuration Structure:
raft:
rateLimiter:
enabled: true
minSize: 5
maxSize: 250
timeout: 30s
Sub-options:
- enabled (boolean)
- Default: true
- Description: Enable/disable adaptive rate limiting for Raft command submission
- minSize (integer)
- Default: 5
- Minimum: 1
- Description: Minimum window size for concurrent in-flight Raft operations
- maxSize (integer)
- Default: 250
- Description: Maximum window size for concurrent in-flight Raft operations. Must be >= minSize
- timeout (duration)
- Default: 30s
- Description: Time after which outstanding work is assumed to have failed if not marked completed
- Restart Self on Snapshot (raft.restartSelfOnSnapshot)
Location: Controller configuration file, under raft section
Type: Boolean
Default: false
Description: When true, the controller will automatically restart itself when restoring a snapshot to an initialized system. When false, the controller will exit with code 0, requiring external process management to restart it.
Example:
raft:
restartSelfOnSnapshot: true
New Metrics
The adaptive rate limiter exposes three new metrics:
- raft.rate_limiter.queue_size (gauge)
- Current number of operations queued/in-flight - raft.rate_limiter.work_timer (timer)
- Duration of rate-limited operations - raft.rate_limiter.window_size (gauge)
- Current adaptive window size
Component Updates and Bug Fixes
-
github.com/openziti/channel/v4: v4.2.41 -> v4.2.42
-
github.com/openziti/edge-api: v0.26.50 -> v0.26.51
-
github.com/openziti/foundation/v2: v2.0.79 -> v2.0.81
- Issue #464 - Add support for -pre in versions
-
github.com/openziti/identity: v1.0.118 -> v1.0.119
-
github.com/openziti/sdk-golang: v1.2.10 -> v1.3.0
- Issue #824 - release notes and hard errors on no TOTP handler breaks partial auth events
-
github.com/openziti/secretstream: v0.1.41 -> v0.1.42
-
github.com/openziti/storage: v0.4.31 -> v0.4.33
- Issue #122 - StringFuncNode has incorrect nil check, allowing panic
- Issue #120 - Change post tx commit constraint handling order
- Issue #119 - Add ContextDecorator API
-
github.com/openziti/transport/v2: v2.0.198 -> v2.0.199
-
github.com/openziti/xweb/v3: v2.3.4 -> v3.0.1
-
github.com/openziti/ziti: v1.7.0 -> v1.8.0
- Issue #3410 - Consolidate fabric REST API code with edge management and edge client code
- Issue #3425 - RDM not properly responding to tunneler enabled flag changes
- Issue #3420 - The terminator id cache uses the same id for all terminators in a host.v2 config, resulting in a single terminator
- Issue #3419 - When using the router data model, precedence specified on the per-service identity mapping are incorrectly interpreted
- Issue #3318 - Terminator creation seems to slow exponentially as the number of terminators rises from 10k to 20k to 40k
- Issue #3407 - The CLI doesn't properly pass JWT authentication information to websocket endpoints
- Issue #3359 - Ensure router data model subscriptions have reasonable performance and will scale
- Issue #3381 - the fabric service REST apis are missing the maxIdleTime property
- Issue #3382 - Legacy service sessions generated pre-1.7.x are incompatible with v1.7.+ and need to be cleared
- Issue #3339 - get router ctrl.endpoint from ctrls claim in JWT
- Issue #3378 - login with file stopped working
- Issue #3346 - Fix confusing attempt logging
- Issue #3337 - Router reports "no xgress edge forwarder for circuit"
- Issue #3345 - Clean up connect events tests and remove global XG registry
- Issue #3264 - Allow routers to generate alert events in cases of service misconfiguration