Idiomatic Go package with context support and concurrent-safe operations
All operations accept context for cancellation and timeouts
Thread-safe operations with proper locking
Standard library only for core functionality
Follows Go conventions and best practices
go get github.com/avp-protocol/avp-go
package main
import (
"context"
"fmt"
"log"
"github.com/avp-protocol/avp-go"
)
func main() {
ctx := context.Background()
// Create client with file backend
backend, err := avp.NewFileBackend("./vault.enc", "your-password")
if err != nil {
log.Fatal(err)
}
client := avp.NewClient(backend)
// Authenticate to workspace
session, err := client.Authenticate(ctx, "my-agent", nil)
if err != nil {
log.Fatal(err)
}
// Store a secret
err = client.Store(ctx, session.ID, "OPENAI_API_KEY", []byte("sk-..."), nil)
if err != nil {
log.Fatal(err)
}
// Retrieve a secret
secret, err := client.Retrieve(ctx, session.ID, "OPENAI_API_KEY", nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Key: %s\n", string(secret.Value))
}
In-memory storage for testing.
import "github.com/avp-protocol/avp-go"
backend := avp.NewMemoryBackend()
client := avp.NewClient(backend)
Encrypted file storage using AES-256-GCM.
backend, err := avp.NewFileBackend("./vault.enc", "password")
if err != nil {
log.Fatal(err)
}
client := avp.NewClient(backend)
OS-native credential storage.
backend, err := avp.NewKeychainBackend("my-app-avp")
if err != nil {
log.Fatal(err)
}
client := avp.NewClient(backend)
info, err := client.Discover(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Version: %s\n", info.Version)
fmt.Printf("Backends: %v\n", info.Backends)
fmt.Printf("Operations: %v\n", info.Operations)
import "time"
// Default TTL (1 hour)
session, err := client.Authenticate(ctx, "workspace", nil)
// Custom TTL
ttl := 2 * time.Hour
session, err := client.Authenticate(ctx, "workspace", &avp.AuthOptions{
TTL: &ttl,
})
fmt.Printf("Session ID: %s\n", session.ID)
fmt.Printf("Expires: %v\n", session.ExpiresAt)
// Simple store
err := client.Store(ctx, session.ID, "API_KEY", []byte("sk-..."), nil)
// With options
err := client.Store(ctx, session.ID, "API_KEY", []byte("sk-..."), &avp.StoreOptions{
Labels: map[string]string{
"env": "production",
"provider": "openai",
},
ExpiresAt: time.Now().Add(30 * 24 * time.Hour), // 30 days
})
// Latest version
secret, err := client.Retrieve(ctx, session.ID, "API_KEY", nil)
// Specific version
version := uint32(1)
secret, err := client.Retrieve(ctx, session.ID, "API_KEY", &avp.RetrieveOptions{
Version: &version,
})
fmt.Printf("Value: %s\n", string(secret.Value))
fmt.Printf("Version: %d\n", secret.Version)
fmt.Printf("Labels: %v\n", secret.Labels)
err := client.Delete(ctx, session.ID, "OLD_KEY")
// List all
secrets, err := client.List(ctx, session.ID, nil)
// With label filter
secrets, err := client.List(ctx, session.ID, &avp.ListOptions{
LabelFilter: map[string]string{
"env": "production",
},
})
for _, s := range secrets {
fmt.Printf("%s: v%d\n", s.Name, s.Version)
}
result, err := client.Rotate(ctx, session.ID, "API_KEY", []byte("sk-new-..."))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Previous: v%d\n", result.PreviousVersion)
fmt.Printf("New: v%d\n", result.NewVersion)
import "errors"
secret, err := client.Retrieve(ctx, session.ID, "UNKNOWN", nil)
if err != nil {
var avpErr *avp.Error
if errors.As(err, &avpErr) {
switch avpErr.Code {
case avp.ErrNotFound:
fmt.Println("Secret not found")
case avp.ErrSessionExpired:
fmt.Println("Session expired, re-authenticate")
case avp.ErrUnauthorized:
fmt.Println("Not authorized for this workspace")
default:
fmt.Printf("AVP Error: %s\n", avpErr.Message)
}
} else {
fmt.Printf("Error: %v\n", err)
}
}
import (
"context"
"time"
)
// With timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
secret, err := client.Retrieve(ctx, session.ID, "API_KEY", nil)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
fmt.Println("Operation timed out")
}
}
// With cancellation
ctx, cancel := context.WithCancel(context.Background())
go func() {
// Cancel after some condition
cancel()
}()
secret, err := client.Retrieve(ctx, session.ID, "API_KEY", nil)
import "sync"
var wg sync.WaitGroup
keys := []string{"KEY1", "KEY2", "KEY3"}
for _, key := range keys {
wg.Add(1)
go func(k string) {
defer wg.Done()
secret, err := client.Retrieve(ctx, session.ID, k, nil)
if err != nil {
log.Printf("Error retrieving %s: %v", k, err)
return
}
fmt.Printf("%s: %s\n", k, string(secret.Value))
}(key)
}
wg.Wait()
package main
import (
"context"
"time"
"github.com/avp-protocol/avp-go"
)
type MyBackend struct {
// Your storage implementation
}
func (b *MyBackend) Discover(ctx context.Context) (*avp.DiscoverInfo, error) {
// Return capabilities
}
func (b *MyBackend) Authenticate(ctx context.Context, workspace string, opts *avp.AuthOptions) (*avp.Session, error) {
// Create session
}
func (b *MyBackend) Store(ctx context.Context, sessionID, name string, value []byte, opts *avp.StoreOptions) error {
// Store secret
}
func (b *MyBackend) Retrieve(ctx context.Context, sessionID, name string, opts *avp.RetrieveOptions) (*avp.Secret, error) {
// Retrieve secret
}
func (b *MyBackend) Delete(ctx context.Context, sessionID, name string) error {
// Delete secret
}
func (b *MyBackend) List(ctx context.Context, sessionID string, opts *avp.ListOptions) ([]*avp.SecretMetadata, error) {
// List secrets
}
func (b *MyBackend) Rotate(ctx context.Context, sessionID, name string, newValue []byte) (*avp.RotateResult, error) {
// Rotate secret
}
// Verify interface implementation
var _ avp.Backend = (*MyBackend)(nil)
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/avp-protocol/avp-go"
)
func main() {
ctx := context.Background()
// Initialize
backend, err := avp.NewFileBackend("./agent-vault.enc", os.Getenv("VAULT_PASSWORD"))
if err != nil {
log.Fatal(err)
}
client := avp.NewClient(backend)
// Authenticate
session, err := client.Authenticate(ctx, "openai-agent", nil)
if err != nil {
log.Fatal(err)
}
// Store with labels
err = client.Store(ctx, session.ID, "OPENAI_API_KEY", []byte(os.Getenv("OPENAI_API_KEY")), &avp.StoreOptions{
Labels: map[string]string{
"provider": "openai",
"env": "production",
},
})
if err != nil {
log.Fatal(err)
}
// Retrieve and use
secret, err := client.Retrieve(ctx, session.ID, "OPENAI_API_KEY", nil)
if err != nil {
log.Fatal(err)
}
apiKey := string(secret.Value)
fmt.Printf("Using API key v%d\n", secret.Version)
// Use apiKey with OpenAI client...
_ = apiKey
// Rotate when needed
result, err := client.Rotate(ctx, session.ID, "OPENAI_API_KEY", []byte("sk-new-..."))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Rotated from v%d to v%d\n", result.PreviousVersion, result.NewVersion)
}