User Request
Replace static identity file provisioning with runtime self-enrollment. The Gateway should call ziti-management.RequestServiceIdentity() at startup to obtain an enrolled OpenZiti identity, and periodically extend the lease via ExtendIdentityLease().
See Service Identity Self-Enrollment.
Specification
Current Behavior
The Gateway reads a pre-provisioned identity file from ZITI_IDENTITY_FILE env var and calls ziti.NewContextFromFile().
Target Behavior
-
At startup, if OpenZiti is enabled (determined by a config flag — see below), the Gateway:
a. Creates a gRPC client to ziti-management (already exists: zitimgmtclient.Client).
b. Calls RequestServiceIdentity(service_type: SERVICE_TYPE_GATEWAY).
c. Receives ziti_identity_id + identity_json (bytes).
d. Writes identity_json to a temp file on ephemeral disk (e.g., os.CreateTemp("", "ziti-identity-*.json")).
e. Loads the identity via ziti.NewContextFromFile(tempFile).
f. Proceeds as before: ListenWithOptions("gateway", ...).
-
Lease renewal: starts a background goroutine that calls ExtendIdentityLease(ziti_identity_id) every ZITI_LEASE_RENEWAL_INTERVAL (default: 2 minutes — well under the 5-minute lease TTL). On error, log and retry on next tick. On context cancellation, stop.
-
Shutdown: temp file is cleaned up via defer os.Remove(tempFile).
Config Changes
Replace ZITI_IDENTITY_FILE with a boolean-like enablement. The identity file is no longer externally provided — it's obtained at runtime.
| Env Var |
Default |
Description |
ZITI_ENABLED |
false |
Enable OpenZiti self-enrollment |
ZITI_MANAGEMENT_GRPC_TARGET |
ziti-management:50051 |
Already exists |
ZITI_LEASE_RENEWAL_INTERVAL |
2m |
How often to extend the lease |
ZITI_SERVICE_NAME |
gateway |
Already exists |
Remove ZITI_IDENTITY_FILE from the config — it's no longer used.
Changes to zitimgmtclient
The existing zitimgmtclient.Client only has ResolveIdentity. Add:
RequestServiceIdentity(ctx, serviceType) (zitiIdentityID string, identityJSON []byte, error)
ExtendIdentityLease(ctx, zitiIdentityID string) error
This requires regenerating the proto stubs from the updated BSR (which now includes the new RPCs).
Changes to main.go
The OpenZiti setup block (currently gated on config.ZitiIdentityFile != "") should be replaced with a self-enrollment flow gated on config.ZitiEnabled:
if config.ZitiEnabled {
// 1. Request identity from ziti-management
zitiIdentityID, identityJSON, err := zitiMgmtClient.RequestServiceIdentity(ctx, SERVICE_TYPE_GATEWAY)
// 2. Write to temp file
tmpFile, err := os.CreateTemp("", "ziti-identity-*.json")
tmpFile.Write(identityJSON)
tmpFile.Close()
defer os.Remove(tmpFile.Name())
// 3. Load identity
zitiContext, err := ziti.NewContextFromFile(tmpFile.Name())
defer zitiContext.Close()
// 4. Start lease renewal
go renewLease(ctx, zitiMgmtClient, zitiIdentityID, leaseRenewalInterval)
// 5. Listen (same as before)
listener, err := zitiContext.ListenWithOptions(serviceName, ziti.DefaultListenOptions())
go server.Serve(listener)
}
Proto Stub Regeneration
The Gateway needs to pull the updated proto from BSR to get the new RequestServiceIdentity and ExtendIdentityLease RPCs. Run buf dep update + buf generate to regenerate stubs.
Lease Renewal Function
func renewLease(ctx context.Context, client *zitimgmtclient.Client, identityID string, interval time.Duration) {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if err := client.ExtendIdentityLease(ctx, identityID); err != nil {
log.Printf("failed to extend ziti lease: %v", err)
}
}
}
}
User Request
Replace static identity file provisioning with runtime self-enrollment. The Gateway should call
ziti-management.RequestServiceIdentity()at startup to obtain an enrolled OpenZiti identity, and periodically extend the lease viaExtendIdentityLease().See Service Identity Self-Enrollment.
Specification
Current Behavior
The Gateway reads a pre-provisioned identity file from
ZITI_IDENTITY_FILEenv var and callsziti.NewContextFromFile().Target Behavior
At startup, if OpenZiti is enabled (determined by a config flag — see below), the Gateway:
a. Creates a gRPC client to ziti-management (already exists:
zitimgmtclient.Client).b. Calls
RequestServiceIdentity(service_type: SERVICE_TYPE_GATEWAY).c. Receives
ziti_identity_id+identity_json(bytes).d. Writes
identity_jsonto a temp file on ephemeral disk (e.g.,os.CreateTemp("", "ziti-identity-*.json")).e. Loads the identity via
ziti.NewContextFromFile(tempFile).f. Proceeds as before:
ListenWithOptions("gateway", ...).Lease renewal: starts a background goroutine that calls
ExtendIdentityLease(ziti_identity_id)everyZITI_LEASE_RENEWAL_INTERVAL(default: 2 minutes — well under the 5-minute lease TTL). On error, log and retry on next tick. On context cancellation, stop.Shutdown: temp file is cleaned up via
defer os.Remove(tempFile).Config Changes
Replace
ZITI_IDENTITY_FILEwith a boolean-like enablement. The identity file is no longer externally provided — it's obtained at runtime.ZITI_ENABLEDfalseZITI_MANAGEMENT_GRPC_TARGETziti-management:50051ZITI_LEASE_RENEWAL_INTERVAL2mZITI_SERVICE_NAMEgatewayRemove
ZITI_IDENTITY_FILEfrom the config — it's no longer used.Changes to
zitimgmtclientThe existing
zitimgmtclient.Clientonly hasResolveIdentity. Add:RequestServiceIdentity(ctx, serviceType) (zitiIdentityID string, identityJSON []byte, error)ExtendIdentityLease(ctx, zitiIdentityID string) errorThis requires regenerating the proto stubs from the updated BSR (which now includes the new RPCs).
Changes to
main.goThe OpenZiti setup block (currently gated on
config.ZitiIdentityFile != "") should be replaced with a self-enrollment flow gated onconfig.ZitiEnabled:Proto Stub Regeneration
The Gateway needs to pull the updated proto from BSR to get the new
RequestServiceIdentityandExtendIdentityLeaseRPCs. Runbuf dep update+buf generateto regenerate stubs.Lease Renewal Function