Credential Encryption (PMEK)

For: Platform engineers and security teams evaluating the data-at-rest security model for inline AI provider credentials.

Security Overview | mTLS | Bundle Signing | Credential Encryption

Axemere uses PMEK (Platform-Managed Encryption Keys) to encrypt AI provider API keys before they are stored in the database. A database backup, stolen snapshot, or SQL injection attack yields only ciphertext; the encryption key is never stored alongside the data.

Table of Contents


What Is Encrypted

Credential modeWhat is stored in DBEncrypted?
inlineActual AI provider API keyYes — AES-256-GCM
aliasName of an environment variable (e.g. OPENAI_API_KEY)No — not a secret
byokEmpty: caller supplies the key at request timeN/A

Only inline mode stores a real secret in the database. alias and byok modes do not need encryption because no secret is persisted.


How Envelope Encryption Works

Axemere uses AES-256-GCM (NIST SP 800-38D, authenticated encryption) with a platform key supplied via environment variable. The ciphertext is self-contained: it includes the nonce and authentication tag alongside the encrypted value.

AES-256-GCM
Encrypt(key, nonce, plaintext)

Stored in DB
credentials.secret_ref

Read

AES-256-GCM
Decrypt(key, nonce, ciphertext)

key material

key material

Platform Key
MVGC_CP_PMEK_KEY
(env var, never in DB)

Plaintext API key
sk-proj-...

Ciphertext
pmek1:base64(nonce+ciphertext+tag)

Database

Plaintext API key
sent to gateway over mTLS


Encryption Flow

When an inline credential is registered via the admin API or console:

  1. The CP server reads the api_key value from the request.
  2. It calls SecretBackend.Encrypt(orgID, plaintext).
  3. A random 12-byte nonce is generated.
  4. AES-256-GCM encrypts the value: ciphertext = Encrypt(platformKey, nonce, plaintext).
  5. The result is base64-encoded and prefixed with pmek1: to mark the version.
  6. The ciphertext string is stored in credentials.secret_ref; no plaintext ever reaches the DB.

Decryption Flow

When a gateway requests its credential set via the ListNodeCredentials gRPC call:

  1. The CP server reads the ciphertext from credentials.secret_ref.
  2. It detects the pmek1: prefix and routes to the PMEK backend.
  3. It calls SecretBackend.Decrypt(orgID, ciphertext).
  4. The nonce is extracted and AES-256-GCM decrypts the value.
  5. The plaintext API key is returned to the gateway over mTLS; it is never stored or logged by the CP.
DatabaseControl PlaneGatewayDatabaseControl PlaneGatewayKey used for outbound request to AI provider, never loggedListNodeCredentials(org_id, node_id) [mTLS]SELECT secret_ref FROM credentials WHERE org_id=?AND (org_wide OR assigned to node_id)"pmek1:base64(nonce+ct+tag)"Decrypt(platformKey, nonce, ct)plaintext API key [over mTLS]

Credential Modes and Encryption Scope

mode: inline
api_key: sk-proj-...

mode: alias
secret_ref: OPENAI_API_KEY

mode: byok
secret_ref: empty

Credential Registration
PUT /v1/admin/credentials

Encrypt
AES-256-GCM

Store as-is
(env var name, not secret)

Nothing stored
(caller supplies key per-request)

DB: pmek1:...

DB: OPENAI_API_KEY

DB: null


Threat Model

ThreatMitigated by PMEK?Notes
Database backup / dump theftYesOnly ciphertext in DB; key not stored there
Misconfigured DB IAMYesSame — ciphertext only
SQL injection on CP DBYesOnly ciphertext reachable
Compromised CP process memoryNoPlaintext in memory during request lifecycle
Compromised gateway process memoryNoGateway receives plaintext over mTLS for use in outbound requests
mTLS interceptionNoSeparate concern: see mTLS guide
Insider with access to CP infra AND platform keyNoMitigated by future CMEK (per-org keys in customer-managed KMS)

PMEK protects the database at rest. It does not protect in-flight data or process memory. That is the correct and intended scope.


See Also