Skip to content

rah-0/aegis

Repository files navigation

Go Report Card License: MIT

Buy Me A Coffee

aegis

Lightweight Go library for sealing and unsealing data using AEAD (AES-GCM) with built-in key routing.

Installation

go get github.com/rah-0/aegis

Usage

// Define a codec (or use any serialization: JSON, msgpack, protobuf, etc.)
type jsonCodec struct{}

func (jsonCodec) Encode(v any) ([]byte, error) { return json.Marshal(v) }
func (jsonCodec) Decode(data []byte, v any) error { return json.Unmarshal(data, v) }

// Create a vault
vault, err := aegis.NewVault(jsonCodec{})
if err != nil {
    log.Fatal(err)
}

// Register a 32-byte key under a label
key := []byte("my-32-byte-secret-key-here!!1234")
if err := vault.AddSecret("default", key); err != nil {
    log.Fatal(err)
}

// Seal
sealed, err := vault.Seal("default", map[string]string{"user": "alice"})
if err != nil {
    log.Fatal(err)
}

// Unseal — label is embedded, key routing is automatic
var result map[string]string
if err := vault.Unseal(sealed, &result); err != nil {
    log.Fatal(err)
}

Key Management

// Bulk load multiple keys
vault.LoadSecrets([]aegis.Secret{
    {Label: "primary", Key: key1},
    {Label: "secondary", Key: key2},
})

// Rotate a key at runtime (hot-reload)
vault.UpdateSecret("primary", newKey)

// Remove a key
vault.RemoveSecret("secondary")

Custom Codec

Implement the Codec interface to use any serialization format:

type Codec interface {
    Encode(v any) ([]byte, error)
    Decode(data []byte, v any) error
}

When to Use

  • Encrypting session tokens, cookies, or API payloads
  • Sealing configuration secrets or credentials at rest
  • Cross-service encryption — all services that need to seal/unseal must share the same labels and keys
  • Any scenario where you need authenticated encryption with key routing

Planned

  • Streaming encryption — seal/unseal data as a stream instead of loading entire payloads in memory
  • File encryption — chunked AEAD for large files
  • Nonce-misuse resistance (AES-GCM-SIV) — Go's x/crypto has an accepted proposal for aesgcmsiv, currently in backlog. Once shipped, aegis will support it as an alternative AEAD backend

When Not to Use

  • Password hashing — use bcrypt/scrypt/argon2 instead
  • Key exchange or asymmetric crypto — aegis is symmetric-key only

Wire Format

[label-len-size: 1 byte]   — number of bytes used to encode label length
[label-len: 1–8 bytes]     — label length as big-endian uint
[label: N bytes]            — label string, length defined above
[nonce: 12 bytes]           — GCM nonce (fixed)
[ciphertext: variable]      — encrypted data
[auth-tag: 16 bytes]        — GCM authentication tag (appended to ciphertext by AEAD)

Security

  • AES-256-GCM: 256-bit key (enforced), 12-byte random nonce, 16-byte authentication tag
  • CSPRNG nonces: Generated via crypto/rand, nonce collision probability is negligible below ~2⁴⁸ operations per key
  • Key material never leaves memory: Keys are stored as cipher.AEAD interfaces, the raw bytes are not retained
  • Concurrent-safe: All vault operations are protected by sync.RWMutex

Benchmarks

See BENCHMARK.md for detailed results comparing JSON vs binary codecs across message sizes, label sizes, and full round-trips.

Key takeaways:

  • Seal at ~550 MB/s (JSON) or ~960 MB/s (binary) for 64 KB payloads
  • Unseal at ~200 MB/s (JSON) or ~1,450 MB/s (binary) — codec choice dominates unseal performance
  • Constant allocation count (5 allocs) regardless of payload size
  • Label size has negligible impact on performance

☕ Support

If this saved you time or brought value to your project, feel free to show some support. Every bit is appreciated 🙂

Buy Me A Coffee

About

Lightweight Go library for sealing and unsealing data using AEAD (AES-GCM) with built-in key routing.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages