Authentication Package
OAuth 2.0 authentication providers for gRPC connections in Chainlink Canton. Supports Authorization Code Flow (
interactive user login) and Client Credentials Flow (machine-to-machine).
Quick Start
Client Credentials
For server-to-server authentication:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/clientcredentials"
provider, err := clientcredentials.NewDiscoveryProvider(
ctx,
"https://auth.example.com",
"client-id",
"client-secret",
)
Authorization Code (Interactive Login)
For user login flows:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/authorizationcode"
provider, err := authorizationcode.NewDiscoveryProvider(
ctx,
"https://auth.example.com",
"client-id",
)
Authorization Code Flow
For interactive user authentication via browser login. Requires OAuth server to support PKCE with S256 challenge
method. Automatically handles state validation to prevent CSRF attacks. By default, automatically opens the
authorization URL in your browser.
Automatically discovers authorization and token endpoints via RFC 8414:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/authorizationcode"
provider, err := authorizationcode.NewDiscoveryProvider(
ctx,
"https://auth.example.com",
"client-id",
authorizationcode.WithScopes("daml_ledger_api", "offline_access"),
authorizationcode.WithOpenBrowser(false), // Disables automatically opening the login URL in the default browser
)
Direct Configuration
If metadata discovery is unavailable:
provider, err := authorizationcode.NewProvider(
ctx,
"https://auth.example.com/oauth/authorize",
"https://auth.example.com/oauth/token",
"client-id",
)
Additional options are available via the functional options pattern (see package documentation for WithScopes,
WithCallbackURL, WithOpenBrowser, etc).
Token Persistence (Keyring)
CLIs can persist tokens in the operating system's native keyring (macOS Keychain, Windows Credential Manager, or the
Secret Service on Linux) so users don't have to log in again for every invocation:
provider, err := authorizationcode.NewDiscoveryProvider(
ctx,
"https://auth.example.com",
"client-id",
authorizationcode.WithScopes("daml_ledger_api", "offline_access"),
authorizationcode.WithKeyring(true),
)
When enabled, the provider first checks the keyring for a token from a previous login. If a usable token is found
(still valid, or renewable via its refresh token), the interactive login is skipped entirely. Otherwise, the login
flow runs and the fetched token is stored in the keyring afterward. Tokens are keyed by token endpoint and client
ID, and refreshed tokens are written back automatically. A broken or unavailable keyring only prints a warning and
falls back to the interactive login.
Client Credentials Flow
For server-to-server authentication. Ideal for automated systems, CI/CD pipelines, and service-to-service communication.
Automatically discovers token endpoint via RFC 8414:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/clientcredentials"
provider, err := clientcredentials.NewDiscoveryProvider(
ctx,
"https://auth.example.com",
"client-id",
"client-secret",
clientcredentials.WithScopes("daml_ledger_api", "admin"),
)
Direct Configuration
If metadata discovery is unavailable:
provider, err := clientcredentials.NewProvider(
ctx,
"https://auth.example.com/oauth/token",
"client-id",
"client-secret",
)
Additional options are available via the functional options pattern (see package documentation for WithScopes,
WithTransportCredentials, etc).
Static Providers
For cases where you already have an access token and don't need OAuth flows:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/static"
provider := static.NewStaticProvider("access-token")
The static provider enforces TLS transport security and is suitable for remote environments.
Insecure Static Provider
For testing against LocalNet or other non-production environments only:
import "github.com/smartcontractkit/chainlink-canton/authentication/providers/static"
provider := static.NewInsecureStaticProvider("access-token")
The insecure static provider does not enforce transport security and must not be used in production.
Token Management
Both providers automatically handle token lifecycle management: caching, automatic refresh, and thread-safe operations.