onepassword

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 10 Imported by: 0

README

OmniVault Provider for 1Password

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

OmniVault provider for 1Password using the official 1Password Go SDK.

Features

  • 🔐 Access 1Password secrets through the unified OmniVault interface
  • 📋 Support for multi-field items (username, password, URL, etc.)
  • ⚡ Batch secret resolution for efficient bulk access
  • 🔢 TOTP code generation
  • ✏️ Full CRUD operations (create, read, update, delete)
  • 🔗 Flexible path formats including native op:// references

Requirements

  • Go 1.22 or later (Go 1.24+ recommended for 1Password SDK)
  • 1Password account with Service Account access
  • Service account token with appropriate vault permissions

Installation

go get github.com/agentplexus/omnivault-onepassword

Quick Start

1. Create a Service Account
  1. Go to 1Password Developer Tools
  2. Create a new service account
  3. Grant it access to the vaults you need
2. Set the Token
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
3. Use the Provider
package main

import (
    "context"
    "fmt"
    "log"

    op "github.com/agentplexus/omnivault-onepassword"
)

func main() {
    // Create provider (uses OP_SERVICE_ACCOUNT_TOKEN env var)
    provider, err := op.NewFromEnv()
    if err != nil {
        log.Fatal(err)
    }
    defer provider.Close()

    ctx := context.Background()

    // Get a specific field
    secret, err := provider.Get(ctx, "Private/API Keys/github-token")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Token:", secret.Value)

    // Get all fields from an item
    creds, err := provider.Get(ctx, "Private/Database Credentials")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Username:", creds.Fields["username"])
    fmt.Println("Password:", creds.Fields["password"])
}

Path Formats

The provider supports multiple path formats:

Format Example Description
vault/item/field Private/API Keys/token Full path to a specific field
vault/item Private/Database Creds All fields from an item
item/field API Keys/token With default vault configured
item API Keys Item in default vault
op://vault/item/field op://Private/API Keys/token Native 1Password reference

Configuration

provider, err := op.New(op.Config{
    // Required: Service account token (or use OP_SERVICE_ACCOUNT_TOKEN env var)
    ServiceAccountToken: "ops_...",

    // Optional: Default vault for simplified paths
    DefaultVaultName: "Private",

    // Optional: Default category for new items
    DefaultCategory: op.CategoryLogin,

    // Optional: Integration identification
    IntegrationName:    "my-app",
    IntegrationVersion: "1.0.0",
})

Usage with OmniVault Resolver

import (
    "github.com/agentplexus/omnivault"
    op "github.com/agentplexus/omnivault-onepassword"
)

// Create provider
provider, _ := op.NewFromEnv()

// Register with resolver
resolver := omnivault.NewResolver()
resolver.Register("op", provider)

// Resolve secrets using URI syntax
token, _ := resolver.Resolve(ctx, "op://Private/API Keys/github-token")

Operations

Read Secrets
// Get specific field
secret, err := provider.Get(ctx, "vault/item/field")
fmt.Println(secret.Value)

// Get all fields
secret, err := provider.Get(ctx, "vault/item")
for name, value := range secret.Fields {
    fmt.Printf("%s: %s\n", name, value)
}

// Check existence
exists, err := provider.Exists(ctx, "vault/item")
Write Secrets
// Create new item
err := provider.Set(ctx, "vault/new-item", &vault.Secret{
    Value: "secret-value",
    Fields: map[string]string{
        "username": "user@example.com",
        "password": "secure-password",
        "url":      "https://example.com",
    },
})

// Update specific field
err := provider.Set(ctx, "vault/item/password", &vault.Secret{
    Value: "new-password",
})
Delete Secrets
err := provider.Delete(ctx, "vault/item")
List Secrets
// List all items
items, err := provider.List(ctx, "")

// List items with prefix
items, err := provider.List(ctx, "Private/")
Batch Operations
// Get multiple secrets efficiently
results, err := provider.GetBatch(ctx, []string{
    "Private/API Keys/github",
    "Private/API Keys/aws",
    "Private/Database/prod",
})

for path, secret := range results {
    fmt.Printf("%s: %s\n", path, secret.Value)
}

Field Type Inference

When creating items, field types are automatically inferred from names:

Field Name Contains 1Password Type
password, secret, token, key Concealed
url, website, endpoint URL
phone, mobile, tel Phone
(value starts with otpauth://) TOTP
(other) Text

Metadata

Retrieved secrets include rich metadata:

secret, _ := provider.Get(ctx, "vault/item")

fmt.Println(secret.Metadata.Provider)   // "onepassword"
fmt.Println(secret.Metadata.Path)       // "vault/item"
fmt.Println(secret.Metadata.Version)    // "5"

// Extra metadata
fmt.Println(secret.Metadata.Extra["vaultId"])  // "abc123"
fmt.Println(secret.Metadata.Extra["itemId"])   // "def456"
fmt.Println(secret.Metadata.Extra["category"]) // "Login"

// Tags
for key, value := range secret.Metadata.Tags {
    fmt.Printf("Tag: %s=%s\n", key, value)
}

Capabilities

caps := provider.Capabilities()
// caps.Read       = true
// caps.Write      = true
// caps.Delete     = true
// caps.List       = true
// caps.MultiField = true
// caps.Batch      = true
// caps.Binary     = true
// caps.Versioning = false (SDK limitation)
// caps.Rotation   = false (SDK limitation)

Error Handling

secret, err := provider.Get(ctx, "vault/item/field")
if err != nil {
    if errors.Is(err, vault.ErrSecretNotFound) {
        // Secret doesn't exist
    } else if errors.Is(err, vault.ErrAccessDenied) {
        // No permission to access
    } else {
        // Other error
    }
}

Testing

# Unit tests
go test -v ./...

# Integration tests (requires credentials)
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
export OP_TEST_VAULT_NAME="Test Vault"
go test -tags=integration -v ./...

License

MIT License - see LICENSE for details.

Documentation

Overview

Package onepassword provides an OmniVault provider for 1Password.

This package implements the vault.Vault interface using the official 1Password Go SDK, allowing applications to access secrets stored in 1Password vaults through the unified OmniVault interface.

Authentication requires a 1Password Service Account token. Create one at: https://my.1password.com/developer-tools/infrastructure-secrets/serviceaccount/

Basic usage:

provider, err := onepassword.New(onepassword.Config{
    ServiceAccountToken: os.Getenv("OP_SERVICE_ACCOUNT_TOKEN"),
})
if err != nil {
    log.Fatal(err)
}
defer provider.Close()

secret, err := provider.Get(ctx, "Private/API Keys/github-token")

With OmniVault resolver:

resolver := omnivault.NewResolver()
resolver.Register("op", provider)
value, err := resolver.Resolve(ctx, "op://Private/API Keys/github-token")

Index

Constants

View Source
const (
	// ProviderName is the name returned by Provider.Name().
	ProviderName = "onepassword"

	// EnvServiceAccountToken is the environment variable for the service account token.
	EnvServiceAccountToken = "OP_SERVICE_ACCOUNT_TOKEN" //nolint:gosec // G101: this is an env var name, not a credential

	// DefaultIntegrationName identifies this integration to 1Password.
	DefaultIntegrationName = "omnivault-onepassword"

	// DefaultIntegrationVersion is the default version string.
	DefaultIntegrationVersion = "0.1.0"
)
View Source
const (
	CategoryLogin          = op.ItemCategoryLogin
	CategorySecureNote     = op.ItemCategorySecureNote
	CategoryAPICredentials = op.ItemCategoryAPICredentials
	CategoryDatabase       = op.ItemCategoryDatabase
	CategoryServer         = op.ItemCategoryServer
	CategoryPassword       = op.ItemCategoryPassword
	CategorySSHKey         = op.ItemCategorySSHKey
)

Common item categories re-exported for convenience.

Variables

View Source
var ErrInvalidPath = errors.New("invalid path format")

ErrInvalidPath is returned when a path cannot be parsed.

Functions

This section is empty.

Types

type Config

type Config struct {
	// ServiceAccountToken is the 1Password service account token.
	// Required. Can also be set via OP_SERVICE_ACCOUNT_TOKEN environment variable.
	ServiceAccountToken string

	// IntegrationName identifies this integration to 1Password.
	// Default: "omnivault-onepassword"
	IntegrationName string

	// IntegrationVersion is the version of this integration.
	// Default: "0.1.0"
	IntegrationVersion string

	// DefaultVaultID is used when path doesn't specify a vault.
	// Takes precedence over DefaultVaultName if both are set.
	DefaultVaultID string

	// DefaultVaultName is used when path doesn't specify a vault.
	// Resolved to ID on first use.
	DefaultVaultName string

	// DefaultCategory is the item category for newly created items.
	// Default: CategorySecureNote
	DefaultCategory op.ItemCategory

	// CacheTTL enables caching of vault/item ID lookups.
	// Zero disables caching. Default: 0 (disabled)
	CacheTTL time.Duration

	// Logger for debug output. Optional.
	Logger *slog.Logger
}

Config holds configuration for the 1Password provider.

type ParsedPath

type ParsedPath struct {
	// Vault is the vault name or ID.
	Vault string

	// Item is the item name or ID.
	Item string

	// Section is the section name (optional).
	Section string

	// Field is the field name (optional).
	Field string
}

ParsedPath represents a parsed 1Password secret path.

func ParsePath

func ParsePath(path string, defaultVault string) (*ParsedPath, error)

ParsePath parses a path string into components.

Supported formats:

  • "vault/item/field" - full path with vault, item, and field
  • "vault/item" - vault and item (returns all fields)
  • "item/field" - item and field (uses defaultVault)
  • "item" - item only (uses defaultVault, returns all fields)
  • "vault/item/section/field" - full path with section
  • "op://vault/item/field" - native 1Password secret reference

func (*ParsedPath) SecretReference

func (p *ParsedPath) SecretReference() string

SecretReference returns the path as a 1Password secret reference URI.

func (*ParsedPath) String

func (p *ParsedPath) String() string

String returns the path in canonical format.

type Provider

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

Provider implements vault.Vault for 1Password.

func New

func New(config Config) (*Provider, error)

New creates a new 1Password provider with the given configuration.

func NewFromEnv

func NewFromEnv() (*Provider, error)

NewFromEnv creates a new provider using the OP_SERVICE_ACCOUNT_TOKEN environment variable.

func NewWithContext

func NewWithContext(ctx context.Context, config Config) (*Provider, error)

NewWithContext creates a new 1Password provider with context.

func (*Provider) Capabilities

func (p *Provider) Capabilities() vault.Capabilities

Capabilities returns the provider capabilities.

func (*Provider) Close

func (p *Provider) Close() error

Close releases resources held by the provider.

func (*Provider) Delete

func (p *Provider) Delete(ctx context.Context, path string) error

Delete removes a secret from 1Password.

func (*Provider) DeleteBatch

func (p *Provider) DeleteBatch(ctx context.Context, paths []string) error

DeleteBatch removes multiple secrets in a single operation. Note: 1Password SDK doesn't support batch deletes, so this is implemented as sequential operations.

func (*Provider) Exists

func (p *Provider) Exists(ctx context.Context, path string) (bool, error)

Exists checks if a secret exists in 1Password.

func (*Provider) Get

func (p *Provider) Get(ctx context.Context, path string) (*vault.Secret, error)

Get retrieves a secret from 1Password.

Path formats supported:

  • "vault/item/field" - returns the specific field value
  • "vault/item" - returns the item with all fields
  • "item/field" - uses default vault (if configured)
  • "op://vault/item/field" - native 1Password secret reference

func (*Provider) GetBatch

func (p *Provider) GetBatch(ctx context.Context, paths []string) (map[string]*vault.Secret, error)

GetBatch retrieves multiple secrets in a single operation. This implements the vault.BatchVault interface.

Note: The 1Password SDK v0.1.x doesn't support batch resolution, so this is implemented as sequential Resolve calls.

func (*Provider) List

func (p *Provider) List(ctx context.Context, prefix string) ([]string, error)

List returns all secret paths matching the prefix.

func (*Provider) Name

func (p *Provider) Name() string

Name returns the provider name.

func (*Provider) Set

func (p *Provider) Set(ctx context.Context, path string, secret *vault.Secret) error

Set stores a secret in 1Password.

func (*Provider) SetBatch

func (p *Provider) SetBatch(ctx context.Context, secrets map[string]*vault.Secret) error

SetBatch stores multiple secrets in a single operation. Note: 1Password SDK doesn't support batch writes, so this is implemented as sequential operations.

Directories

Path Synopsis
examples
basic command
Example: Basic usage of omnivault-onepassword
Example: Basic usage of omnivault-onepassword
resolver command
Example: Using omnivault-onepassword with OmniVault resolver
Example: Using omnivault-onepassword with OmniVault resolver

Jump to

Keyboard shortcuts

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