# Is it possible to bind to service without host config and still have TLS?

**URL:** <https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172>\
**Category:** Uncategorized\
**Created:** [October 1, 2025, 12:32pm UTC](https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172 "2025-10-01T12:32:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![CarlosHleb](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/carloshleb/32/2187_2.png) [@CarlosHleb](https://openziti.discourse.group/u/CarlosHleb)\
**Post date:** [October 1, 2025, 12:32pm UTC](https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172/1 "2025-10-01T12:32:53Z")

</div>

Context:

1. a go app that binds to a service

2. intercept config for `myapi.ziti` on port 443

3. chrome browser that opens(host running a tunneler) `https://myapi.ziti`

The api part, without TLS works great, but it would be better for api to use TLS(get rid of chrome warning - this site is not secure).

Heres my code:

```auto
package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/openziti/sdk-golang/ziti"
	"github.com/openziti/sdk-golang/ziti/edge"
)

func main() {
	// load identity
	cfg, err := ziti.NewConfigFromFile("api-binder.json")
	if err != nil {
		panic(err)
	}
	ctx, err := ziti.NewContext(cfg)
	if err != nil {
		panic(err)
	}

	// listen on a Ziti service (instead of a TCP port)
	listener, err := ctx.Listen("api")
	if err != nil {
		panic(err)
	}
	defer listener.Close()

	// create Gin router
	r := gin.Default()
	r.GET("/", CheckAuth, func(c *gin.Context) {
		log.Print(c.Get("zitiIdentity"))
		log.Print(c.Get("AppData"))
		c.JSON(200, gin.H{"msg": "hello over ziti"})
	})
	r.POST("/echo", func(c *gin.Context) {
		body, _ := c.GetRawData()
		c.Data(200, "application/octet-stream", body)
	})

	srv := &http.Server{
		Handler: r,
		ConnContext: func(ctx context.Context, c net.Conn) context.Context {
			if edge, ok := c.(edge.Conn); ok {
				return context.WithValue(ctx, "zitiConn", edge)
			}
			return ctx
		},
	}

	fmt.Println("Gin HTTP server is running over Ziti service: my-http-service")
	if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
		panic(err)
	}
}

func CheckAuth(c *gin.Context) {
	val := c.Request.Context().Value("zitiConn")
	if val != nil {
		if edge, ok := val.(edge.Conn); ok {
			c.Set("zitiIdentity", edge.SourceIdentifier())
			c.Set("AppData", string(edge.GetAppData()))
		}
	}
	c.Next()
}

```

If i do

```auto
if err := srv.ServeTLS(listener, "server.crt", "server.key"); err != nil && err != http.ErrServerClosed {

```

I get errors in logs:

```auto
2025/10/01 15:02:17 http: TLS handshake error from ziti-edge-router connId=2147483648, logical=ziti-sdk[router=tls:ziti-edge-router:80]: remote error: tls: unknown certificate

```

Is it possible to still use `https` for an api when binding to service?

---

<div class="post-metadata">

**Author:** ![CarlosHleb](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/carloshleb/32/2187_2.png) [@CarlosHleb](https://openziti.discourse.group/u/CarlosHleb)\
**Post date:** [October 1, 2025, 5:07pm UTC](https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172/2 "2025-10-01T17:07:57Z")

</div>

> [@CarlosHleb](#):
>
> ```auto
> 2025/10/01 15:02:17 http: TLS handshake error from ziti-edge-router connId=2147483648, logical=ziti-sdk[router=tls:ziti-edge-router:80]: remote error: tls: unknown certificate
> 
> ```

I got it working(getting ziti data in middleware), but still get errors in logs:

```auto
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"
	"net"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/openziti/sdk-golang/ziti"
	"github.com/openziti/sdk-golang/ziti/edge"
)

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	// load identity
	cfg, err := ziti.NewConfigFromFile("api-binder.json")
	if err != nil {
		panic(err)
	}
	ctx, err := ziti.NewContext(cfg)
	if err != nil {
		panic(err)
	}

	// listen on a Ziti service (instead of a TCP port)
	listener, err := ctx.Listen("api")
	if err != nil {
		panic(err)
	}
	defer listener.Close()

	// create Gin router
	r := gin.Default()
	r.GET("/", CheckAuth, func(c *gin.Context) {
		log.Print(c.Get("zitiIdentity"))
		log.Print(c.Get("AppData"))
		c.JSON(200, gin.H{"msg": "hello over ziti"})
	})
	r.POST("/echo", func(c *gin.Context) {
		body, _ := c.GetRawData()
		c.Data(200, "application/octet-stream", body)
	})

	srv := &http.Server{
		Handler: r,
		ConnContext: func(ctx context.Context, c net.Conn) context.Context {
			// If TLS, unwrap it
			if tlsConn, ok := c.(*tls.Conn); ok {
				if underlying := tlsConn.NetConn(); underlying != nil {
					if edgeConn, ok := underlying.(edge.Conn); ok {
						return context.WithValue(ctx, "zitiConn", edgeConn)
					}
				}
			}

			// If it’s a direct Ziti connection (no TLS)
			if edgeConn, ok := c.(edge.Conn); ok {
				return context.WithValue(ctx, "zitiConn", edgeConn)
			}

			log.Print("connection was neither edge.Conn nor tls->edge.Conn")
			return ctx
		},
	}

	fmt.Println("Gin HTTP server is running over Ziti service: my-http-service")
	if err := srv.ServeTLS(listener, "server.crt", "server.key"); err != nil {
		panic(err)
	}
}

func CheckAuth(c *gin.Context) {
	val := c.Request.Context().Value("zitiConn")
	if val != nil {
		if edge, ok := val.(edge.Conn); ok {
			c.Set("zitiIdentity", edge.SourceIdentifier())
			c.Set("AppData", string(edge.GetAppData()))
		} else {
			log.Print("not okey")
		}
	}
	c.Next()
}

```

logs:

```auto
INFO[0000] new service session session token=f48603bd-af8f-4346-a32a-5946e10d4ec0
2025/10/01 18:47:01 server.go:3640: http: TLS handshake error from ziti-edge-router connId=2147483648, logical=ziti-sdk[router=tls:ziti-edge-router:80]: remote error: tls: unknown certificate
2025/10/01 18:47:01 server.go:3640: http: TLS handshake error from ziti-edge-router connId=2147483649, logical=ziti-sdk[router=tls:ziti-edge-router:80]: remote error: tls: unknown certificate
2025/10/01 18:47:01 main.go:39: admin1@gmail.comtrue
2025/10/01 18:47:01 main.go:40: {"connType":null,"dst_protocol":"tcp","dst_hostname":"myapi.ziti","dst_ip":"100.64.0.7","dst_port":"443","src_protocol":"tcp","src_ip":"100.64.0.1","src_port":"44278"}true
[GIN] 2025/10/01 - 18:47:01 | 200 | 144.125µs | | GET "/"

```

---

<div class="post-metadata">

**Author:** ![CarlosHleb](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/carloshleb/32/2187_2.png) [@CarlosHleb](https://openziti.discourse.group/u/CarlosHleb)\
**Post date:** [October 3, 2025, 12:41pm UTC](https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172/3 "2025-10-03T12:41:15Z")

</div>

More info on the TLS handshake errors, they only show up on the first request, any subsequent request dont have those warnings. And they show up only when called from chrome(if i curl from terminal they dont show up)

---

<div class="post-metadata">

**Author:** ![TheLumberjack](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/thelumberjack/32/113_2.png) [@TheLumberjack](https://openziti.discourse.group/u/TheLumberjack)\
**Post date:** [October 6, 2025, 11:45am UTC](https://openziti.discourse.group/t/is-it-possible-to-bind-to-service-without-host-config-and-still-have-tls/5172/4 "2025-10-06T11:45:30Z")

</div>

> [@CarlosHleb](#):
>
> Is it possible to still use `https` for an api when binding to service?

Yes it's certainly possible as you discovered. You just need to make a tls listener in some fashion (as you showed in your code)

As for a TLS handshake error, if you are presenting a correct certificate, you won't have that problem. Unfortunately, I don't believe this is an OpenZiti-related issue so it's kinda hard for us to help you. I think this is just a "regular ol tls-related" issue. OpenZiti won't impact that at all.

If you curl from the terminal and don't see the problem, that smells to me like the go library doesn't use the same ca store possibly, but unfortunattely this doesn't seem like an OpenZiti issue to me.
