The billing service returns invoices on GET /invoices. Gin returns 401 unless Authdog authenticates the caller.
Clone starters/go. SDK reference: Go.
AttachSession records context and never fails a request on its own. RequireAuth on GET /invoices is the identity gate. A signed-in session is not a permission grant. Apply authorization after RequireAuth.
What you need
| Requirement | Detail |
|---|---|
| Public key | pk_... from the console |
| Environment | Copy .env.example to .env and export PK_AUTHDOG |
| Secret key | Never put sk_... in the service |
| Package | No tagged versions. go.mod in the sample pins a commit. Do not use @latest for a reproducible build. Go 1.25+. Gin is the ready adapter. net/http, chi, and Echo compose the core functions themselves |
| Request | Hosted sign-in stays in a browser. Call /invoices with the authdog-session cookie or Authorization: Bearer |
Run
go mod download
export PK_AUTHDOG=pk_...
go run .Open http://localhost:3000. curl -i http://localhost:3000/invoices with no session returns 401. With a valid session the body includes inv_90 (Northwind, open) and inv_91 (Contoso, paid). GET /logout expires the local cookie and redirects. It does not revoke a bearer token.
Invoices
// main.go
ad, err := authdog.New(authdog.Config{PublicKey: publicKey})
if err != nil {
log.Fatal(err)
}
r := gin.Default()
r.Use(ad.AttachSession())
r.GET("/invoices", ad.RequireAuth(), func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"caller": authdog.FromGin(c).User,
"invoices": []gin.H{
{"id": "inv_90", "customer": "Northwind", "total": 1280, "status": "open"},
{"id": "inv_91", "customer": "Contoso", "total": 640, "status": "paid"},
},
})
})FetchUser: false makes RequireAuth reject every caller. This example does not set that option.