Skip to content
@go-signet

Signet

Signet is a self-hosted OAuth 2.0 and OpenID Connect authorization server written in Go — a lightweight, single-binary identity provider for enterprises and hom

Signet — OAuth 2.0 / OIDC Authorization Server

go-signet

Signet is a production-ready OAuth 2.0 / OIDC toolkit for Go — covering the Authorization Server, Go & Python SDKs for secure token storage and validation, and a Helm chart for Kubernetes. MCP-ready out of the box with Resource Indicators (RFC 8707) and AS Metadata (RFC 8414).

A signet ring stays with its owner — pressing it into wax produces a mark anyone can verify but nobody else can make. The ring is the private key you hold; the impression is the verifiable signature it stamps onto every token.

License


Supported OAuth 2.0 Flows

1. Authorization Code Flow + PKCE (RFC 6749 + RFC 7636)

Designed for web apps, SPAs, and mobile apps. PKCE replaces client secrets for public clients, preventing authorization code interception. Issues an id_token (OIDC) when the openid scope is granted.

sequenceDiagram
    participant App    as App (SPA / Mobile / CLI)
    participant Browser as Browser
    participant Server  as Signet Server

    App->>App: Generate code_verifier + code_challenge (S256)
    App->>Browser: Redirect to /oauth/authorize?code_challenge=...&state=...
    Browser->>Server: GET /oauth/authorize (Login + Consent page)
    Server-->>Browser: Render login / consent UI

    Browser->>Server: POST /oauth/authorize (user approves)
    Server->>Browser: 302 redirect_uri?code=XXXXX&state=...
    Browser->>App: Authorization code delivered to callback

    App->>App: Verify state parameter (CSRF check)
    App->>Server: POST /oauth/token (code + code_verifier + client_id)
    Server->>Server: Verify SHA256(code_verifier) == code_challenge
    Server-->>App: access_token + refresh_token + expires_in [+ id_token]
Loading

Security properties:

  • PKCE (RFC 7636) with S256 enforced — plain is rejected; prevents authorization code interception attacks
  • state parameter — CSRF protection on the callback
  • No client secret required for public clients (SPA, mobile, CLI)
  • Callback server binds to 127.0.0.1 only (CLI mode)

2. Device Authorization Grant (RFC 8628)

Designed for CLI tools, IoT devices, and headless environments where a browser is not available.

sequenceDiagram
    participant CLI    as CLI / Device
    participant Server as Signet Server
    participant User   as User (Browser on another device)

    CLI->>Server: POST /oauth/device/code (client_id + scope)
    Server-->>CLI: device_code + user_code + verification_uri + expires_in + interval

    Note over CLI: Display to user:<br/>"Visit verification_uri<br/>and enter user_code"

    User->>Server: GET /device (enter user_code)
    Server-->>User: Render code entry page (login required)
    User->>Server: POST /device/verify (user_code)
    Server-->>User: ✅ Authorization approved

    loop Poll every interval seconds (default 5 s)
        CLI->>Server: POST /oauth/token (device_code + grant_type)
        alt still waiting
            Server-->>CLI: error: authorization_pending
        else user approved
            Server-->>CLI: access_token + refresh_token + expires_in
        else slow down
            Server-->>CLI: error: slow_down (increase interval)
        else expired / denied
            Server-->>CLI: error: expired_token / access_denied
        end
    end
Loading

Polling behavior:

  • Respects server-specified interval (default 5 s)
  • Exponential backoff on slow_down response (up to 60 s, per RFC 8628)
  • Device codes expire after 30 minutes
  • Resource-bound device codes (RFC 8707) always route through an explicit confirmation screen before authorization

3. Client Credentials Grant (RFC 6749 Section 4.4)

Designed for microservices, daemons, and CI/CD pipelines — machine-to-machine authentication where no user is involved.

sequenceDiagram
    participant Service as Service / Daemon
    participant Server  as Signet Server
    participant API     as Protected API

    Service->>Server: POST /oauth/token (client_id + client_secret + grant_type=client_credentials)
    Server->>Server: Validate client credentials
    Server-->>Service: access_token + expires_in (no refresh_token)

    Service->>API: Request with Bearer access_token
    API->>Server: GET /oauth/tokeninfo (verify token)
    Server-->>API: Token valid + scopes
    API-->>Service: Protected resource
Loading

Key characteristics:

  • No user interaction — the client authenticates with its own credentials
  • Requires confidential clients (client_secret must be securely stored server-side)
  • No refresh tokens issued — the client requests a new token when the current one expires
  • Scoped access — tokens carry only the scopes assigned to the client (openid and offline_access are not permitted)

Use Cases

CLI Tools

One binary, two flows, zero configuration — mirrors the strategy used by GitHub CLI, Azure CLI, and Google Cloud SDK.

sequenceDiagram
    participant User   as User
    participant CLI    as CLI Tool
    participant Server as Signet Server

    User->>CLI: Launch CLI
    CLI->>CLI: Detect environment
    alt Developer Workstation (browser available)
        CLI->>Server: Auth Code + PKCE Flow
        Server-->>CLI: access_token + refresh_token
    else SSH / Headless (no display)
        CLI->>Server: Device Code Flow
        Server-->>CLI: access_token + refresh_token
    end
    CLI-->>User: Authenticated
Loading

Microservices & CI/CD

Service-to-service authentication — no user context needed, no browser involved.

sequenceDiagram
    participant CI     as CI/CD Pipeline
    participant Server as Signet Server
    participant Deploy as Deploy Service

    CI->>Server: POST /oauth/token (client_credentials)
    Server-->>CI: access_token
    CI->>Deploy: Trigger deploy with Bearer token
    Deploy->>Server: Verify token
    Server-->>Deploy: Valid (scopes: deploy:trigger)
    Deploy-->>CI: Deployment started
Loading

MCP & Multi-Resource APIs

A single Signet server fronts multiple resource servers; each token's audience is bound at issuance and cannot be replayed elsewhere.

sequenceDiagram
    participant Client as MCP Client
    participant Server as Signet Server
    participant RS_A   as api-a.corp
    participant RS_B   as api-b.corp

    Client->>Server: GET /.well-known/oauth-authorization-server
    Server-->>Client: AS metadata (RFC 8414)
    Client->>Server: POST /oauth/token (resource=https://api-a.corp)
    Server-->>Client: access_token (aud bound to api-a.corp)
    Client->>RS_A: Bearer token (aud matches) ✅
    Client->>RS_B: Bearer token (aud mismatch) ❌ rejected
Loading

Hardening: Every bearer token carries a type claim, so a refresh token can never be accepted as an access token. Resource-bound device codes require explicit user confirmation of the client and target resource.


IoT & Smart Devices

No keyboard, no embedded secret — the user authorizes from any nearby device.

sequenceDiagram
    participant TV    as Smart TV / IoT
    participant Server as Signet Server
    participant Phone as User (Phone / Laptop)

    TV->>Server: POST /oauth/device/code
    Server-->>TV: user_code + verification_uri

    Note over TV: Display short URL + user_code<br/>(or QR code)

    Phone->>Server: Visit URL, enter user_code
    Server-->>Phone: ✅ Approved

    TV->>Server: Poll /oauth/token
    Server-->>TV: access_token + refresh_token
Loading

Web Applications (Confidential Client)

Server-side backend holds the client secret; it is never exposed to the browser.

sequenceDiagram
    participant User   as User (Browser)
    participant App    as Backend Server
    participant Server as Signet Server

    User->>App: ① Visit app
    App->>User: ② Redirect to /oauth/authorize
    User->>Server: ③ Login + Consent
    Server->>User: ④ 302 redirect_uri?code=XXXXX
    User->>App: ⑤ code delivered to callback
    App->>Server: ⑥ POST /oauth/token (code + client_secret)
    Server-->>App: access_token + refresh_token [+ id_token]
Loading

Single-Page Apps & Mobile (Public Client + PKCE)

No client secret on device — PKCE binds the token exchange to the original requestor.

sequenceDiagram
    participant App     as SPA / Mobile App
    participant Browser as Browser
    participant Server  as Signet Server

    App->>App: Generate code_verifier + code_challenge (S256)
    App->>Browser: Redirect to /oauth/authorize?code_challenge=...&method=S256
    Browser->>Server: Login + Consent
    Server->>Browser: 302 redirect_uri?code=XXXXX&state=...
    Browser->>App: code delivered to callback
    App->>App: Verify state (CSRF check)
    App->>Server: POST /oauth/token (code + code_verifier)
    Server->>Server: Verify SHA256(code_verifier) == code_challenge
    Server-->>App: access_token + refresh_token [+ id_token]
Loading

Which Flow Should I Use?

Scenario Recommended Flow
CLI tools, IoT devices, TV apps Device Code Flow (RFC 8628)
Web apps with a server-side backend Authorization Code Flow (confidential client)
Single-page apps (SPA), mobile apps Authorization Code Flow + PKCE (public client)
Microservices, daemons, CI/CD pipelines Client Credentials Grant (RFC 6749 §4.4)
MCP servers, multi-resource APIs Any grant + resource parameter (RFC 8707)

Brand

The Signet identity — a signet ring with an octagonal bezel and a carved "S" — lives in the brand repository, with logos, marks, favicons, the color palette, and usage rules. Browse the interactive guidelines at go-signet.github.io/brand.


References

Popular repositories Loading

  1. sdk-go sdk-go Public

    Signet SDK for Go — OAuth 2.0 device/PKCE flows, JWKS-based JWT verification, and secure credential storage with OS keyring integration

    Go 2

  2. examples examples Public

    Multi-language usage examples for Signet authentication (Go, Python, Bash) — OAuth flows: Auth Code+PKCE, Device Code, Client Credentials, JWKS validation

    Go 1

  3. kong-mcp-oauth2 kong-mcp-oauth2 Public

    MCP OAuth2 plugin secures Model Context Protocol (MCP) traffic on AI Gateway using OAuth 2.0 specification for MCP servers

    Go

  4. brand brand Public

    Official brand assets for Signet — logos, marks, favicons, and palette for the self-hosted OAuth 2.0 / OIDC authorization server

    HTML

  5. .github .github Public

    Signet organization profile — production-ready OAuth 2.0 / OIDC toolkit for Go: authorization server, Go & Python SDKs, and Helm chart. MCP-ready.

  6. sdk-python sdk-python Public

    Python SDK for Signet — OAuth 2.0 authentication and token management

    Python

Repositories

Showing 6 of 6 repositories

People

This organization has no public members. You must be a member to see who’s a part of this organization.

Top languages

Loading…

Most used topics

Loading…