---
title: "sdk/go"
description: "Go server SDK for networkless JWT verification, request authentication, and webhook signature validation."
locale: "en"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/en/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/go

## Status

Implemented and verified locally. Real IdP round-trip verification (JWKS fetch, token sign/verify against a live XID instance) has not been performed yet and must be completed before production use.

## Install

```shell
go get github.com/StringKe/xid/sdk/go
```

## Quick start

Create one `Client` at application startup and reuse it across requests. The client caches JWKS internally with a configurable TTL.

```go
import "github.com/StringKe/xid/sdk/go/xid"

client, err := xid.NewClient(xid.ClientOptions{
Issuer:        "https://xid.dev",
Audience:      "your-client-id",
WebhookSecret: "whs_...",
})
if err != nil {
log.Fatal(err)
}

// HTTP middleware (recommended)
http.Handle("/api/", client.Middleware(apiHandler, func(w http.ResponseWriter, r *http.Request) {
http.Error(w, `{"error":"unauthorized"}`, http.StatusUnauthorized)
}))

// Inside a protected handler
func apiHandler(w http.ResponseWriter, r *http.Request) {
claims := xid.ClaimsFromContext(r.Context())
fmt.Fprintf(w, "hello %s", claims.Subject)
}
```

## Verify token directly

```go
claims, err := client.VerifyAccessToken(ctx, tokenString)
if err != nil {
// handle verification failure
}
fmt.Println(claims.Subject, claims.OrgID)
```

## Verify webhook

```go
func webhookHandler(w http.ResponseWriter, r *http.Request) {
event, err := client.VerifyWebhook(r)
if err != nil {
    http.Error(w, "invalid signature", http.StatusBadRequest)
    return
}
// event.Body: raw JSON body
// event.ID:   svix-id for idempotency
w.WriteHeader(http.StatusNoContent)
}
```

## Core API

| Symbol | Description |
| --- | --- |
| `NewClient(opts)` | Construct the client. `Issuer` is required; other fields are optional. |
| `(*Client).VerifyAccessToken(ctx, token)` | Verify a JWT string, return `*Claims` or error. |
| `(*Client).AuthenticateRequest(ctx, r)` | Extract and verify token from an HTTP request. Always returns `AuthState`, does not panic. |
| `(*Client).Middleware(next, onUnauthorized)` | Standard `net/http` middleware. Injects `*Claims` into context on success. |
| `ClaimsFromContext(ctx)` | Extract claims injected by Middleware. |
| `(*Client).VerifyWebhook(r)` | Verify webhook request signature. Returns `*WebhookEvent` with raw body on success. |

## ClientOptions

| Field | Default | Description |
| --- | --- | --- |
| `Issuer` | required | XID issuer URL |
| `Audience` | empty (skip) | Expected JWT aud claim |
| `WebhookSecret` | empty | Webhook HMAC signing secret |
| `JWKSCacheTTL` | `1h` | JWKS local cache TTL |
| `HTTPClient` | 10s timeout default | HTTP client for JWKS fetch |

## Platform notes

- ES256 is the primary algorithm; RS256 is supported for compatibility. ES384 and ES512 are not yet implemented.
- JWKS is fetched from `{issuer}/jwks`. OIDC Discovery auto-detection is a planned improvement.
- `Claims` embeds `jwt.RegisteredClaims` and adds `ClientID`, `Scope`, `AMR`, `ACR`, `OrgID`, `OrgSlug`.

Source: https://xid.dev/sdks/go/index.mdx
