Architecture and Security
Oris sits between your AI agents and your payment providers. It verifies identity, enforces policy, screens for safety, and logs every action. This page covers the security architecture that protects your provider credentials and your agents' transactions.
BYOK Architecture
Oris follows a Bring Your Own Keys model. You maintain your own accounts with payment providers such as Pimlico, Circle, Turnkey, or Fireblocks. You register your provider API keys with Oris through the /oris/developers/provider-keys endpoint. Oris encrypts those keys with envelope encryption and stores only ciphertext in the database.
When your agent initiates a payment, Oris decrypts the key in ephemeral memory, calls your provider to execute the transaction, and wipes the plaintext key from the process heap. Oris never holds funds. Oris never maintains provider accounts on your behalf. The payment relationship exists between you and your provider.
|
[ Decrypt Provider Key ] --> Your Provider --> Blockchain
|
[ Wipe Key + Audit Log ]
Oris provides the orchestration layer: identity, policy, safety, and audit. Your provider executes the on-chain transaction.
Envelope Encryption
Oris uses a two-layer encryption scheme to protect your provider credentials. The outer layer is a key encryption key (KEK) managed by HashiCorp Vault Transit. The inner layer is a per-developer data encryption key (DEK) that encrypts the actual provider keys.
- When you register provider keys, Oris generates a fresh AES-256-GCM data encryption key (DEK) for your developer account.
- The DEK encrypts your provider API keys. The resulting ciphertext is stored in the database.
- HashiCorp Vault Transit encrypts the DEK itself (the KEK operation). The plaintext DEK is destroyed immediately.
- Both ciphertexts are stored in the database: the encrypted provider keys and the encrypted DEK.
- On every payment request, Vault Transit decrypts the DEK, the DEK decrypts the provider keys, and the plaintext key is used for a single API call to your provider.
Ephemeral Memory Management
After every request, Oris wipes the plaintext provider key from memory at the C level. Python's garbage collector does not handle sensitive data deterministically. A deallocated string can persist in heap memory for an unpredictable duration. Oris uses ctypes.memset to overwrite the memory backing the Python string object with null bytes before the reference is released.
The SecureProviderKeys context manager automates this process. Every key is wiped when the request scope exits, regardless of whether the request succeeded or failed.
Vault Transit
Oris uses HashiCorp Vault Transit as the key encryption key (KEK) layer. The Transit secret engine performs cryptographic operations on data in transit without storing the data. Key material never leaves Vault.
KEK rotation happens inside Vault with zero application downtime. When you rotate the KEK, old DEKs remain decryptable with their original KEK version. New encryption operations use the latest KEK version. This allows key rotation without re-encrypting every developer's stored credentials.
| Property | Value |
|---|---|
| Algorithm | aes256-gcm96 |
| Key derivation | Per-developer, per-key-version |
| Rotation | Zero-downtime, backward-compatible |
| Key export | Disabled (keys cannot leave Vault) |
| Audit logging | Every encrypt/decrypt operation is logged |
Authentication
Every API request is signed with Ed25519 asymmetric cryptography. The SDK constructs a canonical request string from the timestamp, nonce, HTTP method, path, and SHA-256 hash of the body. It signs this string with your private_key (the oris_pk_* seed) and sends the signature in the X-Request-Signature header. Oris stores only your public key; private keys never leave your environment.
The server verifies the signature with the developer's public key in constant time. A 30-second nonce window prevents replay attacks. Redis SETNX with a 30-second TTL enforces nonce uniqueness. If the same nonce appears twice within 30 seconds, the second request is rejected.
| Header | Purpose |
|---|---|
Authorization | Developer API key for identification |
X-Request-Signature | Ed25519 signature for integrity |
X-Timestamp | Unix epoch seconds (30-second tolerance) |
X-Nonce | Unique token (Redis SETNX enforced) |
Safety Screening
Every transaction passes through the Veris safety engine before reaching your payment provider. The engine evaluates counterparty risk, sanctions exposure, and transaction patterns. Evaluation completes in under 100 milliseconds for the p95 case.
The architecture is fail-closed. If the safety engine is unavailable or returns an error, Oris blocks the transaction. There is no bypass mechanism. This behavior is enforced at the infrastructure level and cannot be overridden by API parameters or SDK configuration.
Safety screening powered by Veris.
Audit Trail
Every action in Oris is recorded in a SHA-256 hash chain. Each audit entry contains the action type, actor identity, timestamp, request parameters, and the result. Each entry also references the previous entry's hash value. This creates a tamper-evident chain where retroactive modification of any entry breaks the hash sequence from that point forward.
Every 100 entries, Oris writes the latest hash to HashiCorp Vault KV for independent cross-verification. An auditor can compare the chain's computed hash at any checkpoint against the value stored in Vault. If they diverge, the chain has been modified.
| Field | Description |
|---|---|
action | Operation type (payment.send, policy.evaluate, agent.register) |
actor_id | Developer or agent UUID |
timestamp | Server-side UTC timestamp |
request_hash | SHA-256 of the request payload |
result | Outcome (success, rejected, error) |
prev_hash | SHA-256 of the previous audit entry |
entry_hash | SHA-256 of this entry (includes prev_hash) |
Request Lifecycle
Every payment request passes through six stages in sequence. If any stage fails, the request is rejected and the audit log records the failure point.
| Stage | Operation | Latency (p95) |
|---|---|---|
| 1 | Ed25519 signature verification + nonce check | < 2ms |
| 2 | KYA identity verification (agent trust level check) | < 5ms |
| 3 | Spending policy evaluation (Redis-cached rules) | < 10ms |
| 4 | Safety screening (counterparty risk, sanctions) | < 100ms |
| 5 | Provider key decryption + provider API call | 200ms - 2s |
| 6 | Audit log entry + hash chain extension | < 5ms |
Stages 1 through 4 are internal to Oris. Stage 5 latency depends on your provider and the target blockchain. Stage 6 runs asynchronously after the response is returned to the caller.
Support
For architecture or security questions, email developers@fluxa.ventures.