Authdog

Billing service

Last updated Oct 7, 2026
View as Markdown

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.