Security

Your own KMS key

Bring your own AWS KMS key and your workspace's documents are written under a key you own, in your account, which you can rotate or revoke without asking us. Saving the key runs a real encrypt against our bucket, so a key policy that is not quite right fails on the settings screen instead of on your next upload.

What your key covers

This is the sentence the API returns with every response on this setting, word for word, because it is the one place the product says exactly which copies your key reaches:

Your key encrypts this workspace's documents and extracted text in the Engram document bucket. The cartridge store is written by the serving stack and stays on the platform default key for now.

So: the file you uploaded and the text we extracted from it are on your key. The compiled memory the serving stack builds from that text is written by the serving box, not by the control plane, and it stays on the platform key until that work lands. Saying so here is cheaper than you discovering it in a security review.

Everything is server-side encrypted either way. Without a customer key, writes use the bucket default.

The key policy to grant

Create a symmetric encryption key in AWS KMS, in the same region as the deployment you are on, and add a statement to its key policy letting the Engram platform role use it. The principal is the role the platform runs as in the Engram AWS account, and the AWS console shows you the exact ARN: a denied save writes a CloudTrail event in your own account whose caller identity is the principal to grant. Support will confirm it up front if you would rather not go round that way.

{
  "Sid": "AllowEngramToEncryptThisWorkspacesDocuments",
  "Effect": "Allow",
  "Principal": { "AWS": "<engram platform role arn>" },
  "Action": [
    "kms:DescribeKey",
    "kms:GenerateDataKey",
    "kms:Encrypt",
    "kms:Decrypt"
  ],
  "Resource": "*"
}

Four actions, and each one is load-bearing. kms:DescribeKey is how we check the key exists and is enabled. kms:GenerateDataKey and kms:Encrypt are what S3 needs to write an object under your key. kms:Decrypt is what reading it back needs, which is every question anyone asks of those documents. Resource is * because in a key policy the resource is the key the policy is attached to.

Revoking the grant, disabling the key or scheduling it for deletion stops us reading the documents written under it. That is the control you are buying, and it is worth saying out loud: it is not reversible by us.

Turn it on

In the app: Settings, Security, Encryption key, paste the ARN and save. Over the API:

curl -s -X PUT https://api.engramdynamics.org/enterprise/kms-key \
  -H "Authorization: Bearer <your key>" \
  -H "Content-Type: application/json" \
  -d '{"key_arn": "arn:aws:kms:us-east-1:111122223333:key/1a2b3c4d-5e6f-7890-abcd-ef1234567890"}'
{
  "key_arn": "arn:aws:kms:us-east-1:111122223333:key/1a2b3c4d-5e6f-7890-abcd-ef1234567890",
  "scope": "Your key encrypts this workspace's documents and extracted text in the Engram document bucket. The cartridge store is written by the serving stack and stays on the platform default key for now.",
  "verified": true
}

From that moment, new writes for this workspace carry server-side encryption with your key.

What the save actually checks

Saving a key runs two checks, because each catches a different mistake.

  1. Describe the key. This catches a typo, a key in the wrong account or region, and a key that is disabled or pending deletion. A key that is not enabled is refused with its state named.
  2. Write one object with it. This is the check that matters more and that describing the key cannot see: whether your key policy actually lets our role encrypt. We put a tiny object into the document bucket under the reserved prefix corpora/_kms-check/, with server-side encryption set to your key, then delete it again. The prefix is outside any document base of yours, so the check can never collide with real content, and the delete runs even if the put failed, so the check never leaves anything behind.

If the put is denied you get a 400 saying so, on the screen where you typed the ARN:

{
  "detail": "That key exists but we could not encrypt with it. Add kms:GenerateDataKey and kms:Decrypt for the Engram account to the key policy, then try again."
}

Rotating, clearing and downgrading

Two facts about S3 are worth knowing before you change anything, because they are S3's behaviour and not ours.

curl -s -X PUT https://api.engramdynamics.org/enterprise/kms-key \
  -H "Authorization: Bearer <your key>" \
  -H "Content-Type: application/json" \
  -d '{"key_arn": null}'

Setting a key is plan-gated. Clearing one never is. A workspace that moves to a plan without the customer key can always take the key off, on any tier, and documents already written keep being decrypted with it whatever plan you are on. A downgrade that made your own documents unreadable would be a far worse outcome than an unenforced promise.

Every change writes an enterprise.kms_key_set row to the audit log. Which plan carries the setting is in the plan table.

Next

Data lifecycle and deletion covers what happens to those encrypted copies when you delete a document, including the recycle-bin window.