Registers the AGENT-scoped caller's active RSA public key. The private key stays on the agent runtime and never traverses the server.
POST /api/v1/machine/vault/public-key| Header | Type | Required | Description |
|---|---|---|---|
X-API-Key | string | Yes | Your AGENT-scoped API key |
{
"encryptionKeyId": "507f1f77bcf86cd799439015",
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...\n-----END PUBLIC KEY-----",
"previousEncryptionKeyId": "507f1f77bcf86cd799439010",
"rotationSignature": "base64-signature",
"rewrappedVaultKeys": [
{
"vaultId": "507f1f77bcf86cd799439011",
"encryptionKeyId": "507f1f77bcf86cd799439015",
"signerEncryptionKeyId": "507f1f77bcf86cd799439015",
"signerType": "AGENT_ENCRYPTION_KEY",
"dekVersion": 3,
"wrappedDek": "base64-ciphertext",
"wrappedDekSignature": "base64-signature"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
encryptionKeyId | string | No | Optional client-chosen ID for the new active encryption key. Required when rotating a key that still has active wrapped vault access |
publicKey | string | Yes | PEM-encoded RSA public key generated and stored locally by the agent |
previousEncryptionKeyId | string | No | Previous active agent key ID. Required when rotating to a different key |
rotationSignature | string | No | RSA-PSS signature from the previous private key approving the new public key |
rewrappedVaultKeys | array | No | Full replacement wrapped-DEK batch for every still-active vault assignment on the old key. Required when rotating away from a key that still has active wrapped vault access |
Success (201 Created)
{
"encryptionKeyId": "507f1f77bcf86cd799439015",
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...\n-----END PUBLIC KEY-----",
"fingerprint": "b5d44d6c7c1c1d4b8f31b1d9d8445d6c7c1c1d4b8f31b1d9d8445d6c7c1c1d4b",
"previousEncryptionKeyId": "507f1f77bcf86cd799439010",
"rotationSignature": "base64-signature"
}| Field | Type | Description |
|---|---|---|
encryptionKeyId | string | Active agent encryption key ID used as the wrapped-DEK recipient |
publicKey | string | PEM-encoded RSA public key currently active for the agent |
fingerprint | string | SHA-256 fingerprint of the public key |
previousEncryptionKeyId | string | null | Previous key ID for continuity verification |
rotationSignature | string | null | Continuity signature verifiable by the previous public key |
400 Bad Request - Rotation proof missing or invalid
{
"message": "Key rotation requires previousEncryptionKeyId and rotationSignature."
}400 Bad Request - Rotation missing the required re-wrap batch
{
"message": "Rotating an active agent key with wrapped vault access requires encryptionKeyId so the runtime can pre-sign replacement wrapped DEKs."
}403 Forbidden - Not an AGENT-scoped API key
{
"error": {
"code": "agent_scope_required",
"message": "This endpoint requires an AGENT-scoped API key."
}
}404 Not Found - Agent not found
{
"error": {
"code": "agent_not_found",
"message": "Agent not found or you do not have access to it."
}
}curl -X POST "https://r4.dev/api/v1/machine/vault/public-key" \
-H "X-API-Key: rk_abc123def456.ghijklmnopqrstuvwxyz" \
-H "Content-Type: application/json" \
-d '{
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...\n-----END PUBLIC KEY-----"
}'rewrappedVaultKeys batch, and the backend archives the old wrapped-DEK rows plus the old key in one transactionPOST /vault/public-key on first boot before operators grant vault-backed access to the agent.GET /vault/:vaultId/wrapped-key for the vault DEK encrypted to encryptionKeyId.GET /vault/:vaultId/public-keys to verify the wrapped-DEK signer.If you are sending a different public key, include previousEncryptionKeyId and a rotationSignature from the current private key. If that old key still has active wrapped vault access, also include encryptionKeyId plus a rewrappedVaultKeys entry for every active vault DEK so the server can rotate and re-wrap atomically.