pki

package
v1.22.1 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2025 License: MIT Imports: 21 Imported by: 0

README

OpenBao/Vault PKI Integration

Type-safe PKI operations with OpenBao and HashiCorp Vault

Go Version Test Coverage Integration Tests


📋 Table of Contents


Overview

The bao package provides seamless integration between GoPKI's type-safe cryptographic operations and OpenBao/Vault PKI secrets engine. It enables centralized certificate authority management while maintaining the security and type safety that GoPKI is known for.

What You Can Do
  • Manage Certificate Authorities: Create root and intermediate CAs
  • Generate Keys: RSA, ECDSA, and Ed25519 with type-safe operations
  • Issue Certificates: Multiple workflows for different security requirements
  • Configure Policies: Role-based certificate issuance policies
  • Navigate Relationships: Fluent APIs between Keys, Issuers, Roles, and Certificates
  • Complete Lifecycle: From CA setup to certificate revocation

Key Features

Type-Safe Design
  • ✅ Generic-based API prevents runtime type errors
  • ✅ Compile-time type checking for all cryptographic operations
  • ✅ Support for RSA, ECDSA, and Ed25519 algorithms
Security First
  • 🔒 Private keys can stay local (never sent to OpenBao)
  • 🔒 CSR-based certificate issuance workflow
  • 🔒 Secure key storage in OpenBao when needed
Integration Features
  • 🔗 Fluent APIs for navigating between related resources
  • 🔗 Builder patterns for complex configurations
  • 🔗 Automatic relationship management
Developer Experience
  • 📚 Comprehensive documentation and examples
  • 🧪 Integration tests with testcontainers
  • 🎯 Clear error messages and type safety
  • 🚀 Simple and intuitive API design

Architecture & Relationships

The bao package is built around four core types that have clear relationships with each other:

┌─────────────────┐
│  KeyClient[K]   │  ← Foundation: Manages cryptographic keys
└────────┬────────┘
         │ GetIssuers()
         ↓
┌─────────────────┐
│  IssuerClient   │  ← Certificate Authority: Signs certificates
└────────┬────────┘
         │ CreateRole() / IssueXXXCertificate()
         ↓
┌─────────────────┐
│   RoleClient    │  ← Policy: Defines certificate constraints
└────────┬────────┘
         │ GetIssuer() / IssueXXXCertificate()
         ↓
┌─────────────────┐
│CertificateClient│  ← End Result: Issued certificate
└─────────────────┘
Relationship Flow
  1. KeyClient → IssuerClient: A key becomes an issuer when it's used to create a CA certificate
  2. IssuerClient → RoleClient: Issuers can create roles to define certificate policies
  3. RoleClient → CertificateClient: Roles are used to issue certificates with specific constraints
  4. Bidirectional Navigation: All relationships support navigation in both directions
Key Relationships
From To Method Description
KeyClient IssuerClient GetIssuers() Find all CAs using this key
IssuerClient RoleClient CreateRole() Create a role under this CA
IssuerClient CertificateClient IssueXXXCertificate() Issue certificate directly
RoleClient IssuerClient GetIssuer() Get the CA for this role
RoleClient CertificateClient IssueXXXCertificate() Issue certificate using role

Quick Start

Installation
go get github.com/jasoet/gopki/bao
Basic Usage
package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/jasoet/gopki/bao"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    ctx := context.Background()
    
    // 1. Connect to OpenBao
    client, err := bao.NewClient(&bao.Config{
        Address: "http://localhost:8200",
        Token:   "root-token",
        Mount:   "pki",
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // 2. Generate CA key and certificate
    caKey, err := client.GenerateRSAKey(ctx, &bao.GenerateKeyOptions{
        KeyName: "my-ca-key",
        KeyBits: 4096,
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // 3. Create CA (issuer)
    caResp, err := client.GenerateRootCA(ctx, &bao.CAOptions{
        Type:       "internal",
        CommonName: "My Root CA",
        KeyType:    "rsa",
        KeyBits:    4096,
        KeyName:    "my-ca-key",
        IssuerName: "my-ca",
        TTL:        "87600h", // 10 years
    })
    if err != nil {
        log.Fatal(err)
    }
    
    issuer, err := client.GetIssuer(ctx, caResp.IssuerID)
    if err != nil {
        log.Fatal(err)
    }
    
    // 4. Create a role using the issuer
    role, err := issuer.CreateRole(ctx, "web-server", &bao.RoleOptions{
        AllowedDomains:  []string{"example.com"},
        AllowSubdomains: true,
        TTL:             "720h",
        ServerFlag:      true,
    })
    if err != nil {
        log.Fatal(err)
    }
    
    // 5. Issue a certificate using the role
    certClient, err := role.IssueRSACertificate(ctx, "my-app-key", 
        &bao.GenerateCertificateOptions{
            CommonName: "app.example.com",
            TTL:        "720h",
        })
    if err != nil {
        log.Fatal(err)
    }
    
    cert := certClient.Certificate()
    fmt.Printf("Certificate issued: %s\n", cert.Subject.CommonName)
}

Core Concepts

KeyClient

KeyClient[K] provides type-safe operations for cryptographic keys stored in OpenBao.

Type Parameters:

  • K: Key pair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Key Features:

  • Generate keys in OpenBao (internal) or export key material
  • Import existing keys
  • Type-safe operations prevent mixing incompatible key types
  • Navigate to issuers using this key

Example:

// Generate RSA key (key stays in OpenBao)
keyClient, err := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-key",
    KeyBits: 2048,
})

// Export RSA key (returns key material)
keyClient, err := client.GenerateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-exported-key",
    KeyBits: 2048,
})
keyPair, err := keyClient.KeyPair() // Get the key material

// Find all issuers using this key
issuers, err := keyClient.GetIssuers(ctx)
IssuerClient

IssuerClient represents a Certificate Authority (CA) that can sign certificates.

Key Features:

  • Manage CA certificates (root and intermediate)
  • Create roles for certificate issuance
  • Issue certificates directly
  • Sign CSRs
  • Update CA configuration

Example:

// Get issuer
issuer, err := client.GetIssuer(ctx, "my-ca")

// Create a role under this issuer
role, err := issuer.CreateRole(ctx, "web-server", &bao.RoleOptions{
    AllowedDomains:  []string{"example.com"},
    AllowSubdomains: true,
    TTL:             "720h",
})

// Issue certificate directly from issuer
certClient, err := issuer.IssueRSACertificate(ctx, "my-key", 
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
    })

// Sign a CSR
cert, err := issuer.SignCSR(ctx, csr, &bao.SignCertificateOptions{
    TTL: "720h",
})
RoleClient

RoleClient defines policies and constraints for certificate issuance.

Key Features:

  • Configure allowed domains, SANs, key types, etc.
  • Link to specific issuer
  • Issue certificates with role constraints
  • Update role configuration with builder pattern

Example:

// Get role
role, err := client.GetRole(ctx, "web-server")

// Get the issuer for this role
issuer, err := role.GetIssuer(ctx)

// Issue certificate using role
certClient, err := role.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
        TTL:        "720h",
    })

// Update role with builder pattern
err = role.Update(ctx, 
    bao.NewRoleOptionsBuilder().
        WithTTL("1440h").
        WithAllowedDomains("example.com", "example.org").
        WithServerFlag(true).
        Build())
CertificateClient

CertificateClient[K] represents an issued certificate with optional key material.

Type Parameters:

  • K: Key pair type (same as KeyClient)

Key Features:

  • Access certificate and metadata
  • Revoke certificates
  • Access key pair if available (when generated/imported)
  • Type-safe certificate and key operations

Example:

// Issue certificate
certClient, err := role.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
    })

// Access certificate
cert := certClient.Certificate()
fmt.Printf("CN: %s\n", cert.Subject.CommonName)

// Access key pair (if available)
if certClient.HasKeyPair() {
    keyPair, err := certClient.KeyPair()
    // Use keyPair for signing, encryption, etc.
}

// Revoke certificate
err = certClient.Revoke(ctx)

API Reference

Client Creation
// Create client
client, err := bao.NewClient(&bao.Config{
    Address: "http://localhost:8200",
    Token:   "root-token",
    Mount:   "pki",
})
Key Operations
Generate Keys (Internal - OpenBao stores private key)
keyClient, err := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-key",
    KeyBits: 2048,
})

keyClient, err := client.CreateECDSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-ec-key",
    KeyBits: 256,
})

keyClient, err := client.CreateEd25519Key(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-ed25519-key",
})
Generate Keys (Exported - Returns private key)
keyClient, err := client.GenerateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-exported-key",
    KeyBits: 2048,
})
keyPair, err := keyClient.KeyPair() // Get key material
Import Keys
rsaKeyPair, _ := algo.GenerateRSAKeyPair(2048)
keyClient, err := client.ImportRSAKey(ctx, rsaKeyPair, 
    &bao.ImportKeyOptions{
        KeyName: "imported-key",
    })
Key Operations
// List keys
keys, err := client.ListKeys(ctx)

// Get key metadata
keyInfo, err := client.GetKey(ctx, "key-id")

// Get typed key client
keyClient, err := client.GetRSAKey(ctx, "my-key")

// Find issuers using this key
issuers, err := keyClient.GetIssuers(ctx)

// Delete key
err := client.DeleteKey(ctx, "key-id")
Issuer Operations
Create CA
// Root CA
caResp, err := client.GenerateRootCA(ctx, &bao.CAOptions{
    Type:       "internal",
    CommonName: "My Root CA",
    KeyType:    "rsa",
    KeyBits:    4096,
    KeyName:    "my-ca-key",
    IssuerName: "my-ca",
    TTL:        "87600h",
})

// Intermediate CA
intermediateResp, err := client.GenerateIntermediateCA(ctx, &bao.CAOptions{
    Type:       "exported",
    CommonName: "My Intermediate CA",
    KeyType:    "rsa",
    KeyBits:    2048,
    IssuerName: "my-intermediate",
    TTL:        "43800h",
})
Issuer Operations
// List issuers
issuers, err := client.ListIssuers(ctx)

// Get issuer
issuer, err := client.GetIssuer(ctx, "issuer-id")

// Set default issuer
err := issuer.SetAsDefault(ctx)

// Update issuer
err := issuer.UpdateName(ctx, "new-name")
err := issuer.UpdateUsage(ctx, "read-only,issuing-certificates")

// Create role under issuer
role, err := issuer.CreateRole(ctx, "web-server", &bao.RoleOptions{
    AllowedDomains: []string{"example.com"},
    TTL:            "720h",
})

// Issue certificate from issuer
certClient, err := issuer.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
    })

// Sign CSR
cert, err := issuer.SignCSR(ctx, csr, &bao.SignCertificateOptions{
    TTL: "720h",
})

// Delete issuer
err := issuer.Delete(ctx)
Role Operations
Create and Manage Roles
// Create role
err := client.CreateRole(ctx, "web-server", &bao.RoleOptions{
    AllowedDomains:  []string{"example.com"},
    AllowSubdomains: true,
    TTL:             "720h",
    MaxTTL:          "8760h",
    ServerFlag:      true,
})

// Get role
role, err := client.GetRole(ctx, "web-server")

// List roles
roles, err := client.ListRoles(ctx)

// Update role using builder
err = role.Update(ctx, 
    bao.NewRoleOptionsBuilder().
        WithTTL("1440h").
        WithAllowedDomains("example.com", "example.org").
        WithServerFlag(true).
        WithClientFlag(true).
        Build())

// Delete role
err := role.Delete(ctx)
Role Navigation
// Get issuer for this role
issuer, err := role.GetIssuer(ctx)

// Issue certificate using role
certClient, err := role.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
        TTL:        "720h",
    })
Certificate Operations
Issue Certificates
// Using role (with existing key)
certClient, err := client.IssueRSACertificateWithKeyRef(ctx, "web-server", "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
        AltNames:   []string{"www.example.com"},
        TTL:        "720h",
    })

// Generate new key and certificate together
certClient, err := client.GenerateRSACertificate(ctx, "web-server",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
        TTL:        "720h",
    })
Sign CSR
// Create CSR locally
rsaKeyPair, _ := algo.GenerateRSAKeyPair(2048)
csr, _ := cert.CreateCSR(rsaKeyPair, cert.CSRRequest{
    Subject: cert.SubjectInfo{
        CommonName: "app.example.com",
    },
})

// Sign with OpenBao
certificate, err := client.SignCSR(ctx, "web-server", csr,
    &bao.SignCertificateOptions{
        TTL: "720h",
    })
Certificate Operations
// Get certificate
certClient, err := client.GetRSACertificate(ctx, "serial-number")

// Access certificate
cert := certClient.Certificate()
certInfo := certClient.CertificateInfo()

// Access key pair (if available)
if certClient.HasKeyPair() {
    keyPair, err := certClient.KeyPair()
}

// Revoke certificate
err := certClient.Revoke(ctx)

Relationship-Based APIs

The bao package provides fluent APIs for navigating between related resources:

From Key to Issuers
// Find all CAs using a specific key
keyClient, _ := client.GetRSAKey(ctx, "my-key")
issuers, err := keyClient.GetIssuers(ctx)

for _, issuer := range issuers {
    fmt.Printf("Issuer: %s (ID: %s)\n", issuer.Name(), issuer.ID())
}
From Issuer to Roles and Certificates
issuer, _ := client.GetIssuer(ctx, "my-ca")

// Create role under this issuer
role, err := issuer.CreateRole(ctx, "api-server", &bao.RoleOptions{
    AllowedDomains: []string{"api.example.com"},
    TTL:            "720h",
})

// Issue certificate directly from issuer
certClient, err := issuer.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "api.example.com",
    })
From Role to Issuer and Certificates
role, _ := client.GetRole(ctx, "web-server")

// Get the issuer for this role
issuer, err := role.GetIssuer(ctx)
fmt.Printf("Role uses issuer: %s\n", issuer.Name())

// Issue certificate using role
certClient, err := role.IssueRSACertificate(ctx, "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
    })
Complete Workflow Example
// 1. Start with a key
keyClient, _ := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-ca-key",
    KeyBits: 4096,
})

// 2. Create CA using that key
caResp, _ := client.GenerateRootCA(ctx, &bao.CAOptions{
    Type:       "internal",
    CommonName: "My CA",
    KeyName:    "my-ca-key",
    IssuerName: "my-ca",
})

// 3. Get issuer and create role
issuer, _ := client.GetIssuer(ctx, caResp.IssuerID)
role, _ := issuer.CreateRole(ctx, "web-server", &bao.RoleOptions{
    AllowedDomains: []string{"example.com"},
    TTL:            "720h",
})

// 4. Issue certificate using role
certClient, _ := role.IssueRSACertificate(ctx, "app-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
    })

// 5. Navigate back
roleIssuer, _ := role.GetIssuer(ctx)
keyIssuers, _ := keyClient.GetIssuers(ctx)

fmt.Printf("Role's issuer: %s\n", roleIssuer.Name())
fmt.Printf("Key is used by %d issuer(s)\n", len(keyIssuers))

Complete Examples

Example 1: Simple CA Setup
ctx := context.Background()

// Connect
client, _ := bao.NewClient(&bao.Config{
    Address: "http://localhost:8200",
    Token:   "root-token",
    Mount:   "pki",
})

// Generate CA
caResp, _ := client.GenerateRootCA(ctx, &bao.CAOptions{
    Type:       "internal",
    CommonName: "My Root CA",
    KeyType:    "rsa",
    KeyBits:    4096,
    IssuerName: "root-ca",
    TTL:        "87600h",
})

fmt.Printf("CA Created: %s\n", caResp.Certificate.Subject.CommonName)
Example 2: Certificate Issuance with Role
ctx := context.Background()
client, _ := bao.NewClient(&bao.Config{...})

// Create role
err := client.CreateRole(ctx, "web-server", &bao.RoleOptions{
    AllowedDomains:  []string{"example.com"},
    AllowSubdomains: true,
    TTL:             "720h",
    ServerFlag:      true,
})

// Issue certificate
certClient, _ := client.IssueRSACertificateWithKeyRef(ctx, "web-server", "my-key",
    &bao.GenerateCertificateOptions{
        CommonName: "app.example.com",
        AltNames:   []string{"www.example.com", "api.example.com"},
        TTL:        "720h",
    })

cert := certClient.Certificate()
fmt.Printf("Certificate issued: %s\n", cert.Subject.CommonName)
Example 3: CSR-Based Workflow (Maximum Security)
ctx := context.Background()
client, _ := bao.NewClient(&bao.Config{...})

// 1. Generate key locally (never leaves your system)
rsaKeyPair, _ := algo.GenerateRSAKeyPair(2048)

// 2. Create CSR locally
csr, _ := cert.CreateCSR(rsaKeyPair, cert.CSRRequest{
    Subject: cert.SubjectInfo{
        CommonName:   "app.example.com",
        Organization: []string{"My Company"},
    },
    DNSNames: []string{"www.example.com"},
})

// 3. Sign CSR with OpenBao (only CSR is sent, not private key)
certificate, _ := client.SignCSR(ctx, "web-server", csr,
    &bao.SignCertificateOptions{
        TTL: "720h",
    })

fmt.Printf("Certificate signed: %s\n", certificate.Subject.CommonName)
// Private key never left your system!
Example 4: Relationship Navigation
ctx := context.Background()
client, _ := bao.NewClient(&bao.Config{...})

// Start with a role
role, _ := client.GetRole(ctx, "web-server")

// Navigate to issuer
issuer, _ := role.GetIssuer(ctx)
fmt.Printf("Role uses issuer: %s\n", issuer.Name())

// Get key info
keyID := issuer.KeyID()
fmt.Printf("Issuer uses key: %s\n", keyID)

// Get key and find all its issuers
keyClient, _ := client.GetRSAKey(ctx, keyID)
issuers, _ := keyClient.GetIssuers(ctx)
fmt.Printf("Key is used by %d issuer(s)\n", len(issuers))

GoPKI Integration

The bao/pki module is fully integrated with gopki's ecosystem, providing seamless compatibility with all gopki modules.

Manager Pattern Integration

Access gopki's powerful Manager pattern for advanced key operations:

// Generate key with Manager support
keyClient, _ := client.GenerateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-key",
    KeyBits: 2048,
})

// Get Manager for advanced operations
manager, _ := keyClient.Manager()

// Save with secure permissions (0600 for private, 0644 for public)
manager.SaveToPEM("private.pem", "public.pem")

// Convert to SSH format
sshPriv, sshPub, _ := manager.ToSSH("user@host", "")

// Convert to DER format
privateDER, publicDER, _ := manager.ToDER()
Import from gopki Manager

Seamlessly import keys managed by gopki:

// Generate with gopki's Manager
import (
    "github.com/jasoet/gopki/keypair"
    "github.com/jasoet/gopki/keypair/algo"
)

manager, _ := keypair.Generate[algo.KeySize2048, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)

// Import into OpenBao
keyClient, err := client.ImportRSAKeyFromManager(ctx, manager, &bao.ImportKeyOptions{
    KeyName: "gopki-managed-key",
})
Format Conversion

Easy conversion between different formats:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &bao.GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

// Export as PEM
certPEM, keyPEM, _ := certClient.ExportPEM()

// Save to files with secure permissions
certClient.SaveToFiles("cert.pem", "key.pem")

// Save certificate chain
certClient.SaveCertificateChain("cert-chain.pem")

// Convert certificate to DER
derBytes, _ := certClient.ToDER()
Signing Integration

Direct integration with gopki's signing module:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &bao.GenerateCertificateOptions{
    CommonName: "app.example.com",
})

// Sign document
document := []byte("Important contract")
signature, err := certClient.Sign(document, signing.DefaultSignOptions())

// Create detached signature
detachedSig, _ := certClient.SignDetached(document, signing.DefaultSignOptions())

// Verify signature
err = certClient.Verify(document, signature, signing.DefaultVerifyOptions())
Encryption Integration

Direct integration with gopki's encryption module:

// Encrypt for a certificate's public key
certClient, _ := client.GetRSACertificate(ctx, "serial-number")
encrypted, _ := certClient.Encrypt([]byte("Secret message"), encryption.DefaultEncryptOptions())

// Decrypt with private key (requires key pair available)
certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &bao.GenerateCertificateOptions{...})
decrypted, _ := certClient.Decrypt(encrypted, encryption.DefaultDecryptOptions())
CSR Creation

Create CSRs for certificate renewal:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &bao.GenerateCertificateOptions{...})

// Create CSR using existing certificate info
csrReq := cert.CSRRequest{
    Subject:  certClient.Certificate().Certificate.Subject,
    DNSNames: []string{"app.example.com", "www.app.example.com"},
}
csr, err := certClient.CreateCSR(csrReq)

// Sign the CSR with OpenBao
newCert, _ := client.SignCSR(ctx, "web-server", csr, &bao.SignCertificateOptions{
    TTL: "8760h",
})
Complete Workflow Example

Combining OpenBao PKI with gopki modules:

import (
    "github.com/jasoet/gopki/bao/pki"
    "github.com/jasoet/gopki/signing"
    "github.com/jasoet/gopki/encryption"
)

// 1. Generate certificate with OpenBao
certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &pki.GenerateCertificateOptions{
    CommonName: "app.example.com",
    AltNames:   []string{"www.app.example.com"},
    TTL:        "720h",
})

// 2. Get Manager for key operations
manager, _ := certClient.Manager()

// 3. Save in multiple formats
manager.SaveToPEM("key.pem", "key.pub")
sshPriv, sshPub, _ := manager.ToSSH("user@host", "")
os.WriteFile("id_rsa", sshPriv, 0600)
os.WriteFile("id_rsa.pub", sshPub, 0644)

// 4. Save certificate
certClient.SaveToFiles("cert.pem", "cert-key.pem")
certClient.SaveCertificateChain("cert-chain.pem")

// 5. Use for signing
document := []byte("Contract v1.0")
signature, _ := certClient.Sign(document, signing.DefaultSignOptions())

// 6. Use for encryption
secret := []byte("API Key: secret123")
encrypted, _ := certClient.Encrypt(secret, encryption.DefaultEncryptOptions())

// 7. Decrypt
decrypted, _ := certClient.Decrypt(encrypted, encryption.DefaultDecryptOptions())

fmt.Printf("Decrypted: %s\n", decrypted)
Key Operations

Advanced key management with gopki integration:

keyClient, _ := client.GenerateRSAKey(ctx, &pki.GenerateKeyOptions{
    KeyName: "advanced-key",
    KeyBits: 4096,
})

// Get Manager
manager, _ := keyClient.Manager()

// Save in multiple formats simultaneously
manager.SaveToPEM("private.pem", "public.pem")
privateDER, publicDER, _ := manager.ToDER()
sshPriv, sshPub, _ := manager.ToSSH("[email protected]", "")

// Or use convenience methods directly on KeyClient
keyClient.SaveKeyPairToFiles("key-private.pem", "key-public.pem")
sshPriv, sshPub, _ = keyClient.ToSSH("user@host", "")
privateDER, publicDER, _ = keyClient.ToDER()
Benefits of Integration
  1. Consistent API: Use familiar gopki patterns with OpenBao
  2. No Boilerplate: Direct method access without manual conversions
  3. Type Safety: Compile-time guarantees across all operations
  4. Secure Defaults: Automatic secure file permissions (0600 for keys)
  5. Format Flexibility: Easy conversion between PEM, DER, SSH, PKCS#12
  6. Full Feature Access: All gopki signing and encryption capabilities

Testing

Unit Tests
go test ./bao -v
Integration Tests

Integration tests use testcontainers to spin up a real OpenBao instance:

go test ./bao -tags=integration -v
Cross-Module Integration Tests

Tests that verify relationship navigation and complex workflows:

go test ./bao -tags=integration -run TestCrossModule -v
Writing Tests

Example integration test:

func TestMyFeature(t *testing.T) {
    // Setup OpenBao container
    ctx := context.Background()
    baoContainer, err := testcontainer.SetupOpenBao(ctx)
    require.NoError(t, err)
    defer testcontainer.TeardownOpenBao(ctx, baoContainer)
    
    // Get client
    client := baoContainer.Client
    
    // Your test code here
    keyClient, err := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{
        KeyName: "test-key",
        KeyBits: 2048,
    })
    require.NoError(t, err)
    assert.NotNil(t, keyClient)
}

Advanced Topics

Builder Pattern for Roles

Use RoleOptionsBuilder for complex role configurations:

opts := bao.NewRoleOptionsBuilder().
    WithIssuerRef("my-ca").
    WithTTL("720h").
    WithMaxTTL("8760h").
    WithAllowedDomains("example.com", "example.org").
    WithAllowSubdomains(true).
    WithAllowWildcardCertificates(true).
    WithServerFlag(true).
    WithClientFlag(true).
    WithKeyType("rsa").
    WithKeyBits(2048).
    WithOrganization("My Company").
    WithCountry("US").
    Build()

err := client.CreateRole(ctx, "my-role", opts)
Error Handling

The package provides helper functions for error classification:

cert, err := client.GetRSACertificate(ctx, "serial")
if err != nil {
    if bao.IsNotFoundError(err) {
        fmt.Println("Certificate not found")
    } else if bao.IsAuthError(err) {
        fmt.Println("Authentication failed")
    } else if bao.IsRetryable(err) {
        fmt.Println("Temporary error, retry later")
    } else {
        fmt.Printf("Other error: %v\n", err)
    }
}
Type Safety Benefits

The generic-based API prevents common mistakes:

// Compile-time error: can't mix RSA and ECDSA
rsaKey, _ := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{...})
ecdsaCert, _ := client.IssueECDSACertificate(ctx, ...) // Different types

// This works: types match
rsaKey, _ := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{...})
rsaCert, _ := client.IssueRSACertificate(ctx, ...)
keyPair, _ := rsaCert.KeyPair() // Returns *algo.RSAKeyPair

Best Practices

  1. Use CSR Workflow for Maximum Security: Keep private keys local, only send CSRs to OpenBao
  2. Leverage Relationships: Use fluent APIs to navigate between related resources
  3. Use Roles for Policies: Define certificate constraints in roles, not in each request
  4. Type Safety: Use typed methods (IssueRSACertificate) over generic ones
  5. Error Handling: Use helper functions (IsNotFoundError, etc.) for robust error handling
  6. Builder Pattern: Use RoleOptionsBuilder for complex role configurations
  7. Integration Tests: Use testcontainers for reliable integration testing

Contributing

Contributions are welcome! Please ensure:

  • All tests pass
  • Integration tests are included for new features
  • Documentation is updated
  • Code follows existing patterns

License

See LICENSE file in the repository root.

Documentation

Overview

Package vault provides integration with Vault/OpenBao PKI secrets engine. It enables seamless interaction between GoPKI's type-safe cryptographic operations and centralized PKI management via Vault/OpenBao.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Authentication and authorization errors
	ErrUnauthorized     = errors.New("bao: authentication failed")
	ErrPermissionDenied = errors.New("bao: permission denied")

	// Connection errors
	ErrTimeout           = errors.New("bao: operation timeout")
	ErrHealthCheckFailed = errors.New("bao: health check failed")

	// Mount errors
	ErrMountNotFound = errors.New("bao: PKI mount not found")
)

Predefined errors for common OpenBao operations. These can be checked using errors.Is().

Functions

func IsAuthError

func IsAuthError(err error) bool

IsAuthError returns true if the error is an authentication error.

func IsNotFoundError

func IsNotFoundError(err error) bool

IsNotFoundError returns true if the error indicates a resource was not found.

func ParseCertificateFromDER added in v1.22.0

func ParseCertificateFromDER(derData []byte) (*cert.Certificate, error)

ParseCertificateFromDER parses a DER-encoded certificate.

Example:

derData, _ := os.ReadFile("cert.der")
goPKICert, err := pki.ParseCertificateFromDER(derData)

func ParseCertificateFromPEM added in v1.22.0

func ParseCertificateFromPEM(pemData []byte) (*cert.Certificate, error)

ParseCertificateFromPEM is a helper to parse a PEM-encoded certificate. This is useful when working with certificates from external sources.

Example:

pemData, _ := os.ReadFile("cert.pem")
goPKICert, err := pki.ParseCertificateFromPEM(pemData)

Types

type CABundle

type CABundle struct {
	PEMBundle string // PEM bundle containing certificate(s) and optionally private key
}

CABundle contains a CA certificate bundle for import.

type CAOptions

type CAOptions struct {
	Type                string   // "internal" (OpenBao generates key) or "exported" (returns private key/CSR)
	CommonName          string   // Required
	Organization        []string // Optional
	Country             []string // Optional
	Locality            []string // Optional
	Province            []string // Optional
	StreetAddress       []string // Optional
	PostalCode          []string // Optional
	TTL                 string   // Time to live (e.g., "8760h" for 1 year)
	KeyType             string   // "rsa", "ec", "ed25519"
	KeyBits             int      // Key size (RSA: 2048/3072/4096, EC: 224/256/384/521)
	MaxPathLength       int      // Max depth of intermediate CAs (-1 = no limit, 0 = can only sign end-entity certs)
	ExcludeCNFromSANs   bool     // Exclude CN from SANs
	PermittedDNSDomains []string // Permitted DNS domains
	URISANs             []string // URI SANs
	IPSANs              []string // IP SANs
	AltNames            []string // DNS SANs
	IssuerName          string   // Name for the issuer
	KeyName             string   // Name for the key
	ManagedKeyName      string   // Name of managed key to use
	ManagedKeyID        string   // ID of managed key to use
	AddBasicConstraints bool     // Add basic constraints (for intermediate CAs)
}

CAOptions contains parameters for generating a CA certificate (root or intermediate).

type CAOptionsBuilder

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

CAOptionsBuilder provides a fluent API for building CAOptions.

func NewIntermediateCABuilder

func NewIntermediateCABuilder(commonName string) *CAOptionsBuilder

NewIntermediateCABuilder creates a new builder for intermediate CA options.

func NewRootCABuilder

func NewRootCABuilder(commonName string) *CAOptionsBuilder

NewRootCABuilder creates a new builder for root CA options.

func (*CAOptionsBuilder) AsExported

func (b *CAOptionsBuilder) AsExported() *CAOptionsBuilder

AsExported sets the type to "exported" (returns private key).

func (*CAOptionsBuilder) Build

func (b *CAOptionsBuilder) Build() *CAOptions

Build returns the built CAOptions.

func (*CAOptionsBuilder) WithAltNames

func (b *CAOptionsBuilder) WithAltNames(names ...string) *CAOptionsBuilder

WithAltNames sets alternative names.

func (*CAOptionsBuilder) WithCountry

func (b *CAOptionsBuilder) WithCountry(country ...string) *CAOptionsBuilder

WithCountry sets the country.

func (*CAOptionsBuilder) WithIssuerName

func (b *CAOptionsBuilder) WithIssuerName(name string) *CAOptionsBuilder

WithIssuerName sets the issuer name.

func (*CAOptionsBuilder) WithKeyName

func (b *CAOptionsBuilder) WithKeyName(name string) *CAOptionsBuilder

WithKeyName sets the key name.

func (*CAOptionsBuilder) WithKeyType

func (b *CAOptionsBuilder) WithKeyType(keyType string, bits int) *CAOptionsBuilder

WithKeyType sets the key type and bits.

func (*CAOptionsBuilder) WithLocality

func (b *CAOptionsBuilder) WithLocality(locality ...string) *CAOptionsBuilder

WithLocality sets the locality.

func (*CAOptionsBuilder) WithMaxPathLength

func (b *CAOptionsBuilder) WithMaxPathLength(length int) *CAOptionsBuilder

WithMaxPathLength sets the maximum path length for certificate chains.

func (*CAOptionsBuilder) WithOrganization

func (b *CAOptionsBuilder) WithOrganization(org ...string) *CAOptionsBuilder

WithOrganization sets the organization.

func (*CAOptionsBuilder) WithPermittedDNSDomains

func (b *CAOptionsBuilder) WithPermittedDNSDomains(domains ...string) *CAOptionsBuilder

WithPermittedDNSDomains sets permitted DNS domains.

func (*CAOptionsBuilder) WithProvince

func (b *CAOptionsBuilder) WithProvince(province ...string) *CAOptionsBuilder

WithProvince sets the province.

func (*CAOptionsBuilder) WithTTL

func (b *CAOptionsBuilder) WithTTL(ttl string) *CAOptionsBuilder

WithTTL sets the TTL.

type CertificateClient

type CertificateClient[K keypair.KeyPair] struct {
	// contains filtered or unexported fields
}

CertificateClient provides type-safe certificate operations for OpenBao PKI. It uses generics to ensure compile-time type safety for certificate and key operations.

Type parameter:

  • K: KeyPair type constraint (keypair.KeyPair)

Supported types:

  • *algo.RSAKeyPair
  • *algo.ECDSAKeyPair
  • *algo.Ed25519KeyPair

The keyPair field is populated when:

  • Certificate is issued with GenerateXXXCertificate() (OpenBao generates key)
  • Certificate is issued with IssueXXXCertificate() (local key used)

The keyPair field is nil when:

  • Certificate is signed with SignCSR() (key not provided)
  • Certificate is retrieved with GetCertificate() (only metadata available)

func (*CertificateClient[K]) Certificate

func (cc *CertificateClient[K]) Certificate() *cert.Certificate

Certificate returns the certificate.

func (*CertificateClient[K]) CertificateInfo

func (cc *CertificateClient[K]) CertificateInfo() *CertificateInfo

CertificateInfo returns the certificate metadata.

func (*CertificateClient[K]) CreateCSR added in v1.22.0

CreateCSR creates a new Certificate Signing Request from the certificate's subject information. This is useful for renewing certificates or creating subordinate certificates. Returns an error if the key pair is not available.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
csrReq := cert.CSRRequest{
    Subject: certClient.Certificate().Certificate.Subject,
    DNSNames: []string{"app.example.com", "www.app.example.com"},
}
csr, err := certClient.CreateCSR(csrReq)

func (*CertificateClient[K]) ExportPEM added in v1.22.0

func (cc *CertificateClient[K]) ExportPEM() (certPEM, keyPEM []byte, err error)

ExportPEM exports both certificate and private key as PEM bytes. Returns an error if the key pair is not available.

This is useful for saving certificate bundles or transmitting them securely.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
certPEM, keyPEM, err := certClient.ExportPEM()
if err != nil {
    // Key not available
}

func (*CertificateClient[K]) HasKeyPair

func (cc *CertificateClient[K]) HasKeyPair() bool

HasKeyPair returns true if the key pair is cached and available.

func (*CertificateClient[K]) IsExpired added in v1.22.0

func (cc *CertificateClient[K]) IsExpired() bool

IsExpired checks if the certificate has expired.

Example:

certClient, _ := client.GetRSACertificate(ctx, "serial-number")
if certClient.IsExpired() {
    fmt.Println("Certificate has expired")
}

func (*CertificateClient[K]) KeyPair

func (cc *CertificateClient[K]) KeyPair() (K, error)

KeyPair returns the cached key pair if available. Returns an error if the key pair is not cached (e.g., certificate was signed without key generation).

The key pair is available when:

  • Certificate was issued with GenerateXXXCertificate() (OpenBao generated key)
  • Certificate was issued with IssueXXXCertificate() (local key used)

The key pair is NOT available when:

  • Certificate was signed with SignCSR() (key not included)
  • Certificate was retrieved with GetCertificate() (only metadata retrieved)

Example:

certClient, err := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
keyPair, err := certClient.KeyPair()  // Returns the keypair
// Use keyPair.PrivateKey, keyPair.PublicKey

func (*CertificateClient[K]) PublicKeyAlgorithm added in v1.22.0

func (cc *CertificateClient[K]) PublicKeyAlgorithm() string

PublicKeyAlgorithm returns the public key algorithm of the certificate.

Example:

certClient, _ := client.GetRSACertificate(ctx, "serial-number")
algo := certClient.PublicKeyAlgorithm()
fmt.Printf("Algorithm: %s\n", algo) // "RSA", "ECDSA", or "Ed25519"

func (*CertificateClient[K]) Revoke

func (cc *CertificateClient[K]) Revoke(ctx context.Context) error

Revoke revokes this certificate.

Example:

certClient, _ := client.GetCertificate(ctx, "11:22:33:44:55")
err := certClient.Revoke(ctx)

func (*CertificateClient[K]) RevokeWithKey

func (cc *CertificateClient[K]) RevokeWithKey(ctx context.Context) error

RevokeWithKey revokes this certificate using its private key.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
err := certClient.RevokeWithKey(ctx)

func (*CertificateClient[K]) SaveCertificate added in v1.22.0

func (cc *CertificateClient[K]) SaveCertificate(path string) error

SaveCertificate saves the certificate to a file in PEM format. The certificate is saved with 0644 permissions.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
err := certClient.SaveCertificate("cert.pem")

func (*CertificateClient[K]) SaveToFiles added in v1.22.0

func (cc *CertificateClient[K]) SaveToFiles(certPath, keyPath string) error

SaveToFiles saves the certificate and private key to separate files. The certificate is saved with 0644 permissions, and the private key with secure 0600 permissions. Returns an error if the key pair is not available.

This follows gopki's security best practices for file permissions.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
err := certClient.SaveToFiles("cert.pem", "key.pem")

func (*CertificateClient[K]) SerialNumber added in v1.22.0

func (cc *CertificateClient[K]) SerialNumber() string

SerialNumber returns the certificate's serial number.

Example:

certClient, _ := client.GetRSACertificate(ctx, "serial-number")
serial := certClient.SerialNumber()

func (*CertificateClient[K]) ToDER added in v1.22.0

func (cc *CertificateClient[K]) ToDER() ([]byte, error)

ToDER converts the certificate to DER format. Returns the certificate in DER-encoded bytes.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
derBytes, err := certClient.ToDER()
os.WriteFile("cert.der", derBytes, 0644)

func (*CertificateClient[K]) ToPEM added in v1.22.0

func (cc *CertificateClient[K]) ToPEM() ([]byte, error)

ToPEM converts the certificate to PEM format. Returns the certificate in PEM-encoded bytes.

Example:

certClient, _ := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{...})
pemBytes, err := certClient.ToPEM()
os.WriteFile("cert.pem", pemBytes, 0644)

type CertificateInfo

type CertificateInfo struct {
	SerialNumber   string    // Certificate serial number
	Expiration     time.Time // Certificate expiration time
	Revoked        bool      // Whether the certificate is revoked
	RevocationTime int64     // Revocation time (Unix timestamp)
}

CertificateInfo represents certificate metadata from OpenBao.

type Client

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

Client represents an OpenBao PKI client.

func NewClient

func NewClient(config *Config) (*Client, error)

NewClient creates a new OpenBao client using the OpenBao SDK. The client validates the configuration and establishes connection settings.

Example:

client, err := bao.NewClient(&bao.Config{
    Address: "https://openbao.example.com",
    Token:   os.Getenv("BAO_TOKEN"),
    Mount:   "pki",
})

func (*Client) Close

func (c *Client) Close() error

Close closes the client and releases resources. This is a no-op for HTTP clients but included for future extensibility.

func (*Client) Config

func (c *Client) Config() *Config

Config returns the client configuration.

func (*Client) CreateECDSAKey

func (c *Client) CreateECDSAKey(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.ECDSAKeyPair], error)

CreateECDSAKey creates an ECDSA key in OpenBao without returning the private key. The key is stored securely in OpenBao and cannot be retrieved later.

Example:

keyClient, err := client.CreateECDSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-managed-ec-key",
    KeyBits: 256,
})

func (*Client) CreateEd25519Key

func (c *Client) CreateEd25519Key(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.Ed25519KeyPair], error)

CreateEd25519Key creates an Ed25519 key in OpenBao without returning the private key. The key is stored securely in OpenBao and cannot be retrieved later.

Example:

keyClient, err := client.CreateEd25519Key(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-managed-ed25519-key",
})

func (*Client) CreateRSAKey

func (c *Client) CreateRSAKey(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.RSAKeyPair], error)

CreateRSAKey creates an RSA key in OpenBao without returning the private key. The key is stored securely in OpenBao and cannot be retrieved later. Use this when you want OpenBao to manage the key internally (e.g., for signing operations).

Example:

keyClient, err := client.CreateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-managed-rsa-key",
    KeyBits: 2048,
})
// Key is stored in OpenBao, use keyClient for operations

func (*Client) CreateRole

func (c *Client) CreateRole(ctx context.Context, name string, opts *RoleOptions) error

CreateRole creates or updates a role in OpenBao. Roles define policies for certificate issuance.

Example:

err := client.CreateRole(ctx, "web-server", &bao.RoleOptions{
   TTL:              "720h",
   MaxTTL:           "8760h",
   AllowedDomains:   []string{"example.com"},
   AllowSubdomains:  true,
   ServerFlag:       true,
   KeyType:          "rsa",
   KeyBits:          2048,
})

func (*Client) DeleteIssuer

func (c *Client) DeleteIssuer(ctx context.Context, issuerRef string) error

DeleteIssuer deletes an issuer from Vault. Note: This will fail if the issuer is the default issuer.

Example:

err := client.DeleteIssuer(ctx, "issuer-id")

func (*Client) DeleteKey

func (c *Client) DeleteKey(ctx context.Context, keyRef string) error

DeleteKey deletes a key from OpenBao by ID or name.

Example:

err := client.DeleteKey(ctx, "key-id")

func (*Client) DeleteRole

func (c *Client) DeleteRole(ctx context.Context, name string) error

DeleteRole deletes a role from OpenBao.

Example:

err := client.DeleteRole(ctx, "web-server")

func (*Client) GenerateECDSACertificate

func (c *Client) GenerateECDSACertificate(ctx context.Context, role string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.ECDSAKeyPair], error)

GenerateECDSACertificate generates an ECDSA certificate with OpenBao creating the key pair.

func (*Client) GenerateECDSAKey

func (c *Client) GenerateECDSAKey(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.ECDSAKeyPair], error)

GenerateECDSAKey generates an ECDSA key and returns a KeyClient with the key pair cached. The key is also stored in OpenBao for future use. Access the keypair using keyClient.KeyPair().

Example:

keyClient, err := client.GenerateECDSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-ec-key",
    KeyBits: 256,
})
keyPair, err := keyClient.KeyPair()  // Get the cached keypair

func (*Client) GenerateEd25519Certificate

func (c *Client) GenerateEd25519Certificate(ctx context.Context, role string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.Ed25519KeyPair], error)

GenerateEd25519Certificate generates an Ed25519 certificate with OpenBao creating the key pair.

func (*Client) GenerateEd25519Key

func (c *Client) GenerateEd25519Key(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.Ed25519KeyPair], error)

GenerateEd25519Key generates an Ed25519 key and returns a KeyClient with the key pair cached. The key is also stored in OpenBao for future use. Access the keypair using keyClient.KeyPair().

Example:

keyClient, err := client.GenerateEd25519Key(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-ed25519-key",
})
keyPair, err := keyClient.KeyPair()  // Get the cached keypair

func (*Client) GenerateIntermediateCA

func (c *Client) GenerateIntermediateCA(ctx context.Context, opts *CAOptions) (*GenerateCAResponse, error)

GenerateIntermediateCA generates an intermediate CA certificate. The type can be "internal" (Vault generates and stores the key) or "exported" (returns CSR).

For "internal" type, the intermediate CA is generated and signed immediately. For "exported" type, a CSR is returned which must be signed separately.

Example:

intermediate, err := client.GenerateIntermediateCA(ctx, &bao.CAOptions{
    Type:                "internal",
    CommonName:          "Example Intermediate CA",
    Organization:        []string{"Example Org"},
    TTL:                 "43800h", // 5 years
    KeyType:             "rsa",
    KeyBits:             2048,
    AddBasicConstraints: true,
})

func (*Client) GenerateRSACertificate

func (c *Client) GenerateRSACertificate(ctx context.Context, role string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.RSAKeyPair], error)

GenerateRSACertificate generates an RSA certificate with OpenBao creating the key pair. The private key is returned and cached in the CertificateClient.

Example:

certClient, err := client.GenerateRSACertificate(ctx, "web-server", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    AltNames:   []string{"www.app.example.com"},
    TTL:        "720h",
})
keyPair, _ := certClient.KeyPair()  // Get the generated keypair

func (*Client) GenerateRSAKey

func (c *Client) GenerateRSAKey(ctx context.Context, opts *GenerateKeyOptions) (*KeyClient[*algo.RSAKeyPair], error)

GenerateRSAKey generates an RSA key and returns a KeyClient with the key pair cached. The key is also stored in OpenBao for future use. Access the keypair using keyClient.KeyPair().

Example:

keyClient, err := client.GenerateRSAKey(ctx, &bao.GenerateKeyOptions{
    KeyName: "my-rsa-key",
    KeyBits: 2048,
})
keyPair, err := keyClient.KeyPair()  // Get the cached keypair
// Use keyPair.PrivateKey, keyPair.PublicKey immediately

func (*Client) GenerateRootCA

func (c *Client) GenerateRootCA(ctx context.Context, opts *CAOptions) (*GenerateCAResponse, error)

GenerateRootCA generates a self-signed root CA certificate in Vault. The type can be "internal" (Vault generates and stores the key) or "exported" (returns private key).

Example:

rootCA, err := client.GenerateRootCA(ctx, &vault.CAOptions{
    Type:         "internal",
    CommonName:   "Example Root CA",
    Organization: []string{"Example Org"},
    Country:      []string{"US"},
    TTL:          "87600h", // 10 years
    KeyType:      "rsa",
    KeyBits:      4096,
})

func (*Client) GetCertificate

func (c *Client) GetCertificate(ctx context.Context, serial string) (*cert.Certificate, error)

GetCertificate retrieves a certificate from OpenBao by serial number. Returns only the certificate without type-safe wrapper.

For type-safe operations, use GetRSACertificate(), GetECDSACertificate(), or GetEd25519Certificate().

Example:

certificate, err := client.GetCertificate(ctx, "39:dd:2e:90:b7:23:1f:8d")

func (*Client) GetDefaultIssuer

func (c *Client) GetDefaultIssuer(ctx context.Context) (string, error)

GetDefaultIssuer retrieves the default issuer ID for the PKI mount.

Example:

issuerID, err := client.GetDefaultIssuer(ctx)

func (*Client) GetECDSACertificate

func (c *Client) GetECDSACertificate(ctx context.Context, serial string) (*CertificateClient[*algo.ECDSAKeyPair], error)

GetECDSACertificate retrieves an ECDSA certificate from OpenBao and returns a type-safe CertificateClient. The returned CertificateClient does not have a cached key pair (HasKeyPair() will be false).

Note: This validates the certificate is ECDSA type at retrieval time.

Example:

certClient, err := client.GetECDSACertificate(ctx, "39:dd:2e:90:b7:23:1f:8d")
cert := certClient.Certificate()
err := certClient.Revoke(ctx)  // ✓ Works

func (*Client) GetECDSAKey

func (c *Client) GetECDSAKey(ctx context.Context, keyRef string) (*KeyClient[*algo.ECDSAKeyPair], error)

GetECDSAKey retrieves an ECDSA key reference from OpenBao and returns a type-safe KeyClient. Note: This only retrieves metadata. The private key material is not available unless the key was originally generated with GenerateECDSAKey or imported with ImportECDSAKey.

Example:

ecKeys, err := client.GetECDSAKey(ctx, "ec-key-id")
// Use ecKeys for operations like UpdateName(), Delete()

func (*Client) GetEd25519Certificate

func (c *Client) GetEd25519Certificate(ctx context.Context, serial string) (*CertificateClient[*algo.Ed25519KeyPair], error)

GetEd25519Certificate retrieves an Ed25519 certificate from OpenBao and returns a type-safe CertificateClient. The returned CertificateClient does not have a cached key pair (HasKeyPair() will be false).

Note: This validates the certificate is Ed25519 type at retrieval time.

Example:

certClient, err := client.GetEd25519Certificate(ctx, "39:dd:2e:90:b7:23:1f:8d")
cert := certClient.Certificate()
err := certClient.Revoke(ctx)  // ✓ Works

func (*Client) GetEd25519Key

func (c *Client) GetEd25519Key(ctx context.Context, keyRef string) (*KeyClient[*algo.Ed25519KeyPair], error)

GetEd25519Key retrieves an Ed25519 key reference from OpenBao and returns a type-safe KeyClient. Note: This only retrieves metadata. The private key material is not available unless the key was originally generated with GenerateEd25519Key or imported with ImportEd25519Key.

Example:

edKeys, err := client.GetEd25519Key(ctx, "ed25519-key-id")
// Use edKeys for operations like UpdateName(), Delete()

func (*Client) GetIssuer

func (c *Client) GetIssuer(ctx context.Context, issuerRef string) (*IssuerClient, error)

GetIssuer retrieves issuer information by ID or name and returns an IssuerClient.

Example:

issuerClient, err := client.GetIssuer(ctx, "issuer-id-or-name")
cert := issuerClient.Certificate()

func (*Client) GetKey

func (c *Client) GetKey(ctx context.Context, keyRef string) (*KeyInfo, error)

GetKey retrieves key metadata by ID or name (returns metadata only, not key material).

Example:

keyInfo, err := client.GetKey(ctx, "key-id-or-name")
fmt.Println(keyInfo.KeyType)  // "rsa", "ec", or "ed25519"

func (*Client) GetRSACertificate

func (c *Client) GetRSACertificate(ctx context.Context, serial string) (*CertificateClient[*algo.RSAKeyPair], error)

GetRSACertificate retrieves an RSA certificate from OpenBao and returns a type-safe CertificateClient. The returned CertificateClient does not have a cached key pair (HasKeyPair() will be false).

Note: This validates the certificate is RSA type at retrieval time.

Example:

certClient, err := client.GetRSACertificate(ctx, "39:dd:2e:90:b7:23:1f:8d")
cert := certClient.Certificate()
err := certClient.Revoke(ctx)  // ✓ Works
err := certClient.RevokeWithKey(ctx)  // ✗ Fails - no key pair cached

func (*Client) GetRSAKey

func (c *Client) GetRSAKey(ctx context.Context, keyRef string) (*KeyClient[*algo.RSAKeyPair], error)

GetRSAKey retrieves an RSA key reference from OpenBao and returns a type-safe KeyClient. Note: This only retrieves metadata. The private key material is not available unless the key was originally generated with GenerateRSAKey or imported with ImportRSAKey.

Example:

rsaKeys, err := client.GetRSAKey(ctx, "rsa-key-id")
// Use rsaKeys for operations like UpdateName(), Delete()

func (*Client) GetRole

func (c *Client) GetRole(ctx context.Context, name string) (*RoleClient, error)

GetRole retrieves role configuration by name and returns a RoleClient.

Example:

roleClient, err := client.GetRole(ctx, "web-server") ttl := roleClient.Options().TTL err = roleClient.SetTTL(ctx, "1440h")

func (*Client) Health

func (c *Client) Health(ctx context.Context) error

Health checks the health status of the OpenBao server. This performs a basic health check without requiring authentication.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

if err := client.Health(ctx); err != nil {
    log.Printf("OpenBao unhealthy: %v", err)
}

func (*Client) ImportCA

func (c *Client) ImportCA(ctx context.Context, bundle *CABundle) (*IssuerClient, error)

ImportCA imports an existing CA bundle into Vault. The bundle should contain the certificate and optionally the private key in PEM format.

Example:

issuerInfo, err := client.ImportCA(ctx, &vault.CABundle{
    PEMBundle: certificatePEM + privateKeyPEM,
})

func (*Client) ImportECDSAKey

func (c *Client) ImportECDSAKey(ctx context.Context, kp *algo.ECDSAKeyPair, opts *ImportKeyOptions) (*KeyClient[*algo.ECDSAKeyPair], error)

ImportECDSAKey imports an ECDSA key pair into OpenBao and returns a type-safe KeyClient.

Example:

ecKeyPair, _ := algo.GenerateECDSAKeyPair(algo.P256)
ecKeys, err := client.ImportECDSAKey(ctx, ecKeyPair, &bao.ImportKeyOptions{
    KeyName: "imported-ec-key",
})

func (*Client) ImportEd25519Key

func (c *Client) ImportEd25519Key(ctx context.Context, kp *algo.Ed25519KeyPair, opts *ImportKeyOptions) (*KeyClient[*algo.Ed25519KeyPair], error)

ImportEd25519Key imports an Ed25519 key pair into OpenBao and returns a type-safe KeyClient.

Example:

edKeyPair, _ := algo.GenerateEd25519KeyPair()
edKeys, err := client.ImportEd25519Key(ctx, edKeyPair, &bao.ImportKeyOptions{
    KeyName: "imported-ed25519-key",
})

func (*Client) ImportRSAKey

func (c *Client) ImportRSAKey(ctx context.Context, kp *algo.RSAKeyPair, opts *ImportKeyOptions) (*KeyClient[*algo.RSAKeyPair], error)

ImportRSAKey imports an RSA key pair into OpenBao and returns a type-safe KeyClient.

Example:

rsaKeyPair, _ := algo.GenerateRSAKeyPair(algo.KeySize2048)
rsaKeys, err := client.ImportRSAKey(ctx, rsaKeyPair, &bao.ImportKeyOptions{
    KeyName: "imported-rsa-key",
})

func (*Client) IssueECDSACertificate

func (c *Client) IssueECDSACertificate(ctx context.Context, role string, keyPair *algo.ECDSAKeyPair, opts *GenerateCertificateOptions) (*CertificateClient[*algo.ECDSAKeyPair], error)

IssueECDSACertificate issues a certificate using a locally generated ECDSA key pair.

func (*Client) IssueECDSACertificateWithKeyRef

func (c *Client) IssueECDSACertificateWithKeyRef(ctx context.Context, role string, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.ECDSAKeyPair], error)

IssueECDSACertificateWithKeyRef issues a certificate using an existing ECDSA key in OpenBao.

func (*Client) IssueEd25519Certificate

func (c *Client) IssueEd25519Certificate(ctx context.Context, role string, keyPair *algo.Ed25519KeyPair, opts *GenerateCertificateOptions) (*CertificateClient[*algo.Ed25519KeyPair], error)

IssueEd25519Certificate issues a certificate using a locally generated Ed25519 key pair.

func (*Client) IssueEd25519CertificateWithKeyRef

func (c *Client) IssueEd25519CertificateWithKeyRef(ctx context.Context, role string, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.Ed25519KeyPair], error)

IssueEd25519CertificateWithKeyRef issues a certificate using an existing Ed25519 key in OpenBao.

func (*Client) IssueRSACertificate

func (c *Client) IssueRSACertificate(ctx context.Context, role string, keyPair *algo.RSAKeyPair, opts *GenerateCertificateOptions) (*CertificateClient[*algo.RSAKeyPair], error)

IssueRSACertificate issues a certificate using a locally generated RSA key pair. The private key never leaves the local system - only a CSR is sent to OpenBao.

Example:

keyPair, _ := algo.GenerateRSAKeyPair(algo.KeySize2048)
certClient, err := client.IssueRSACertificate(ctx, "web-server", keyPair, &GenerateCertificateOptions{
    CommonName: "app.example.com",
    AltNames:   []string{"www.app.example.com"},
    TTL:        "720h",
})

func (*Client) IssueRSACertificateWithKeyRef

func (c *Client) IssueRSACertificateWithKeyRef(ctx context.Context, role string, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.RSAKeyPair], error)

IssueRSACertificateWithKeyRef issues a certificate using an existing RSA key in OpenBao. The key is referenced by ID or name and stays securely in OpenBao. OpenBao creates the CSR internally and signs the certificate.

The returned CertificateClient does NOT have a cached key pair (HasKeyPair() will be false).

Example:

// Key already exists in OpenBao
keyClient, _ := client.GenerateRSAKey(ctx, &GenerateKeyOptions{KeyName: "my-key"})
keyRef := keyClient.KeyInfo().KeyID  // or KeyName

// Issue certificate using that key
certClient, err := client.IssueRSACertificateWithKeyRef(ctx, "web-server", keyRef, &GenerateCertificateOptions{
    CommonName: "app.example.com",
    AltNames:   []string{"www.app.example.com"},
    TTL:        "720h",
})

func (*Client) ListCertificates

func (c *Client) ListCertificates(ctx context.Context) ([]string, error)

ListCertificates lists all certificate serial numbers in OpenBao.

Example:

serials, err := client.ListCertificates(ctx)
for _, serial := range serials {
    fmt.Println(serial)
}

func (*Client) ListIssuers

func (c *Client) ListIssuers(ctx context.Context) ([]string, error)

ListIssuers lists all issuer IDs in the PKI mount.

Example:

issuers, err := client.ListIssuers(ctx)
for _, issuerID := range issuers {
    fmt.Println(issuerID)
}

func (*Client) ListKeys

func (c *Client) ListKeys(ctx context.Context) ([]string, error)

ListKeys lists all key IDs in the PKI mount (all types).

Example:

keys, err := client.ListKeys(ctx)
for _, keyID := range keys {
    fmt.Println(keyID)
}

func (*Client) ListRoles

func (c *Client) ListRoles(ctx context.Context) ([]string, error)

ListRoles lists all role names in the PKI mount.

Example:

roles, err := client.ListRoles(ctx)

for _, roleName := range roles {
   fmt.Println(roleName)
}

func (*Client) Logical

func (c *Client) Logical() *api.Logical

Logical returns the SDK's Logical client for low-level API access. This allows advanced users to make custom API calls.

func (*Client) Ping

func (c *Client) Ping(ctx context.Context) error

Ping is an alias for Health for compatibility.

func (*Client) RevokeCertificate

func (c *Client) RevokeCertificate(ctx context.Context, serial string) error

RevokeCertificate revokes a certificate by serial number.

Example:

err := client.RevokeCertificate(ctx, "39:dd:2e:90:b7:23:1f:8d")

func (*Client) SetDefaultIssuer

func (c *Client) SetDefaultIssuer(ctx context.Context, issuerRef string) error

SetDefaultIssuer sets the default issuer for the PKI mount.

Example:

err := client.SetDefaultIssuer(ctx, "issuer-id")

func (*Client) SignCSR

SignCSR signs a Certificate Signing Request using OpenBao. This allows you to generate the key pair locally and only send the CSR to OpenBao for signing.

Example:

// Create CSR locally
keyPair, _ := algo.GenerateECDSAKeyPair(algo.P256)
csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{
    Subject: pkix.Name{CommonName: "service.example.com"},
})

// Sign with OpenBao
certificate, err := client.SignCSR(ctx, "web-server", csr, &SignCertificateOptions{
    TTL: "8760h", // 1 year
})

func (*Client) SignCSRWithKeyRef

func (c *Client) SignCSRWithKeyRef(ctx context.Context, role string, csr *cert.CertificateSigningRequest, keyRef string, opts *SignCertificateOptions) (*cert.Certificate, error)

SignCSRWithKeyRef signs a CSR using a specific key reference in OpenBao. The key is referenced by ID or name and used for signing the CSR.

Example:

keyClient, _ := client.GetRSAKey(ctx, "my-signing-key")
keyRef := keyClient.KeyInfo().KeyID

csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := client.SignCSRWithKeyRef(ctx, "web-server", csr, keyRef, &SignCertificateOptions{
    TTL: "8760h",
})

func (*Client) SignIntermediateCSR

func (c *Client) SignIntermediateCSR(ctx context.Context, csr *cert.CertificateSigningRequest, opts *CAOptions) (*cert.Certificate, error)

SignIntermediateCSR signs an intermediate CA CSR using the root CA.

Example:

certificate, err := client.SignIntermediateCSR(ctx, csr, &vault.CAOptions{
    CommonName: "Example Intermediate CA",
    TTL:        "43800h", // 5 years
})

func (*Client) SignSelfIssued

func (c *Client) SignSelfIssued(ctx context.Context, certificate *cert.Certificate, opts *SignSelfIssuedOptions) (*cert.Certificate, error)

SignSelfIssued signs a self-issued certificate. This is used for cross-signing scenarios where an intermediate CA needs to be signed by a different root.

Example:

certificate, err := client.SignSelfIssued(ctx, selfIssuedCert, &SignSelfIssuedOptions{
    RequireMatchingCertificateAlgorithms: true,
})

func (*Client) SignVerbatim

SignVerbatim signs a CSR verbatim without applying role constraints. This endpoint signs the CSR as-is, without enforcing role-based policies.

Example:

csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := client.SignVerbatim(ctx, csr, &SignVerbatimOptions{
    TTL: "8760h",
})

func (*Client) SignVerbatimWithKeyRef

func (c *Client) SignVerbatimWithKeyRef(ctx context.Context, csr *cert.CertificateSigningRequest, keyRef string, opts *SignVerbatimOptions) (*cert.Certificate, error)

SignVerbatimWithKeyRef signs a CSR verbatim using a specific key reference in OpenBao. This bypasses role constraints and signs the CSR as-is.

Example:

keyRef := "my-ca-key"
csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := client.SignVerbatimWithKeyRef(ctx, csr, keyRef, &SignVerbatimOptions{
    TTL: "8760h",
})

func (*Client) Sys

func (c *Client) Sys() *api.Sys

Sys returns the underlying OpenBao SDK Sys client for advanced operations. This is exposed for integration testing and advanced use cases.

func (*Client) UpdateIssuer

func (c *Client) UpdateIssuer(ctx context.Context, issuerRef string, config *IssuerConfig) error

UpdateIssuer updates issuer configuration.

Example:

err := client.UpdateIssuer(ctx, "issuer-id", &vault.IssuerConfig{
    IssuerName:           "My Issuer",
    LeafNotAfterBehavior: "truncate",
    Usage:                "issuing-certificates,crl-signing",
})

func (*Client) UpdateKeyName

func (c *Client) UpdateKeyName(ctx context.Context, keyRef string, newName string) error

UpdateKeyName updates the name of a key by ID or name.

Example:

err := client.UpdateKeyName(ctx, "key-id", "new-name")

func (*Client) UpdateRole

func (c *Client) UpdateRole(ctx context.Context, name string, opts *RoleOptions) error

UpdateRole explicitly updates an existing role in OpenBao. This is semantically clearer than CreateRole for update operations.

Example:

opts.TTL = "1440h" err := client.UpdateRole(ctx, "web-server", opts)

func (*Client) ValidateConnection

func (c *Client) ValidateConnection(ctx context.Context) error

ValidateConnection validates that the client can successfully connect to OpenBao and authenticate. This checks both connectivity and authentication.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

if err := client.ValidateConnection(ctx); err != nil {
    log.Fatalf("Cannot connect to OpenBao: %v", err)
}

type Config

type Config struct {
	// Address is the OpenBao server URL (required)
	// Example: "https://openbao.example.com"
	Address string

	// Token is the OpenBao authentication token (required)
	// Example: "hvs.CAESIHNPbm..."
	// Security: Store securely, use environment variables
	Token string

	// Namespace is the OpenBao namespace (optional, Enterprise only)
	// Example: "admin/engineering"
	Namespace string

	// Mount is the PKI secrets engine mount path (default: "pki")
	// Example: "pki", "pki-root", "pki-intermediate"
	Mount string

	// TLSConfig for HTTPS connections (optional)
	// If nil, uses default TLS configuration
	TLSConfig *tls.Config

	// HTTPClient allows providing a custom HTTP client (optional)
	// If nil, creates a new client with TLSConfig
	HTTPClient *http.Client

	// Timeout for HTTP requests (default: 30 seconds)
	// Applied to individual requests
	Timeout time.Duration

	// RetryConfig for failed requests (optional)
	// If nil, no retries are performed
	RetryConfig *RetryConfig
}

Config contains configuration for connecting to OpenBao.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the configuration is valid.

type GenerateCAResponse

type GenerateCAResponse struct {
	Certificate    *cert.Certificate // Generated certificate
	IssuingCA      string            // Issuing CA certificate (PEM)
	CAChain        []string          // CA chain (PEM)
	SerialNumber   string            // Certificate serial number
	IssuerID       string            // Issuer UUID
	KeyID          string            // Key UUID
	PrivateKey     string            // Private key (only for "exported" type)
	PrivateKeyType string            // Private key type
	CSR            string            // CSR (only for "exported" intermediate)
}

GenerateCAResponse contains the response from generating a CA.

type GenerateCertificateOptions

type GenerateCertificateOptions struct {
	CommonName        string   // Certificate common name (CN)
	AltNames          []string // DNS Subject Alternative Names
	IPSANs            []string // IP Subject Alternative Names
	URISANs           []string // URI Subject Alternative Names
	OtherSANs         []string // Other SANs with the format <oid>;UTF8:<value>
	TTL               string   // Certificate time-to-live (e.g., "720h", "30d")
	Format            string   // Certificate format ("pem", "der", "pem_bundle")
	PrivateKeyFormat  string   // Private key format ("", "pkcs8")
	ExcludeCNFromSANs bool     // Exclude CN from Subject Alternative Names
	NotAfter          string   // Explicit expiration time (RFC3339 format)
	KeyType           string   // Key type ("rsa", "ec", "ed25519") - auto-set by GenerateXXXCertificate methods
	KeyBits           int      // Key bits for RSA and ECDSA keys - auto-set by GenerateXXXCertificate methods
}

GenerateCertificateOptions contains parameters for generating a certificate in OpenBao. OpenBao generates both the private key and certificate.

type GenerateKeyOptions

type GenerateKeyOptions struct {
	KeyName string // Name for the key
	KeyType string // "rsa", "ec", "ed25519" (set automatically by typed functions)
	KeyBits int    // For RSA: 2048, 3072, 4096; For EC: 224, 256, 384, 521
}

GenerateKeyOptions contains parameters for generating a key in OpenBao.

type ImportKeyOptions

type ImportKeyOptions struct {
	KeyName string // Name for the key
}

ImportKeyOptions contains parameters for importing a key to OpenBao.

type IssuerClient

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

IssuerClient wraps an issuer and provides methods for managing it.

func (*IssuerClient) AddCRLDistributionPoint

func (ic *IssuerClient) AddCRLDistributionPoint(ctx context.Context, url string) error

AddCRLDistributionPoint adds a CRL distribution point URL.

func (*IssuerClient) AddIssuingCertificateURL

func (ic *IssuerClient) AddIssuingCertificateURL(ctx context.Context, url string) error

AddIssuingCertificateURL adds an issuing certificate URL.

func (*IssuerClient) AddOCSPServer

func (ic *IssuerClient) AddOCSPServer(ctx context.Context, url string) error

AddOCSPServer adds an OCSP server URL.

func (*IssuerClient) Certificate

func (ic *IssuerClient) Certificate() (*cert.Certificate, error)

Certificate returns the issuer's certificate.

func (*IssuerClient) CreateRole

func (ic *IssuerClient) CreateRole(ctx context.Context, name string, opts *RoleOptions) (*RoleClient, error)

CreateRole creates a new role configured to use this issuer. This is a convenience method that links IssuerClient with RoleClient.

The role's IssuerRef is automatically set to this issuer's ID.

Example:

issuer, _ := client.GetIssuer(ctx, "my-ca")
role, err := issuer.CreateRole(ctx, "web-server", &RoleOptions{
    AllowedDomains: []string{"example.com"},
    AllowSubdomains: true,
    TTL: "720h",
})

func (*IssuerClient) Delete

func (ic *IssuerClient) Delete(ctx context.Context) error

Delete deletes this issuer from OpenBao.

func (*IssuerClient) ID

func (ic *IssuerClient) ID() string

ID returns the issuer ID.

func (*IssuerClient) Info

func (ic *IssuerClient) Info() *IssuerInfo

Info returns the complete issuer information.

func (*IssuerClient) IssueECDSACertificate

func (ic *IssuerClient) IssueECDSACertificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.ECDSAKeyPair], error)

IssueECDSACertificate issues an ECDSA certificate using this issuer. A temporary role may be created if no default role exists for this issuer.

Example:

issuer, _ := client.GetIssuer(ctx, "my-ca")
certClient, err := issuer.IssueECDSACertificate(ctx, "my-ec-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*IssuerClient) IssueEd25519Certificate

func (ic *IssuerClient) IssueEd25519Certificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.Ed25519KeyPair], error)

IssueEd25519Certificate issues an Ed25519 certificate using this issuer. A temporary role may be created if no default role exists for this issuer.

Example:

issuer, _ := client.GetIssuer(ctx, "my-ca")
certClient, err := issuer.IssueEd25519Certificate(ctx, "my-ed25519-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*IssuerClient) IssueRSACertificate

func (ic *IssuerClient) IssueRSACertificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.RSAKeyPair], error)

IssueRSACertificate issues an RSA certificate using this issuer. A temporary role may be created if no default role exists for this issuer.

Example:

issuer, _ := client.GetIssuer(ctx, "my-ca")
certClient, err := issuer.IssueRSACertificate(ctx, "my-rsa-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*IssuerClient) KeyID

func (ic *IssuerClient) KeyID() string

KeyID returns the key ID associated with this issuer.

func (*IssuerClient) Name

func (ic *IssuerClient) Name() string

Name returns the issuer name.

func (*IssuerClient) SetAsDefault

func (ic *IssuerClient) SetAsDefault(ctx context.Context) error

SetAsDefault sets this issuer as the default issuer.

func (*IssuerClient) SignCSR

SignCSR signs a CSR using this issuer. A temporary role may be created if no default role exists for this issuer.

Example:

issuer, _ := client.GetIssuer(ctx, "my-ca")
csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := issuer.SignCSR(ctx, csr, &SignCertificateOptions{
    TTL: "8760h",
})

func (*IssuerClient) Update

func (ic *IssuerClient) Update(ctx context.Context, config *IssuerConfig) error

Update updates this issuer's configuration.

func (*IssuerClient) UpdateName

func (ic *IssuerClient) UpdateName(ctx context.Context, name string) error

UpdateName updates the issuer's name.

func (*IssuerClient) UpdateUsage

func (ic *IssuerClient) UpdateUsage(ctx context.Context, usage string) error

UpdateUsage updates the issuer's usage.

type IssuerConfig

type IssuerConfig struct {
	IssuerName                   string   // Issuer name
	LeafNotAfterBehavior         string   // "err", "truncate", "permit"
	Usage                        string   // Comma-separated: "read-only,issuing-certificates,crl-signing,ocsp-signing"
	RevocationSignatureAlgorithm string   // Signature algorithm
	IssuingCertificates          []string // Issuing certificate URLs
	CRLDistributionPoints        []string // CRL distribution point URLs
	OCSPServers                  []string // OCSP server URLs
	EnableAIAURLTemplating       bool     // Enable AIA URL templating
	ManualChain                  []string // Manual chain (issuer IDs)
}

IssuerConfig contains configuration for updating an issuer.

type IssuerInfo

type IssuerInfo struct {
	// IssuerID is the unique identifier
	IssuerID string

	// IssuerName is the human-readable name
	IssuerName string

	// KeyID is the associated key identifier
	KeyID string

	// Certificate is the issuer certificate (PEM format)
	Certificate string

	// CAChain is the certificate authority chain (PEM format)
	CAChain []string

	// ManualChain is a manually configured chain (issuer IDs)
	ManualChain []string

	// LeafNotAfterBehavior controls leaf certificate expiration handling ("err", "truncate", "permit")
	LeafNotAfterBehavior string

	// Usage specifies the issuer usage (read-only, issuing-certificates, crl-signing, ocsp-signing)
	Usage string

	// RevocationSignatureAlgorithm is the signature algorithm for revocation
	RevocationSignatureAlgorithm string

	// IssuingCertificates are the issuing certificate URLs
	IssuingCertificates []string

	// CRLDistributionPoints are the CRL distribution point URLs
	CRLDistributionPoints []string

	// OCSPServers are the OCSP server URLs
	OCSPServers []string

	// EnableAIAURLTemplating enables AIA URL templating
	EnableAIAURLTemplating bool
}

IssuerInfo represents information about a Vault PKI issuer (CA).

type KeyClient

type KeyClient[K keypair.KeyPair] struct {
	// contains filtered or unexported fields
}

KeyClient provides type-safe key operations for OpenBao PKI. It uses generics to ensure compile-time type safety for key material operations.

Type parameter:

  • K: KeyPair type constraint (keypair.KeyPair)

Supported types:

  • *algo.RSAKeyPair
  • *algo.ECDSAKeyPair
  • *algo.Ed25519KeyPair

The keyPair field is populated when:

  • Key is generated with GenerateXXXKey() (exported generation)
  • Key is imported with ImportXXXKey() (we have the private key)

The keyPair field is nil when:

  • Key is created with CreateXXXKey() (internal generation in OpenBao)
  • Key is retrieved with GetXXXKey() (only metadata available)

func (*KeyClient[K]) Delete

func (kc *KeyClient[K]) Delete(ctx context.Context) error

Delete deletes this key from OpenBao.

Example:

rsaKeys, _ := client.GetRSAKey(ctx, "key-id")
err := rsaKeys.Delete(ctx)

func (*KeyClient[K]) GetIssuers

func (kc *KeyClient[K]) GetIssuers(ctx context.Context) ([]*IssuerClient, error)

GetIssuers returns all issuers that use this key. This enables navigation from KeyClient to IssuerClient.

Example:

keyClient, _ := client.GetRSAKey(ctx, "my-key")
issuers, err := keyClient.GetIssuers(ctx)
for _, issuer := range issuers {
    fmt.Printf("Issuer: %s (ID: %s)\n", issuer.Name(), issuer.ID())
}

func (*KeyClient[K]) HasKeyPair

func (kc *KeyClient[K]) HasKeyPair() bool

HasKeyPair returns true if the key pair is cached and available. This is a convenience method to check availability without handling errors.

Example:

keyClient, err := client.CreateRSAKey(ctx, &GenerateKeyOptions{...})
if keyClient.HasKeyPair() {
    keyPair, _ := keyClient.KeyPair()
    // Use the keypair
} else {
    // Key is managed internally by OpenBao
}

func (*KeyClient[K]) IssueCertificate

func (kc *KeyClient[K]) IssueCertificate(ctx context.Context, role string, opts *GenerateCertificateOptions) (*CertificateClient[K], error)

IssueCertificate issues a certificate using this key. This is a convenience method that links KeyClient with CertificateClient operations.

The key must exist in OpenBao (KeyInfo().KeyID must be available). The returned CertificateClient does NOT have a cached key pair (key stays in OpenBao).

Example:

keyClient, _ := client.GenerateRSAKey(ctx, &GenerateKeyOptions{KeyName: "my-key"})
certClient, err := keyClient.IssueCertificate(ctx, "web-server", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})
cert := certClient.Certificate()

func (*KeyClient[K]) KeyInfo

func (kc *KeyClient[K]) KeyInfo() *KeyInfo

KeyInfo returns the key metadata.

func (*KeyClient[K]) KeyPair

func (kc *KeyClient[K]) KeyPair() (K, error)

KeyPair returns the cached key pair if available. Returns an error if the key pair is not cached (e.g., key was created with CreateXXXKey).

The key pair is available when:

  • Key was generated with GenerateXXXKey() (exported generation)
  • Key was imported with ImportXXXKey()

The key pair is NOT available when:

  • Key was created with CreateXXXKey() (internal generation)
  • Key was retrieved with GetXXXKey() (only metadata retrieved)

Example:

keyClient, err := client.GenerateRSAKey(ctx, &GenerateKeyOptions{...})
keyPair, err := keyClient.KeyPair()  // Returns the keypair
// Use keyPair.PrivateKey, keyPair.PublicKey

func (*KeyClient[K]) SaveKeyPairToFiles added in v1.22.0

func (kc *KeyClient[K]) SaveKeyPairToFiles(privatePath, publicPath string) error

SaveKeyPairToFiles saves the key pair to separate PEM files using gopki's secure patterns. The private key is saved with 0600 permissions, public key with 0644 permissions. Returns an error if the key pair is not available.

Example:

keyClient, _ := client.GenerateRSAKey(ctx, &GenerateKeyOptions{...})
err := keyClient.SaveKeyPairToFiles("private.pem", "public.pem")

func (*KeyClient[K]) SignCSR

SignCSR signs a CSR using this key. This is a convenience method for signing CSRs with a specific key from KeyClient.

Example:

keyClient, _ := client.GetRSAKey(ctx, "my-ca-key")
csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := keyClient.SignCSR(ctx, "web-server", csr, &SignCertificateOptions{
    TTL: "8760h",
})

func (*KeyClient[K]) SignVerbatim

SignVerbatim signs a CSR verbatim using this key. This bypasses role constraints and signs the CSR as-is.

Example:

keyClient, _ := client.GetRSAKey(ctx, "my-ca-key")
csr, _ := cert.CreateCSR(keyPair, cert.CSRRequest{...})
certificate, err := keyClient.SignVerbatim(ctx, csr, &SignVerbatimOptions{
    TTL: "8760h",
})

func (*KeyClient[K]) UpdateName

func (kc *KeyClient[K]) UpdateName(ctx context.Context, newName string) error

UpdateName updates this key's name.

Example:

rsaKeys, _ := bao.GetRSAKey(ctx, client, "key-id")
err := rsaKeys.UpdateName(ctx, "new-name")

type KeyInfo

type KeyInfo struct {
	// KeyID is the unique identifier
	KeyID string

	// KeyName is the human-readable name
	KeyName string

	// KeyType is the algorithm (rsa, ec, ed25519)
	KeyType string

	// KeyBits is the key size in bits
	KeyBits int
}

KeyInfo represents information about a key in Vault.

type RetryConfig

type RetryConfig struct {
	// MaxRetries is the maximum number of retry attempts
	// Default: 3
	MaxRetries int

	// BaseDelay is the initial delay between retries
	// Default: 1 second
	BaseDelay time.Duration

	// MaxDelay is the maximum delay between retries
	// Default: 30 seconds
	MaxDelay time.Duration

	// Multiplier is the backoff multiplier for exponential backoff
	// Default: 2.0
	Multiplier float64
}

RetryConfig contains configuration for retrying failed requests.

func DefaultRetryConfig

func DefaultRetryConfig() *RetryConfig

DefaultRetryConfig returns the default retry configuration.

type RoleClient

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

RoleClient wraps a role and provides methods for managing it.

func (*RoleClient) AddAllowedDomain

func (rc *RoleClient) AddAllowedDomain(ctx context.Context, domain string) error

AddAllowedDomain adds a domain to the allowed domains list.

Example:

roleClient.AddAllowedDomain(ctx, "example.com")

func (*RoleClient) Delete

func (rc *RoleClient) Delete(ctx context.Context) error

Delete deletes this role from OpenBao.

Example:

roleClient, _ := client.GetRole(ctx, "web-server") err := roleClient.Delete(ctx)

func (*RoleClient) DisableClientAuth

func (rc *RoleClient) DisableClientAuth(ctx context.Context) error

DisableClientAuth disables client authentication for this role.

Example:

roleClient.DisableClientAuth(ctx)

func (*RoleClient) DisableServerAuth

func (rc *RoleClient) DisableServerAuth(ctx context.Context) error

DisableServerAuth disables server authentication for this role.

Example:

roleClient.DisableServerAuth(ctx)

func (*RoleClient) EnableClientAuth

func (rc *RoleClient) EnableClientAuth(ctx context.Context) error

EnableClientAuth enables client authentication for this role.

Example:

roleClient.EnableClientAuth(ctx)

func (*RoleClient) EnableCodeSigning

func (rc *RoleClient) EnableCodeSigning(ctx context.Context) error

EnableCodeSigning enables code signing for this role.

Example:

roleClient.EnableCodeSigning(ctx)

func (*RoleClient) EnableServerAuth

func (rc *RoleClient) EnableServerAuth(ctx context.Context) error

EnableServerAuth enables server authentication for this role.

Example:

roleClient.EnableServerAuth(ctx)

func (*RoleClient) GetIssuer

func (rc *RoleClient) GetIssuer(ctx context.Context) (*IssuerClient, error)

GetIssuer returns the issuer referenced by this role. This enables navigation from RoleClient to IssuerClient.

Returns an error if:

  • Role has no IssuerRef configured
  • Issuer cannot be found

Example:

roleClient, _ := client.GetRole(ctx, "web-server")
issuer, err := roleClient.GetIssuer(ctx)
fmt.Printf("Role uses issuer: %s\n", issuer.Name())

func (*RoleClient) IssueECDSACertificate

func (rc *RoleClient) IssueECDSACertificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.ECDSAKeyPair], error)

IssueECDSACertificate issues an ECDSA certificate using this role. This is a convenience method that links RoleClient with certificate issuance.

Example:

roleClient, _ := client.GetRole(ctx, "web-server")
certClient, err := roleClient.IssueECDSACertificate(ctx, "my-ec-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*RoleClient) IssueEd25519Certificate

func (rc *RoleClient) IssueEd25519Certificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.Ed25519KeyPair], error)

IssueEd25519Certificate issues an Ed25519 certificate using this role. This is a convenience method that links RoleClient with certificate issuance.

Example:

roleClient, _ := client.GetRole(ctx, "web-server")
certClient, err := roleClient.IssueEd25519Certificate(ctx, "my-ed25519-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*RoleClient) IssueRSACertificate

func (rc *RoleClient) IssueRSACertificate(ctx context.Context, keyRef string, opts *GenerateCertificateOptions) (*CertificateClient[*algo.RSAKeyPair], error)

IssueRSACertificate issues an RSA certificate using this role. This is a convenience method that links RoleClient with certificate issuance.

Example:

roleClient, _ := client.GetRole(ctx, "web-server")
certClient, err := roleClient.IssueRSACertificate(ctx, "my-rsa-key", &GenerateCertificateOptions{
    CommonName: "app.example.com",
    TTL:        "720h",
})

func (*RoleClient) Name

func (rc *RoleClient) Name() string

Name returns the role name.

func (*RoleClient) Options

func (rc *RoleClient) Options() *RoleOptions

Options returns the role options.

func (*RoleClient) RemoveAllowedDomain

func (rc *RoleClient) RemoveAllowedDomain(ctx context.Context, domain string) error

RemoveAllowedDomain removes a domain from the allowed domains list.

Example:

roleClient.RemoveAllowedDomain(ctx, "old.example.com")

func (*RoleClient) SetMaxTTL

func (rc *RoleClient) SetMaxTTL(ctx context.Context, maxTTL string) error

SetMaxTTL updates the maximum TTL for this role.

Example:

roleClient.SetMaxTTL(ctx, "8760h")

func (*RoleClient) SetTTL

func (rc *RoleClient) SetTTL(ctx context.Context, ttl string) error

SetTTL updates the TTL for this role.

Example:

roleClient.SetTTL(ctx, "1440h")

func (*RoleClient) Update

func (rc *RoleClient) Update(ctx context.Context, opts *RoleOptions) error

Update updates this role with new options.

Example:

opts := roleClient.Options() opts.TTL = "1440h" err := roleClient.Update(ctx, opts)

type RoleOptions

type RoleOptions struct {
	IssuerRef                     string   `json:"issuer_ref,omitempty"`                         // Issuer to use for this role
	TTL                           string   `json:"ttl,omitempty"`                                // Time to live (e.g., "720h")
	MaxTTL                        string   `json:"max_ttl,omitempty"`                            // Maximum TTL (e.g., "8760h")
	AllowLocalhost                bool     `json:"allow_localhost,omitempty"`                    // Allow localhost in certificates
	AllowedDomains                []string `json:"allowed_domains,omitempty"`                    // Allowed domains
	AllowedDomainsTemplate        bool     `json:"allowed_domains_template,omitempty"`           // Allow templating in domain names
	AllowBareDomains              bool     `json:"allow_bare_domains,omitempty"`                 // Allow bare domains (no subdomains)
	AllowSubdomains               bool     `json:"allow_subdomains,omitempty"`                   // Allow subdomains
	AllowGlobDomains              bool     `json:"allow_glob_domains,omitempty"`                 // Allow glob patterns in domains
	AllowWildcardCertificates     bool     `json:"allow_wildcard_certificates,omitempty"`        // Allow wildcard certificates
	AllowAnyName                  bool     `json:"allow_any_name,omitempty"`                     // Allow any common name
	EnforceHostnames              bool     `json:"enforce_hostnames,omitempty"`                  // Enforce hostname format
	AllowIPSANs                   bool     `json:"allow_ip_sans,omitempty"`                      // Allow IP SANs
	AllowedIPSANs                 []string `json:"allowed_ip_sans,omitempty"`                    // Allowed IP SANs (CIDR blocks)
	AllowedURISANs                []string `json:"allowed_uri_sans,omitempty"`                   // Allowed URI SANs
	AllowedOtherSANs              []string `json:"allowed_other_sans,omitempty"`                 // Allowed other SANs
	AllowedSerialNumbers          []string `json:"allowed_serial_numbers,omitempty"`             // Allowed serial numbers
	ServerFlag                    bool     `json:"server_flag,omitempty"`                        // Set server auth extended key usage
	ClientFlag                    bool     `json:"client_flag,omitempty"`                        // Set client auth extended key usage
	CodeSigningFlag               bool     `json:"code_signing_flag,omitempty"`                  // Set code signing extended key usage
	EmailProtectionFlag           bool     `json:"email_protection_flag,omitempty"`              // Set email protection extended key usage
	KeyType                       string   `json:"key_type,omitempty"`                           // "rsa", "ec", "ed25519", "any"
	KeyBits                       int      `json:"key_bits,omitempty"`                           // Key size
	SignatureBits                 int      `json:"signature_bits,omitempty"`                     // Signature bits (for RSA PSS)
	UsePSS                        bool     `json:"use_pss,omitempty"`                            // Use RSA-PSS for RSA keys
	KeyUsage                      []string `json:"key_usage,omitempty"`                          // Key usage extensions
	ExtKeyUsage                   []string `json:"ext_key_usage,omitempty"`                      // Extended key usage extensions
	ExtKeyUsageOIDs               []string `json:"ext_key_usage_oids,omitempty"`                 // Extended key usage OIDs
	UseCSRCommonName              bool     `json:"use_csr_common_name,omitempty"`                // Use CN from CSR
	UseCSRSANs                    bool     `json:"use_csr_sans,omitempty"`                       // Use SANs from CSR
	OrganizationUnit              []string `json:"ou,omitempty"`                                 // Organization unit
	Organization                  []string `json:"organization,omitempty"`                       // Organization
	Country                       []string `json:"country,omitempty"`                            // Country
	Locality                      []string `json:"locality,omitempty"`                           // Locality
	Province                      []string `json:"province,omitempty"`                           // Province
	StreetAddress                 []string `json:"street_address,omitempty"`                     // Street address
	PostalCode                    []string `json:"postal_code,omitempty"`                        // Postal code
	GenerateLease                 bool     `json:"generate_lease,omitempty"`                     // Generate lease for certificate
	NoStore                       bool     `json:"no_store,omitempty"`                           // Don't store certificate
	RequireCN                     bool     `json:"require_cn,omitempty"`                         // Require common name
	PolicyIdentifiers             []string `json:"policy_identifiers,omitempty"`                 // Policy identifiers
	BasicConstraintsValidForNonCA bool     `json:"basic_constraints_valid_for_non_ca,omitempty"` // Allow basic constraints for non-CA
	NotBeforeDuration             string   `json:"not_before_duration,omitempty"`                // Not before duration
	CNValidations                 []string `json:"cn_validations,omitempty"`                     // CN validation rules
	AllowedUserIDs                []string `json:"allowed_user_ids,omitempty"`                   // Allowed user IDs
}

RoleOptions contains parameters for creating or updating a role.

type RoleOptionsBuilder

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

RoleOptionsBuilder provides a fluent API for building RoleOptions.

func NewClientCertRole

func NewClientCertRole(domain string) *RoleOptionsBuilder

NewClientCertRole creates a pre-configured builder for client certificate roles.

Example:

opts := bao.NewClientCertRole("example.com").

WithTTL("1440h").
Build()

err := client.CreateRole(ctx, "client-cert", opts)

func NewCodeSigningRole

func NewCodeSigningRole(domain string) *RoleOptionsBuilder

NewCodeSigningRole creates a pre-configured builder for code signing roles.

Example:

opts := bao.NewCodeSigningRole("example.com").

WithOrganization("Acme Corp").
Build()

err := client.CreateRole(ctx, "code-signing", opts)

func NewRoleOptionsBuilder

func NewRoleOptionsBuilder() *RoleOptionsBuilder

NewRoleOptionsBuilder creates a new builder for role options.

func NewWebServerRole

func NewWebServerRole(domain string) *RoleOptionsBuilder

NewWebServerRole creates a pre-configured builder for web server roles.

Example:

opts := bao.NewWebServerRole("example.com").

WithTTL("1440h").
Build()

err := client.CreateRole(ctx, "web-server", opts)

func (*RoleOptionsBuilder) Build

func (b *RoleOptionsBuilder) Build() *RoleOptions

Build returns the built RoleOptions.

func (*RoleOptionsBuilder) EnableLocalhost

func (b *RoleOptionsBuilder) EnableLocalhost() *RoleOptionsBuilder

EnableLocalhost enables localhost in certificates.

func (*RoleOptionsBuilder) EnableSubdomains

func (b *RoleOptionsBuilder) EnableSubdomains() *RoleOptionsBuilder

EnableSubdomains enables subdomain support.

func (*RoleOptionsBuilder) EnableWildcards

func (b *RoleOptionsBuilder) EnableWildcards() *RoleOptionsBuilder

EnableWildcards enables wildcard certificate support.

func (*RoleOptionsBuilder) WithAllowedDomains

func (b *RoleOptionsBuilder) WithAllowedDomains(domains ...string) *RoleOptionsBuilder

WithAllowedDomains sets the allowed domains.

func (*RoleOptionsBuilder) WithClientAuth

func (b *RoleOptionsBuilder) WithClientAuth() *RoleOptionsBuilder

WithClientAuth enables client authentication.

func (*RoleOptionsBuilder) WithCodeSigning

func (b *RoleOptionsBuilder) WithCodeSigning() *RoleOptionsBuilder

WithCodeSigning enables code signing.

func (*RoleOptionsBuilder) WithCountry

func (b *RoleOptionsBuilder) WithCountry(country ...string) *RoleOptionsBuilder

WithCountry sets the country.

func (*RoleOptionsBuilder) WithEmailProtection

func (b *RoleOptionsBuilder) WithEmailProtection() *RoleOptionsBuilder

WithEmailProtection enables email protection.

func (*RoleOptionsBuilder) WithIssuerRef

func (b *RoleOptionsBuilder) WithIssuerRef(ref string) *RoleOptionsBuilder

WithIssuerRef sets the issuer reference.

func (*RoleOptionsBuilder) WithKeyType

func (b *RoleOptionsBuilder) WithKeyType(keyType string, bits int) *RoleOptionsBuilder

WithKeyType sets the key type and bits.

func (*RoleOptionsBuilder) WithLocality

func (b *RoleOptionsBuilder) WithLocality(locality ...string) *RoleOptionsBuilder

WithLocality sets the locality.

func (*RoleOptionsBuilder) WithMaxTTL

func (b *RoleOptionsBuilder) WithMaxTTL(maxTTL string) *RoleOptionsBuilder

WithMaxTTL sets the maximum TTL.

func (*RoleOptionsBuilder) WithOrganization

func (b *RoleOptionsBuilder) WithOrganization(org ...string) *RoleOptionsBuilder

WithOrganization sets the organization.

func (*RoleOptionsBuilder) WithProvince

func (b *RoleOptionsBuilder) WithProvince(province ...string) *RoleOptionsBuilder

WithProvince sets the province.

func (*RoleOptionsBuilder) WithServerAuth

func (b *RoleOptionsBuilder) WithServerAuth() *RoleOptionsBuilder

WithServerAuth enables server authentication.

func (*RoleOptionsBuilder) WithTTL

func (b *RoleOptionsBuilder) WithTTL(ttl string) *RoleOptionsBuilder

WithTTL sets the time to live.

type SignCertificateOptions

type SignCertificateOptions struct {
	CommonName        string   // Override CSR common name (optional)
	AltNames          []string // Additional DNS SANs (merged with CSR SANs)
	IPSANs            []string // Additional IP SANs (merged with CSR SANs)
	URISANs           []string // Additional URI SANs (merged with CSR SANs)
	OtherSANs         []string // Other SANs with the format <oid>;UTF8:<value>
	TTL               string   // Certificate time-to-live
	Format            string   // Certificate format
	ExcludeCNFromSANs bool     // Exclude CN from SANs
	NotAfter          string   // Explicit expiration time (RFC3339 format)
}

SignCertificateOptions contains parameters for signing a CSR.

type SignSelfIssuedOptions

type SignSelfIssuedOptions struct {
	RequireMatchingCertificateAlgorithms bool // Require matching algorithms
}

SignSelfIssuedOptions contains parameters for signing a self-issued certificate.

type SignVerbatimOptions

type SignVerbatimOptions struct {
	TTL      string // Certificate time-to-live
	Format   string // Certificate format
	NotAfter string // Explicit expiration time (RFC3339 format)
}

SignVerbatimOptions contains parameters for signing a certificate verbatim.

type VaultError

type VaultError struct {
	// Operation is the operation that failed
	Operation string

	// StatusCode is the HTTP status code
	StatusCode int

	// Errors are the error messages from Vault
	Errors []string

	// Err is the underlying error
	Err error
}

VaultError represents a structured error from Vault API.

func (*VaultError) Error

func (e *VaultError) Error() string

Error implements the error interface.

func (*VaultError) Unwrap

func (e *VaultError) Unwrap() error

Unwrap returns the underlying error for error unwrapping.

Jump to

Keyboard shortcuts

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