omnitoken

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2026 License: MIT Imports: 20 Imported by: 0

README

OmniToken

Go CI Go Lint Go SAST Go Report Card Docs Docs Visualization License

Token management SDK that bridges goauth credentials with vault-based storage via omnivault.

Overview

OmniToken enables applications (particularly MCP servers) to:

  • Store and retrieve goauth Credentials in various vault backends
  • Automatically manage OAuth2 token lifecycle (acquisition, refresh, caching)
  • Implement goauth's TokenSet interface for vault-backed token storage
  • Support multiple credential types (OAuth2, JWT, Basic Auth, API keys, GCP service accounts)

Architecture

┌──────────────────────────────────────────────────────────────┐
│                      Applications                            │
│  ┌───────────┐  ┌───────────┐  ┌─────────────────┐           │
│  │ mcp-google│  │  mcp-aha  │  │ mcp-confluence  │           │
│  └─────┬─────┘  └─────┬─────┘  └────────┬────────┘           │
│        └──────────────┼─────────────────┘                    │
│                       │                                      │
│              ┌────────▼────────┐                             │
│              │    omnitoken    │ ← Credential & token mgmt   │
│              └────────┬────────┘                             │
└───────────────────────┼──────────────────────────────────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
   ┌────▼────┐    ┌─────▼─────┐   ┌─────▼─────┐
   │ goauth  │    │ omnivault │   │  oauth2   │
   │(creds)  │    │ (storage) │   │ (tokens)  │
   └─────────┘    └─────┬─────┘   └───────────┘
                        │
        ┌───────────────┼───────────────┐
        │               │               │
   ┌────▼────┐    ┌─────▼─────┐   ┌─────▼─────┐
   │1Password│    │ Bitwarden │   │  Keeper   │
   └─────────┘    └───────────┘   └───────────┘

Installation

go get github.com/plexusone/omnitoken

Quick Start

From Vault URI
import "github.com/plexusone/omnitoken"

// Create from vault URI (1Password, Bitwarden, file, etc.)
mgr, err := omnitoken.NewFromVaultURI("op://MyVault")
if err != nil {
    log.Fatal(err)
}
defer mgr.Close()

// Get credentials stored in the vault
creds, err := mgr.GetCredentials(ctx, "my-api")

// Get an authenticated HTTP client
client, err := mgr.GetClient(ctx, "my-api")
From Credentials File
// Load from goauth CredentialsSet file
mgr, err := omnitoken.NewFromCredentialsFile("/path/to/credentials.json")
if err != nil {
    log.Fatal(err)
}
defer mgr.Close()

// Get client for a specific account
client, err := mgr.GetClient(ctx, "myaccount")
Auto-Detection
// Auto-detect from environment variables:
// - OMNITOKEN_VAULT_URI: vault URI
// - OMNITOKEN_CREDENTIALS_FILE: credentials file path
mgr, err := omnitoken.NewAuto()
if err != nil {
    log.Fatal(err)
}
defer mgr.Close()

Credential Sources

Source Constructor Description
Vault URI NewFromVaultURI(uri) Any omnivault-supported backend
Credentials File NewFromCredentialsFile(path) goauth CredentialsSet JSON
CredentialsSet NewFromCredentialsSet(set) In-memory from goauth.CredentialsSet
Single Credential NewFromCredentials(name, creds) Single goauth.Credentials
Environment NewFromEnv(prefix) Environment variables
Directory NewFromDirectory(dir) File-based storage
Auto NewAuto() Auto-detect from environment

Supported Vault URIs

Provider URI Pattern Requirements
1Password op://vault OP_SERVICE_ACCOUNT_TOKEN env var
Bitwarden bw://org-id BW_ACCESS_TOKEN, BW_ORGANIZATION_ID env vars
Keeper keeper:// KSM_TOKEN or KSM_CONFIG env var
File file:///path None
Environment env://PREFIX_ None
Memory memory:// None (testing)

To use 1Password, Bitwarden, or Keeper, import omnivault-desktop:

import _ "github.com/plexusone/omnivault-desktop"

Environment Variables

Variable Description
OMNITOKEN_VAULT_URI Vault URI for NewAuto()
OMNITOKEN_CREDENTIALS_FILE Credentials file path for NewAuto()
OMNITOKEN_CREDENTIALS_NAME Default credential name (used by MCP servers)

API Reference

TokenManager
// Create token manager
mgr, err := omnitoken.New(omnitoken.Config{
    Vault:         vault,           // omnivault.Vault implementation
    AutoRefresh:   true,            // Auto-refresh expired tokens
    RefreshBuffer: 5 * time.Minute, // Refresh before expiry
})

// Credential operations
creds, err := mgr.GetCredentials(ctx, "name")
err := mgr.SetCredentials(ctx, "name", creds)
err := mgr.DeleteCredentials(ctx, "name")
names, err := mgr.ListCredentials(ctx)

// Token operations
client, err := mgr.GetClient(ctx, "name")     // Get authenticated HTTP client
token, err := mgr.GetToken(ctx, "name")       // Get OAuth2 token
token, err := mgr.RefreshToken(ctx, "name")   // Force refresh

// goauth integration
tokenSet := mgr.TokenSet()                    // Get goauth TokenSet interface
credStore := mgr.CredentialsStore()           // Get credentials store

// Cleanup
err := mgr.Close()
Loading Specific Credential Types
// Load Google service account
err := mgr.LoadGoogleServiceAccount(ctx, "google", "/path/to/sa.json", []string{
    "https://www.googleapis.com/auth/presentations.readonly",
    "https://www.googleapis.com/auth/documents.readonly",
})

// Load from goauth CredentialsSet file
err := mgr.LoadGoauthCredentials(ctx, "myservice", "/path/to/creds.json", "accountKey")

Credential Types

OmniToken supports all goauth credential types:

Type Description
oauth2 OAuth2 client credentials, authorization code, etc.
jwt JWT bearer tokens
basic HTTP Basic Auth
headerquery Custom header/query authentication
gcpsa Google Cloud service account

Token Lifecycle

The TokenManager handles the complete token lifecycle:

  1. Retrieves credentials from vault
  2. Checks for cached/stored valid token
  3. Refreshes expired tokens using refresh_token if available
  4. Obtains new tokens when refresh isn't possible
  5. Stores tokens in vault for persistence across restarts

Usage in MCP Servers

OmniToken is designed for use in MCP servers. See mcp-google for a complete example:

import (
    "github.com/plexusone/omnitoken"
    _ "github.com/plexusone/omnivault-desktop"
)

func main() {
    // Create token manager from vault
    mgr, err := omnitoken.NewFromVaultURI(os.Getenv("OMNITOKEN_VAULT_URI"))
    if err != nil {
        log.Fatal(err)
    }
    defer mgr.Close()

    // Get credentials for the service
    creds, err := mgr.GetCredentials(ctx, os.Getenv("OMNITOKEN_CREDENTIALS_NAME"))
    if err != nil {
        log.Fatal(err)
    }

    // Create authenticated HTTP client
    client, err := creds.NewClient(ctx)
    if err != nil {
        log.Fatal(err)
    }

    // Use client with service SDK...
}

License

MIT

Documentation

Overview

Package omnitoken provides a token management SDK that bridges goauth credentials with vault-based storage via omnivault.

Overview

omnitoken enables applications (particularly MCP servers via omniskill) to:

  • Store and retrieve goauth Credentials in various vault backends
  • Automatically manage OAuth2 token lifecycle (acquisition, refresh, caching)
  • Implement goauth's TokenSet interface for vault-backed token storage
  • Support multiple credential types (OAuth2, JWT, Basic Auth, API keys)

Architecture

omnitoken sits between three libraries:

  • goauth: Provides the Credentials struct and token acquisition logic
  • omnivault: Provides vault abstractions for 30+ backends (1Password, HashiCorp Vault, etc.)
  • omniskill: MCP server framework that uses omnitoken for credential management

Basic Usage

import (
    "github.com/plexusone/omnitoken"
    "github.com/plexusone/omnivault/providers/memory"
)

// Create vault backend (use real vault in production)
vault := memory.New()

// Create token manager
mgr, err := omnitoken.New(omnitoken.Config{
    Vault: vault,
})
if err != nil {
    log.Fatal(err)
}
defer mgr.Close()

// Store credentials
creds := &goauth.Credentials{
    Service: "github",
    Type:    goauth.TypeOAuth2,
    OAuth2: &goauth.CredentialsOAuth2{
        ClientID:     "...",
        ClientSecret: "...",
        GrantType:    "client_credentials",
    },
}
mgr.SetCredentials(ctx, "my-github-app", creds)

// Get authenticated HTTP client
client, err := mgr.GetClient(ctx, "my-github-app")

Vault Integration

omnitoken uses omnivault for storage, supporting backends like:

  • 1Password (op://)
  • HashiCorp Vault (vault://)
  • OpenBao (openbao://)
  • Bitwarden (bw://)
  • AWS Secrets Manager (aws-sm://)
  • Azure Key Vault (azure-kv://)
  • GCP Secret Manager (gcp-sm://)
  • macOS Keychain (keychain://)
  • Environment variables (env://)
  • Files (file://)

Token Lifecycle

The TokenManager handles the complete token lifecycle:

  1. Retrieves credentials from vault
  2. Checks for cached/stored valid token
  3. Refreshes expired tokens using refresh_token if available
  4. Obtains new tokens when refresh isn't possible
  5. Stores tokens in vault for persistence across restarts

goauth Integration

omnitoken implements goauth's TokenSet interface via VaultTokenSet, enabling integration with goauth's multi-service token management:

tokenSet := mgr.TokenSet()
// Use with goauth's NewClientWithTokenSet, OAuth2Manager, etc.

Package omnitoken provides a token management SDK that bridges goauth credentials with vault-based storage via omnivault. It enables MCP servers and other applications to manage OAuth2 tokens and service credentials generically across multiple vault backends.

Key features:

  • Store and retrieve goauth Credentials in vaults (1Password, HashiCorp Vault, etc.)
  • Implement goauth's TokenSet interface for vault-backed token storage
  • Automatic token refresh with configurable buffer time
  • Support for multiple credential types (OAuth2, JWT, Basic Auth, etc.)

Basic usage:

import (
    "github.com/plexusone/omnitoken"
    "github.com/plexusone/omnivault/providers/memory"
)

// Create vault backend
vault := memory.New()

// Create token manager
mgr, err := omnitoken.New(omnitoken.Config{
    Vault: vault,
})

// Get an authenticated HTTP client
client, err := mgr.GetClient(ctx, "my-app")

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCredentialsNotFound is returned when credentials are not found in the vault.
	ErrCredentialsNotFound = errors.New("credentials not found")

	// ErrTokenNotFound is returned when a token is not found in the vault.
	ErrTokenNotFound = errors.New("token not found")

	// ErrTokenExpired is returned when a token has expired and cannot be refreshed.
	ErrTokenExpired = errors.New("token expired")

	// ErrRefreshFailed is returned when token refresh fails.
	ErrRefreshFailed = errors.New("token refresh failed")

	// ErrInvalidCredentials is returned when credentials are malformed.
	ErrInvalidCredentials = errors.New("invalid credentials")

	// ErrVaultNotConfigured is returned when vault is not configured.
	ErrVaultNotConfigured = errors.New("vault not configured")

	// ErrUnsupportedCredentialType is returned for unsupported credential types.
	ErrUnsupportedCredentialType = errors.New("unsupported credential type")
)

Functions

func CredentialsDir

func CredentialsDir() (string, error)

CredentialsDir returns the default credentials directory for the current user. On Unix: ~/.config/omnitoken/credentials On macOS: ~/Library/Application Support/omnitoken/credentials On Windows: %APPDATA%/omnitoken/credentials

Types

type Config

type Config struct {
	// Vault is the vault backend for storing credentials and tokens.
	// Required.
	Vault vault.Vault

	// CredentialsPrefix is the path prefix for storing credentials in the vault.
	// Default: "credentials/"
	CredentialsPrefix string

	// TokensPrefix is the path prefix for storing tokens in the vault.
	// Default: "tokens/"
	TokensPrefix string

	// RefreshBuffer is the time before expiry to trigger token refresh.
	// Default: 60 seconds
	RefreshBuffer time.Duration

	// AutoRefresh enables automatic token refresh when tokens are near expiry.
	// Default: true
	AutoRefresh bool

	// Logger is the logger for the token manager.
	// Default: slog.Default()
	Logger *slog.Logger
}

Config configures the TokenManager.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with default values. Vault must still be set before use.

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration and returns an error if invalid.

type CredentialsStore

type CredentialsStore struct {
	// contains filtered or unexported fields
}

CredentialsStore manages goauth Credentials in a vault.

func NewCredentialsStore

func NewCredentialsStore(v vault.Vault, prefix string, logger *slog.Logger) *CredentialsStore

NewCredentialsStore creates a new CredentialsStore.

func (*CredentialsStore) Delete

func (cs *CredentialsStore) Delete(ctx context.Context, name string) error

Delete removes credentials from the vault.

func (*CredentialsStore) Exists

func (cs *CredentialsStore) Exists(ctx context.Context, name string) (bool, error)

Exists checks if credentials exist in the vault.

func (*CredentialsStore) Get

Get retrieves credentials from the vault by name.

func (*CredentialsStore) GetWithTimeout

func (cs *CredentialsStore) GetWithTimeout(name string, timeout time.Duration) (*goauth.Credentials, error)

GetWithTimeout retrieves credentials with a timeout.

func (*CredentialsStore) List

func (cs *CredentialsStore) List(ctx context.Context) ([]string, error)

List returns all credential names in the vault.

func (*CredentialsStore) LoadCredentialsSet

func (cs *CredentialsStore) LoadCredentialsSet(ctx context.Context) (*goauth.CredentialsSet, error)

CredentialsSetFromVault loads a goauth.CredentialsSet from multiple vault entries.

func (*CredentialsStore) SaveCredentialsSet

func (cs *CredentialsStore) SaveCredentialsSet(ctx context.Context, set *goauth.CredentialsSet) error

SaveCredentialsSet saves a goauth.CredentialsSet to the vault.

func (*CredentialsStore) Set

func (cs *CredentialsStore) Set(ctx context.Context, name string, creds *goauth.Credentials) error

Set stores credentials in the vault.

type TokenManager

type TokenManager struct {
	// contains filtered or unexported fields
}

TokenManager manages credentials and tokens using vault storage. It provides a unified interface for obtaining authenticated HTTP clients from stored credentials, with automatic token refresh and caching.

func New

func New(cfg Config) (*TokenManager, error)

New creates a new TokenManager with the given configuration.

func NewAuto

func NewAuto() (*TokenManager, error)

NewAuto creates a TokenManager by auto-detecting configuration from environment. It checks the following in order:

  1. OMNITOKEN_VAULT_URI - vault URI (e.g., "op://vault", "file:///path")
  2. OMNITOKEN_CREDENTIALS_FILE - path to goauth CredentialsSet file
  3. Falls back to in-memory vault

func NewFromCredentials

func NewFromCredentials(name string, creds *goauth.Credentials) (*TokenManager, error)

NewFromCredentials creates a TokenManager with a single credential. The credential is stored in an in-memory vault under the given name.

func NewFromCredentialsFile

func NewFromCredentialsFile(credentialsFile string) (*TokenManager, error)

NewFromCredentialsFile creates a TokenManager from a goauth CredentialsSet JSON file. The credentials are loaded into an in-memory vault for the session. This is useful for file-based credential workflows without a persistent vault.

func NewFromCredentialsSet

func NewFromCredentialsSet(set *goauth.CredentialsSet) (*TokenManager, error)

NewFromCredentialsSet creates a TokenManager from an existing goauth.CredentialsSet. The credentials are stored in an in-memory vault.

func NewFromDirectory

func NewFromDirectory(directory string) (*TokenManager, error)

NewFromDirectory creates a TokenManager using a directory for file-based storage. Credentials are stored as JSON files in {directory}/credentials/ Tokens are stored as JSON files in {directory}/tokens/

This provides persistent storage without requiring a vault service.

func NewFromEnv

func NewFromEnv(prefix string) (*TokenManager, error)

NewFromEnv creates a TokenManager that reads credentials from environment variables. Environment variables should be named with the pattern: {prefix}{NAME}_CREDENTIALS containing JSON-encoded goauth.Credentials.

If prefix is empty, it defaults to "OMNITOKEN_".

func NewFromVaultURI

func NewFromVaultURI(uri string) (*TokenManager, error)

NewFromVaultURI creates a TokenManager from a vault URI. Supported URI schemes:

  • memory:// - In-memory (testing)
  • file:///path/to/dir - File-based storage
  • env:// - Environment variables (with optional prefix: env://PREFIX_)
  • op:// - 1Password (requires OP_SERVICE_ACCOUNT_TOKEN env var)

Additional providers can be registered via omnivault.RegisterProvider.

func NewWithVault

func NewWithVault(v vault.Vault) (*TokenManager, error)

NewWithVault creates a new TokenManager with the given vault and default configuration.

func (*TokenManager) Close

func (tm *TokenManager) Close() error

Close releases resources held by the token manager.

func (*TokenManager) CredentialsStore

func (tm *TokenManager) CredentialsStore() *CredentialsStore

CredentialsStore returns the underlying credentials store.

func (*TokenManager) DeleteCredentials

func (tm *TokenManager) DeleteCredentials(ctx context.Context, name string) error

DeleteCredentials removes credentials from the vault.

func (*TokenManager) GetClient

func (tm *TokenManager) GetClient(ctx context.Context, name string) (*http.Client, error)

GetClient returns an authenticated HTTP client for the named credentials. It retrieves credentials from the vault, obtains or refreshes the token as needed, and returns a client configured with the token.

func (*TokenManager) GetCredentials

func (tm *TokenManager) GetCredentials(ctx context.Context, name string) (*goauth.Credentials, error)

GetCredentials retrieves credentials from the vault by name.

func (*TokenManager) GetToken

func (tm *TokenManager) GetToken(ctx context.Context, name string) (*oauth2.Token, error)

GetToken returns a valid OAuth2 token for the named credentials. It retrieves from cache/vault if valid, or obtains a new token if needed.

func (*TokenManager) ListCredentials

func (tm *TokenManager) ListCredentials(ctx context.Context) ([]string, error)

ListCredentials returns all credential names in the vault.

func (*TokenManager) LoadGoauthCredentials

func (tm *TokenManager) LoadGoauthCredentials(ctx context.Context, name, credentialsFile, accountKey string) error

LoadGoauthCredentials loads a goauth credential from a CredentialsSet file. The credential is stored under the given name (or accountKey if name is empty).

func (*TokenManager) LoadGoogleServiceAccount

func (tm *TokenManager) LoadGoogleServiceAccount(ctx context.Context, name, serviceAccountFile string, scopes []string) error

LoadGoogleServiceAccount loads a Google service account JSON file into the TokenManager. The credentials are stored under the given name with type "gcpsa". Scopes should be the OAuth2 scopes required for the Google APIs you'll use.

func (*TokenManager) RefreshToken

func (tm *TokenManager) RefreshToken(ctx context.Context, name string) (*oauth2.Token, error)

RefreshToken forces a token refresh for the named credentials.

func (*TokenManager) SetCredentials

func (tm *TokenManager) SetCredentials(ctx context.Context, name string, creds *goauth.Credentials) error

SetCredentials stores credentials in the vault.

func (*TokenManager) TokenSet

func (tm *TokenManager) TokenSet() tokens.TokenSet

TokenSet returns the underlying goauth TokenSet implementation. This allows integration with goauth's multi-service token management.

type VaultTokenSet

type VaultTokenSet struct {
	// contains filtered or unexported fields
}

VaultTokenSet implements goauth's tokens.TokenSet interface backed by an omnivault. This allows goauth's multi-service token management to use vault storage.

func NewVaultTokenSet

func NewVaultTokenSet(v vault.Vault, prefix string, logger *slog.Logger) *VaultTokenSet

NewVaultTokenSet creates a new VaultTokenSet.

func (*VaultTokenSet) DeleteToken

func (ts *VaultTokenSet) DeleteToken(key string) error

DeleteToken removes a token from the vault.

func (*VaultTokenSet) ExistsToken

func (ts *VaultTokenSet) ExistsToken(key string) (bool, error)

ExistsToken checks if a token exists in the vault.

func (*VaultTokenSet) GetToken

func (ts *VaultTokenSet) GetToken(key string) (*oauth2.Token, error)

GetToken retrieves just the OAuth2 token from the vault.

func (*VaultTokenSet) GetTokenInfo

func (ts *VaultTokenSet) GetTokenInfo(key string) (*tokens.TokenInfo, error)

GetTokenInfo retrieves token info from the vault.

func (*VaultTokenSet) ListTokens

func (ts *VaultTokenSet) ListTokens() ([]string, error)

ListTokens returns all token keys in the vault.

func (*VaultTokenSet) SetTokenInfo

func (ts *VaultTokenSet) SetTokenInfo(key string, tokenInfo *tokens.TokenInfo) error

SetTokenInfo stores token info in the vault.

Directories

Path Synopsis
examples
basic command
Package main demonstrates basic usage of omnitoken.
Package main demonstrates basic usage of omnitoken.
mcp command
Package main demonstrates using omnitoken with MCP servers.
Package main demonstrates using omnitoken with MCP servers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL