ZITI_IMAGE=openziti/quickstart
ZITI_VERSION=1.6.6
my go mod:
github.com/openziti/channel/v4 v4.2.21 // indirect
github.com/openziti/edge-api v0.26.47 // indirect
github.com/openziti/foundation/v2 v2.0.70 // indirect
github.com/openziti/identity v1.0.109 // indirect
github.com/openziti/metrics v1.4.2 // indirect
github.com/openziti/sdk-golang v1.2.3 // indirect
github.com/openziti/secretstream v0.1.38 // indirect
github.com/openziti/transport/v2 v2.0.183 // indirect
github.com/openziti/ziti v1.6.7 // indirect
My code:
package openziti
import (
"context"
"log"
"net"
"net/http"
"strings"
"time"
"github.com/gorilla/websocket"
"github.com/openziti/sdk-golang/ziti"
)
var ZitiContext ziti.Context
var ZitiContexts *ziti.CtxCollection
var ZitiTransport *http.Transport
var ZitiClient *http.Client
var ZitiCustomDialer CustomDialer
// CustomDialer wraps a ziti.Context
// Needed when can't use ziti transport(ex. nats)
type CustomDialer struct {
ZitiContext ziti.Context
}
func (cd CustomDialer) Dial(network, address string) (net.Conn, error) {
addr := strings.Split(address, ":")
return cd.ZitiContext.Dial(addr[0])
}
type FallbackDialer struct {
UnderlayDialer *net.Dialer
}
func (z FallbackDialer) Dial(network, address string) (net.Conn, error) {
return z.UnderlayDialer.Dial(network, address)
}
// Enrolls api identity if needed
// Creates openziti api session
// Creates a keepalive goroutine which pings openziti api every X minutes(default 10)
func SetupOpenziti(ctrlUrl string, zitiIDPath string) error {
err := EnrollIfNeeded(zitiIDPath)
if err != nil {
log.Print(err)
return err
}
log.Print(1111111)
err = CreateApiSession(ctrlUrl, zitiIDPath)
if err != nil {
log.Print(err)
return err
}
log.Print(22222)
err = InitCon(zitiIDPath)
if err != nil {
log.Print(err)
return err
}
log.Print(33333)
go KeepAlive(ctrlUrl)
return nil
}
func InitCon(zitiIDPath string) error {
log.Print(00000000000000)
err := SetupZitiContext(zitiIDPath)
if err != nil {
log.Print(err)
return err
}
log.Print(010101010)
err = SetupZitiTransport()
if err != nil {
log.Print(err)
return err
}
log.Print(90909090)
ZitiClient = &http.Client{
Transport: ZitiTransport,
Timeout: 30 * time.Second,
}
ZitiCustomDialer = CustomDialer{ZitiContext: ZitiContext}
// Set ziti transport for websocket
websocket.ZitiTransport = ZitiTransport
return nil
}
func SetupZitiContext(path string) (err error) {
identityFile := path + ".json"
log.Print(identityFile)
cfg, err := ziti.NewConfigFromFile(identityFile)
if err != nil {
log.Print(err)
return err
}
cfg.ConfigTypes = append(cfg.ConfigTypes, "all")
ZitiContext, err = ziti.NewContext(cfg)
if err != nil {
log.Print(err)
return err
}
log.Print("refresh services gliches?")
return ZitiContext.RefreshServices()
}
func SetupZitiTransport() error {
ZitiContexts = ziti.NewSdkCollection()
ZitiContexts.Add(ZitiContext)
fallback := &FallbackDialer{
UnderlayDialer: &net.Dialer{},
}
ZitiTransport = http.DefaultTransport.(*http.Transport).Clone() // copy default transport
ZitiTransport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := ZitiContexts.NewDialerWithFallback(ctx, fallback)
return dialer.Dial(network, addr)
}
ZitiTransport.Dial = func(network, addr string) (net.Conn, error) {
dialer := ZitiContexts.NewDialerWithFallback(context.Background(), fallback)
return dialer.Dial(network, addr)
}
return nil
}
After updating to newest ziti sdk, my code fails at return ZitiContext.RefreshServices()
also there is a new error of listing controllers. The identity used has admin rights.
Heres the error log:
api-server-1 | screen-control-lib/openziti/setup.go has changed
api-server-1 | building...
api-server-1 | running...
api-server-1 | 2025/08/14 08:22:31 setup.go:49: 1111111
api-server-1 | 2025/08/14 08:22:31 auth.go:100: Ziti session token: 320e65de-0ea4-43a3-be0c-22aaac4bd672
api-server-1 | 2025/08/14 08:22:31 setup.go:55: 22222
api-server-1 | 2025/08/14 08:22:31 setup.go:68: 0
api-server-1 | 2025/08/14 08:22:31 setup.go:96: /api-ziti/api.json
api-server-1 | 2025/08/14 08:22:32 setup.go:110: refresh services gliches?
api-server-1 | ERRO[0000] error listing controllers, continuing with 1 default configured controller error="[GET /controllers][401] listControllersUnauthorized &{Error:0xc0007d60c0 Meta:0xc000620100}"
api-server-1 | 2025/08/14 08:22:32 setup.go:71: failed to refresh services: no apiSession, authentication attempt failed: error for request Gg4jdbUKGL: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid, caused by: error for request : UNHANDLED: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid
api-server-1 | 2025/08/14 08:22:32 setup.go:58: failed to refresh services: no apiSession, authentication attempt failed: error for request Gg4jdbUKGL: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid, caused by: error for request : UNHANDLED: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid
api-server-1 | 2025/08/14 08:22:32 main.go:50: failed to refresh services: no apiSession, authentication attempt failed: error for request Gg4jdbUKGL: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid, caused by: error for request : UNHANDLED: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid
Heres policy-advisor for api identity:
ziti@71fb88f17ca8:/persistent$ ziti edge policy-advisor identities api
Policy General Guidelines
In order for an identity to dial or bind a service, the following must be true:
- The identity must have access to the service via a service policy of the correct type (dial or bind)
- The identity must have access to at least one on-line edge router via an edge router policy
- The service must have access to at least one on-line edge router via a service edge router policy
- There must be at least one on-line edge router that both the identity and service have access to.
Policy Advisor Output Guide:
STATUS = The status of the identity -> service reachability. Will be OKAY or ERROR.
ID = identity name
ID ROUTERS = number of routers accessible to the identity via edge router policies.
- See edge router polices for an identity: ziti edge controller list identity edge-router-policies <identity>
SVC = service name
SVC ROUTERS = number of routers accessible to the service via service edge router policies.
- See service edge router policies for a service with: ziti edge controller list service service-edge-router-policies <service>
ONLINE COMMON ROUTERS = number of routers the identity and service have in common which are online.
COMMON ROUTERS = number of routers (online or offline) the identity and service have in common.
DIAL_OK = indicates if the identity has permission to dial the service.
- See service polices for a service : ziti edge controller list service service-policies <service>
- See service polices for an identity: ziti edge controller list identity service-policies <identity>
BIND_OK = indicates if the identity has permission to bind the service.
ERROR_LIST = if the status is ERROR, error details will be listed on the following lines
Output format: STATUS: ID (ID ROUTERS) -> SVC (SVC ROUTERS) Common Routers: (ONLINE COMMON ROUTERS/COMMON ROUTERS) Dial: DIAL_OK Bind: BIND_OK. ERROR_LIST
-------------------------------------------------------------------------------
OKAY : api (1) -> nats.my.domain (1) Common Routers: (1/1) Dial: Y Bind: N
OKAY : api (1) -> livekit.my.domain (1) Common Routers: (1/1) Dial: Y Bind: N
ziti@71fb88f17ca8:/persistent$
and heres logs if i get rid of refresh services:
api-server-1 | ERRO[0092] error listing controllers, continuing with 1 default configured controller error="[GET /controllers][401] listControllersUnauthorized &{Error:0xc0007908a0 Meta:0xc0008719c0}"
api-server-1 | 2025/08/14 08:38:54 setup.go:110: refresh services gliches?2025/08/14 08:38:54 conn.go:40: Failed to connect to NATS: failed to dial: no apiSession, authentication attempt failed: error for request q-hy8b0KlL: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid, caused by: error for request : UNHANDLED: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid
api-server-1 | 2025/08/14 08:38:54 main.go:59: failed to dial: no apiSession, authentication attempt failed: error for request q-hy8b0KlL: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid, caused by: error for request : UNHANDLED: UNAUTHORIZED: The request could not be completed. The session is not authorized or the credentials are invalid