SigilGuard

View Source

SIGIL Protocol integration for Elixir — with optional Rust NIF backend

Hex.pm Docs CI Coverage License

Installation | Quick Start | Documentation


Overview

SigilGuard provides a high-level Elixir API for the SIGIL Protocol, securing MCP (Model Context Protocol) tool calls and AI agent interactions. Use SigilGuard for:

  • Sensitivity Scanning — Detect and redact credentials, API keys, PII in text
  • Envelope Signing — Ed25519 signed _sigil metadata for MCP JSON-RPC
  • Policy Enforcement — Risk-classified trust gating for tool call authorization
  • Tamper-Evident Audit — HMAC-SHA256 chain integrity for immutable audit logs
  • Registry Client — Fetch patterns and policies from the SIGIL registry

Features

FeatureDescriptionBackend
Sensitivity ScannerRegex-based detection of secrets, credentials, PIIElixir / NIF
Envelope Sign/VerifyEd25519 canonical envelope signingElixir / NIF
Policy EngineRisk classification and trust-level gatingElixir / NIF
Audit ChainHMAC-SHA256 tamper-evident event chainElixir / NIF
Secure VaultAES-256-GCM encrypted secret storageElixir
Registry ClientREST client with TTL cacheElixir
TelemetryBuilt-in observability eventsElixir

Installation

Requirements

  • Elixir ~> 1.17
  • Erlang/OTP 27+
  • Rust toolchain (optional, for NIF backend)

Add sigil_guard to your dependencies in mix.exs:

def deps do
  [
    {:sigil_guard, "~> 0.2.0"},
    # Optional: For Rust NIF backend
    {:rustler, "~> 0.37", runtime: false, optional: true}
  ]
end

Optional: Rust NIF Backend

For lower-latency operations and protocol parity with the Rust reference implementation:

# Install Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Configure backend
config :sigil_guard, backend: :nif

Quick Start

Sensitivity Scanning

# Scan for sensitive content
{:ok, "safe text"} = SigilGuard.scan("safe text")
{:hit, hits} = SigilGuard.scan("AKIAIOSFODNN7EXAMPLE")

# Scan and redact in one pass
"key=[AWS_KEY]" = SigilGuard.scan_and_redact("key=AKIAIOSFODNN7EXAMPLE")

Built-in patterns detect: AWS keys, API keys, bearer tokens, database URIs, private key headers, and generic secrets/passwords.

Envelope Signing

# Sign an envelope
envelope = SigilGuard.Envelope.sign("did:sigil:alice", :allowed,
  signer: MySigner,
  reason: "scan passed"
)

# Verify
:ok = SigilGuard.Envelope.verify(envelope, public_key_b64u)

Policy Enforcement

:allowed = SigilGuard.policy_verdict("read_file", :medium)
:blocked = SigilGuard.policy_verdict("delete_database", :low)
{:confirm, reason} = SigilGuard.policy_verdict("create_user", :low)

Trust levels: :low < :medium < :high Risk levels: :low < :medium < :high

Tamper-Evident Audit

key = :crypto.strong_rand_bytes(32)

events = [
  SigilGuard.Audit.new_event("mcp.tool_call", "alice", "read_file", "success"),
  SigilGuard.Audit.new_event("mcp.tool_call", "bob", "write_file", "success")
]

signed = SigilGuard.Audit.build_chain(events, key)
:ok = SigilGuard.Audit.verify_chain(signed, key)

Secure Vaulting

{:ok, _pid} = SigilGuard.Vault.InMemory.start_link([])
{:ok, vault_id} = SigilGuard.Vault.InMemory.encrypt("sk-abc123", "OpenAI key")
{:ok, "sk-abc123"} = SigilGuard.Vault.InMemory.decrypt(vault_id)

Configuration

config :sigil_guard,
  backend: :elixir, # :elixir | :nif
  registry_url: "https://registry.sigil-protocol.org",
  registry_ttl_ms: :timer.hours(1),
  registry_timeout_ms: 5_000,
  registry_retry_ms: :timer.minutes(1),
  registry_enabled: false,
  scanner_patterns: :built_in

Configuration Options

OptionTypeDefaultDescription
backendatom():elixirBackend implementation (:elixir or :nif)
registry_urlString.t()"https://registry.sigil-protocol.org"SIGIL registry URL
registry_ttl_msinteger()3_600_000Registry cache TTL in ms
registry_timeout_msinteger()5_000Registry HTTP timeout in ms
registry_retry_msinteger()60_000Retry interval after a failed registry fetch in ms
registry_enabledboolean()falseEnable registry fetching
scanner_patternsatom():built_inPattern source (:built_in or :registry)

Backend Selection

# Check available backends
SigilGuard.Backend.available_backends()
#=> [:elixir] or [:elixir, :nif]

# Get current backend module
SigilGuard.Backend.impl()
#=> SigilGuard.Backend.Elixir

Backends

SigilGuard uses a pluggable backend architecture. Protocol operations can run in pure Elixir or via a Rust NIF for maximum performance.

BackendIsolationLatencyStatusUse Case
ElixirFullMediumStableDefault, safe, works everywhere
NIFNoneLowestBetaProtocol parity, performance

The NIF backend uses the sigil-protocol Rust crate for protocol operations (envelope signing/verification, canonical bytes) with ed25519-dalek, hmac/sha2, and regex for extensions (detailed scanning, audit HMAC chain).


Architecture

                      SigilGuard (Public API)
                              |
                    SigilGuard.Backend (Behaviour)
                              |
              +---------------+---------------+
              |                               |
              v                               v
SigilGuard.Backend.Elixir         SigilGuard.Backend.NIF
              |                               |
              v                               v
   OTP :crypto + Regex              Rustler + ed25519-dalek + hmac/sha2

Module Overview

SigilGuard (Main API)
    |
    +-- SigilGuard.Backend         Backend behaviour and selection
    |   +-- Backend.Elixir         Pure Elixir backend (default)
    |   +-- Backend.NIF            Rust NIF backend (optional)
    |
    +-- SigilGuard.Scanner         Sensitivity scanning engine
    +-- SigilGuard.Patterns        Pattern compilation and management
    +-- SigilGuard.Envelope        SIGIL envelope signing and verification
    +-- SigilGuard.Policy          Risk classification and trust gating
    +-- SigilGuard.Audit           Tamper-evident audit chain
    +-- SigilGuard.Identity        Trust level hierarchy
    +-- SigilGuard.Signer          Cryptographic signing behaviour
    +-- SigilGuard.Vault           Encrypted storage behaviour
    +-- SigilGuard.Registry        SIGIL registry REST client
    +-- SigilGuard.Config          Configuration access
    +-- SigilGuard.Telemetry       Telemetry event definitions

Extension Points (Behaviours)

BehaviourPurposeExample Implementation
SigilGuard.SignerCryptographic signingHSM, KMS, cloud key management
SigilGuard.VaultEncrypted storageHashiCorp Vault, AWS KMS, database
SigilGuard.Audit.LoggerAudit persistenceDatabase, file, external service
SigilGuard.IdentityAuthentication contextYour auth system integration
SigilGuard.PolicyCustom risk rulesDomain-specific classification

Telemetry

SigilGuard emits telemetry events for observability:

EventMeasurementsMetadata
[:sigil_guard, :scan, :start|:stop]durationhit_count, patterns_checked
[:sigil_guard, :registry, :fetch, :start|:stop]durationurl, count, source
[:sigil_guard, :policy, :decision]system_timeaction, risk_level, trust_level
[:sigil_guard, :audit, :logged]system_timeevent_type, actor

Development

mix setup            # Install dependencies
mix test             # Run tests (unit only)
mix test.nif         # Run with NIF tests
mix lint             # Format + Credo + Dialyzer
mix check            # All quality checks
mix docs             # Generate documentation
mix bench            # Run benchmarks

Running NIF Tests

# Ensure Rust toolchain is installed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

mix test.nif  # Run all tests including NIF

Performance

SigilGuard includes benchmarks comparing Elixir and NIF backends:

mix bench

Results are saved to bench/output/benchmarks.md.


References


Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.


License

SigilGuard is released under the MIT License. See LICENSE for details.