Go SDK attempts OIDC when cert identity is provided

Hey guys!

Been testing out the Go SDK (I need the ziti identity from connections, Go seems to be the only SDK where that is possible or am I wrong?) and I've been having trouble getting the examples working.

I cloned the repo and tried this example following the instructions and when I try running it I get:

./simple-server simple-server-3.json simpleService
Using the provided service name [simpleService]listening for non-ziti requests on localhost:8080
Error binding service failed to listen: no apiSession, authentication attempt failed: failed to initiate authorization flow: authentication request start failed with status 404, either a misconfigured request was sent or the expected redirect URL (http://localhost:8080/auth/callback) is not allowed: {"error":{"cause":{"code":"UNHANDLED","message":"path /edge/client/v1/oidc/authorize was not found"},"code":"NOT_FOUND","message":"The resource requested was not found or is no longer available","requestId":"6hnH2xhlds"},"meta":{"apiEnrollmentVersion":"0.0.1","apiVersion":"0.0.1"}}

panic: failed to listen: no apiSession, authentication attempt failed: failed to initiate authorization flow: authentication request start failed with status 404, either a misconfigured request was sent or the expected redirect URL (http://localhost:8080/auth/callback) is not allowed: {"error":{"cause":{"code":"UNHANDLED","message":"path /edge/client/v1/oidc/authorize was not found"},"code":"NOT_FOUND","message":"The resource requested was not found or is no longer available","requestId":"6hnH2xhlds"},"meta":{"apiEnrollmentVersion":"0.0.1","apiVersion":"0.0.1"}}


goroutine 4 [running]:
main.zitifiedServer()
        /mnt/c/dev/sdk-golang/example/simple-server/simple-server.go:91 +0x31a
created by main.main in goroutine 1
        /mnt/c/dev/sdk-golang/example/simple-server/simple-server.go:105 +0xd2

The identity should be ok, it works with my Nodejs ziti application. Any ideas?

Thanks!

Controller: v1.6.9
go version go1.25.0 linux/amd64

Hi @montwepa,

I gave that example a try and it worked for me so I figured I'll detail what I did here so you can try to replicate... I did find a few small quoting issues with the readme so i'll post the fixed version below as well.

Steps to reproduce

  • i downloaded the 1.6.9 ziti binary from github releases
  • i used ziti edge quickstart to start my instance
  • ensured i had the main branch of the golang-sdk project checked out
  • cd to example
  • built all the examples using mkdir build; go build -o build ./...
  • ran the updated ziti CLI commands (below)
  • cd to the
  • started the server using: .\build\simple-server.exe .\identities\simple-server.json simpleService (i used powershell so change the slashes if using linux/mac)
  • enrolled the client: ziti edge enroll --jwt .\identities\simple-client.jwt
  • ran the client: .\build\curlz.exe http://simpleService .\identities\simple-client.json
  • received the output from the server at the client: Who are you?
  • provided the query param: .\build\curlz.exe http://simpleService?name=testing .\identities\simple-client.json and received Hello, testing, from ziti

Updated ziti CLI commands to create the necessary services/identities etc

mkdir <repo-root-dir>/example/identities
cd <repo-root-dir>/example/identities

echo 'Create the service configs'
ziti edge create config simple.hostv1 host.v1 '{"protocol":"tcp", "address":"localhost","port":8080}'
ziti edge create config simple.interceptv1 intercept.v1 '{"protocols":["tcp"],"addresses":["simpleService.ziti"], "portRanges":[{"low":8080, "high":8080}]}'

echo 'Create the service'
ziti edge create service simpleService --configs "simple.hostv1,simple.interceptv1" --role-attributes simple-service
   
echo 'Create two identities and enroll the server'
ziti edge create identity user simple-client -a simpleserver.clients -o simple-client.jwt
ziti edge create identity device simple-server -a simpleserver.servers -o simple-server.jwt
ziti edge enroll --jwt simple-server.jwt
   
echo 'Create service policies'
ziti edge create service-policy simple-client-dial Dial --identity-roles '#simpleserver.clients' --service-roles '#simple-service'
ziti edge create service-policy simple-client-bind Bind --identity-roles '#simpleserver.servers' --service-roles '#simple-service'
   
echo Run policy advisor to check
ziti edge policy-advisor services

hope that helps. I'm not sure where or how you went wrong. Maybe your controller is not configured in a way that's conducive to this version of ziti. Can you enumerate the apis that are bound? Go to /version and post back the json like mine here:

curl -sk https://localhost:1280/version
{"data":{"apiVersions":{"edge":{"v1":{"apiBaseUrls":["https://sg4:1280/edge/client/v1"],"path":"/edge/client/v1"}},"edge-client":{"v1":{"apiBaseUrls":["https://sg4:1280/edge/client/v1"],"path":"/edge/client/v1"}},"edge-management":{"v1":{"apiBaseUrls":["https://sg4:1280/edge/management/v1"],"path":"/edge/management/v1"}},"edge-oidc":{"v1":{"apiBaseUrls":["https://sg4:1280"],"path":"/oidc"}},"health-checks":{"v1":{"apiBaseUrls":[],"path":"/health-checks/v1"}}},"buildDate":"2025-09-23T20:13:54Z","capabilities":["OIDC_AUTH"],"revision":"61ce69026623","runtimeVersion":"go1.24.1","version":"v1.6.9"},"meta":{}}

Maybe your controller doesn't have OIDC_AUTH? I'd like to confirm that's the case. It'd tell me there some kinda bug in the go sdk I'd think...

Hey!

We do have OIDC_AUTH enabled, here are the API's we have bound from /edge/client/v1 or version (not sure what the difference is between those two?)

Since we do have OIDC_AUTH enabled I figure it's a bug? Haven't experienced this behaviour with the other SDK's. I take it the Go SDK prefers OIDC_AUTH even when cert creds are present?

{
  "data": {
    "apiVersions": {
      "edge": {
        "v1": {
          "apiBaseUrls": [
            "https://ctrl.xx.com:443/edge/client/v1",
            "https://ctrl.xx.com:8444/edge/client/v1"
          ],
          "path": "/edge/client/v1"
        }
      },
      "edge-client": {
        "v1": {
          "apiBaseUrls": [
            "https://ctrl.xx.com:443/edge/client/v1",
            "https://ctrl.xx.com:8444/edge/client/v1"
          ],
          "path": "/edge/client/v1"
        }
      },
      "edge-management": {
        "v1": {
          "apiBaseUrls": [
            "https://ctrl.xx.com:443/edge/management/v1",
            "https://ctrl.xx.com:8444/edge/management/v1",
            "https://ctrl.xx.com:18441/edge/management/v1"
          ],
          "path": "/edge/management/v1"
        }
      },
      "edge-oidc": {
        "v1": {
          "apiBaseUrls": [
            "https://ctrl.xx.com:8444"
          ],
          "path": "/oidc"
        }
      },
      "health-checks": {
        "v1": {
          "apiBaseUrls": [
            "https://ctrl.xx.com:443"
          ],
          "path": "/health-checks/v1"
        }
      }
    },
    "buildDate": "2025-09-23T20:13:26Z",
    "capabilities": [
      "OIDC_AUTH"
    ],
    "revision": "61ce69026623",
    "runtimeVersion": "go1.24.1",
    "version": "v1.6.9"
  },
  "meta": {

  }
}

And from edge/client/v1/oidc/authorize

{
  "error": {
    "cause": {
      "code": "UNHANDLED",
      "message": "path /edge/client/v1/oidc/authorize was not found"
    },
    "code": "NOT_FOUND",
    "message": "The resource requested was not found or is no longer available",
    "requestId": "jHeqi6kxf"
  },
  "meta": {
    "apiEnrollmentVersion": "0.0.1",
    "apiVersion": "0.0.1"
  }
}

I'll give the updated CLI commands a try, I created policies and services with ZAC but they should have been correct - I'll update if that was the issue. Thanks for updating them!

Tried with the updated ziti CLI commands, still got the same error:

./simple-server simple-server.json simpleService
Using the provided service name [simpleService]listening for non-ziti requests on localhost:8080
Error binding service failed to listen: no apiSession, authentication attempt failed: failed to initiate authorization flow: authentication request start failed with status 404, either a misconfigured request was sent or the expected redirect URL (http://localhost:8080/auth/callback) is not allowed: {"error":{"cause":{"code":"UNHANDLED","message":"path /edge/client/v1/oidc/authorize was not found"},"code":"NOT_FOUND","message":"The resource requested was not found or is no longer available","requestId":"MPcM06klds"},"meta":{"apiEnrollmentVersion":"0.0.1","apiVersion":"0.0.1"}}     

panic: failed to listen: no apiSession, authentication attempt failed: failed to initiate authorization flow: authentication request start failed with status 404, either a misconfigured request was sent or the expected redirect URL (http://localhost:8080/auth/callback) is not allowed: {"error":{"cause":{"code":"UNHANDLED","message":"path /edge/client/v1/oidc/authorize was not found"},"code":"NOT_FOUND","message":"The resource requested was not found or is no longer available","requestId":"MPcM06klds"},"meta":{"apiEnrollmentVersion":"0.0.1","apiVersion":"0.0.1"}}


goroutine 22 [running]:
main.zitifiedServer()
        /mnt/c/dev/sdk-golang/example/simple-server/simple-server.go:91 +0x31a
created by main.main in goroutine 1
        /mnt/c/dev/sdk-golang/example/simple-server/simple-server.go:105 +0xd2

Best idea I have that for some reason the Go SDK is trying to use the OIDC_AUTH because it's being advertised?

I was able to get it to work by making a few changes to the code:

import (
	"fmt"
	"net"
	"net/http"
	"os"
	"time"

	"github.com/michaelquigley/pfxlog"
	edge_apis "github.com/openziti/sdk-golang/edge-apis"
	"github.com/openziti/sdk-golang/ziti"
	"github.com/sirupsen/logrus"
)

and in func zitifiedServer() after ctx, err := ziti.NewContext(cfg)

	if impl, ok := ctx.(*ziti.ContextImpl); ok {
        if api, ok := any(impl.CtrlClt).(edge_apis.OidcEnabledApi); ok {
            api.SetUseOidc(false)
            api.SetAllowOidcDynamicallyEnabled(false)
        }
    }

it started to work:

./simple-server simple-server.json simpleService
listening for non-ziti requests on localhost:8080
Using the provided service name [simpleService]listening for requests for Ziti service simpleService
        Saying hello to tester, coming in from plain-internet

So the failure was due to the SDK choosing OIDC

I got the same error also for curlz but I bet it would probably work if I updated the code:

 ./curlz http://simpleService ./simple-client.json
panic: Get "http://simpleService": failed to dial:......```

I might have an idea here, have you by chance "split" the apis? I noticed an additional port here:

          "apiBaseUrls": [
            "https://ctrl.xx.com:443/edge/management/v1",
            "https://ctrl.xx.com:8444/edge/management/v1",
            "https://ctrl.xx.com:18441/edge/management/v1"
          ],

this is making me think you have multiple bindings going on. Is it possible the OIDC binding is NOT exposed publicly? That would be consistent with your experiences here.

When splitting the management and client apis, the "client" and "oidc" apis must remain public. I expect you have an oidc binding and it's not availalbe to the sdk client in this case.

By public I take it you mean available to the wider internet? 18441 is Ziti admin, restricted to only few users. 8444 allows allows external access to Ziti management API and is just for developers. Tried making the ports public also but that didn't help.

We have a Keycloak setup that is working so I think we should've noticed any problems with OIDC there (?) also haven't faced this issue with the other SDK's (Python, Node, Java).

Figured out what the problem was. Port 443 didn't expose the edge-oidc API, only port 8444. After I added - binding: edge-oidc to port 443 it started to work.

Thanks for the help!

Yes exactly, that's what I was trying to imply. The public clients need to have access to both the "edge-client" as well as the "edge-oidc" apis. Glad you got it sorted

1 Like