Skip to main content
  1. Documentation/
  2. Architecture/

Security Model

Table of Contents
TantoC2’s security model covers wire encryption, at-rest encryption, authentication, and access control.

Cryptographic Stack
#

LayerAlgorithmPurpose
Key ExchangeECDH (P-256)Agent-server session key establishment
Key DerivationHKDF-SHA256Derive session keys from ECDH shared secret
Wire EncryptionAES-256-GCMEncrypt all agent-server communication
At-Rest EncryptionAES-256-GCMEncrypt sensitive database fields
Master KeyPBKDF2Derive per-engagement master key from passphrase
Password StoragebcryptHash operator passwords
Anti-ReplayMonotonic counterPrevent message replay attacks

Wire Encryption
#

All agent communication is encrypted at the application layer using AES-256-GCM:

  1. During registration, the agent and server perform ECDH key exchange
  2. Both derive a session key using HKDF-SHA256
  3. All subsequent messages are encrypted with the session key
  4. Each message includes a 12-byte random nonce and GCM authentication tag
  5. A monotonic counter prevents replay attacks

Wire Format (Dev Agent)
#

1
[4B counter][12B nonce][ciphertext + GCM tag]

The counter is included inside the encrypted payload. The server rejects any message with a counter value that is not strictly greater than the last received.

At-Rest Encryption
#

Sensitive data in the engagement database is encrypted with the engagement’s master key:

  • Credential secrets are encrypted before storage
  • Session keys and private keys are encrypted per-session
  • Master key is derived from the engagement passphrase using PBKDF2 (600,000 iterations, 16-byte salt)

Encrypted values are stored as nonce || ciphertext || GCM tag in a single blob.

graph LR
    Pass[Engagement Passphrase] --> PBKDF2[PBKDF2]
    PBKDF2 --> MK[Master Key]
    MK --> AES[AES-256-GCM]
    AES --> EncData[Encrypted Fields]

The passphrase is never stored — it must be provided to activate an engagement.

Session Key Rotation
#

When enabled, the server periodically checks session key age:

  • Keys older than key_rotation_session_ttl are marked for rotation
  • On the agent’s next check-in, a new key exchange is performed
  • The transition is transparent to the agent

Config: key_rotation_enabled, key_rotation_session_ttl

Authentication
#

Operator Authentication
#

  • Passwords are hashed with bcrypt
  • Access tokens (3600s TTL) and refresh tokens (86400s TTL) are issued on login
  • Refresh tokens are single-use — consumed and replaced on each refresh
  • Tokens are stored in-memory and validated on every API request
  • Rate limiting: max 5 failed login attempts per 300-second window
  • Force-logout invalidates all tokens for an operator

Agent Authentication
#

  • Agents authenticate via the ECDH key exchange during registration
  • Session tokens (16 bytes) identify sessions in subsequent check-ins
  • The session key provides mutual authentication — only the holder of the correct key can produce valid encrypted messages

Log Redaction
#

When enabled (default), the server filters sensitive values from log output:

  • Credentials and secrets
  • Callback addresses
  • Cryptographic keys and tokens

This prevents accidental exposure of operational data in log files.

P2P Relay Security
#

When agents relay traffic for other agents via P2P chaining:

  • Traffic is end-to-end encrypted between the originating agent and the teamserver
  • Relay agents handle only opaque ciphertext — they cannot decrypt or inspect forwarded messages
  • Chains of 3+ hops are supported (agent -> relay -> relay -> teamserver)
  • If a relay agent is compromised, the forwarded traffic remains confidential

Module Memory Security
#

When the Tanto Loader Spec is implemented, agents MUST:

  • Zero sensitive memory on module unload — cryptographic keys, session tokens, and module data are wiped
  • Clean unload managed modules without crashing the host agent
  • Isolate module memory so a failed module doesn’t corrupt the agent’s state

Kill Dates
#

Every agent build includes a mandatory kill date — a hard expiration timestamp set at build time:

  • When the kill date is reached, the agent self-destructs regardless of teamserver connectivity
  • Self-destruct removes persistence, zeros sensitive memory, and deletes artifacts
  • Kill dates are immutable after deployment — they cannot be extended remotely

Clock Drift Tolerance
#

The clock_drift_tolerance setting (default: 300 seconds) defines acceptable clock drift between the server and agents for crypto operations and status tracking.