Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino’s access to the data at any time, independently of Infino.
Customer-managed encryption keys (CMEK, also called BYOK) let you encrypt a
bring-your-own-bucket (BYOB) database with a key
you own and control in your own cloud KMS. Because the key is yours, you can
revoke Infino’s ability to read the data at any time, independently of Infino.CMEK applies only to BYOB databases — databases whose data lives in your cloud
bucket. The key is configured on your bucket, in your KMS, and Infino is
only ever granted use of it. Infino never holds your key material.
CMEK, like BYOB, is an enterprise feature enabled per account by Infino —
contact your Infino representative to turn it on. Set up
the BYOB database first (see Bring Your Own Bucket);
CMEK adds a key to that same storage binding.
CMEK is available for BYOB on Amazon S3 (AWS KMS), Google Cloud Storage
(Cloud KMS), and Azure Blob Storage (Key Vault). One Azure-specific note:
revoking a key takes effect on a delay, because the storage service caches the
key for a time — see What revocation does.
Three things make a CMEK-encrypted BYOB database work, and they are the same on
every cloud:
Your bucket encrypts with your key. You configure your bucket’s default
encryption to use your customer-managed key, so every object written into it is
encrypted under that key — including everything Infino writes.
You grant Infino’s identity use of the key. The same role or grant Infino
already uses to read and write your bucket is additionally allowed to encrypt
and decrypt with the key — nothing more. It can never export the key, change
it, or use it for anything but your bucket.
Infino verifies the key before serving. When you create the database (or on
an explicit re-verify), Infino confirms your bucket’s default encryption is the
key you named and that it can write and read under it. On each later access
refresh it re-checks only that the key is still usable. If the key cannot be
used, Infino refuses to serve the database rather than fall back to a weaker key.
Because the key lives in your KMS, disabling, deleting, or un-granting it is your
lever: it makes the database unavailable to Infino within one access-refresh
interval, and deleting the key makes the data permanently unreadable by anyone.
Name the key by its key ARN, not an alias ARN. An alias
(arn:aws:kms:...:alias/...) can be repointed to a different key later, so Infino
scopes access to the key itself and rejects an alias ARN at setup. The key and
the bucket must also be in the same region — S3 SSE-KMS requires it, and Infino
checks the key ARN’s region against the bucket’s when you create the database.
2
Set the bucket's default encryption to SSE-KMS
On the BYOB bucket, set default encryption to SSE-KMS and select the key
from step 1. Every object Infino writes then lands encrypted under your key
automatically.S3 Bucket Keys collapse per-object key derivations to roughly one per bucket
and substantially cut your KMS request cost for a write-heavy workload like an
index, so we recommend enabling them. The tradeoff: with a bucket key, S3 caches a
bucket-level data key for a short window, so a key disable can take effect a
little later than with per-object derivation. If you need the tightest revocation,
leave Bucket Keys off and set bucket_key to false when you create the database;
Infino honours that choice on every write.Infino confirms the bucket default at setup by reading your bucket’s encryption
configuration, so the BYOB role also needs s3:GetEncryptionConfiguration on
the bucket. This is a configuration read, not an object write.
3
Grant Infino's role use of the key
The role Infino assumes for your bucket must be allowed to encrypt and decrypt with
your key. Add a statement to the KMS key policy (or an equivalent grant):
kms:GenerateDataKey wraps a data key on write; kms:Decrypt unwraps it on
read. Those two actions are all Infino needs, and all you should grant.
"Resource": "*" in a key policy means this key — the policy is attached to
the key itself and grants no access to any other key.
Recommended: the kms:ViaService condition (set to your bucket’s region). It
confines the grant to calls S3 makes on the role’s behalf, so a leaked role
credential still cannot call KMS outside S3.
4
Add the key to the database's storage binding
Create the BYOB database as in
Bring Your Own Bucket, adding an encryption block
to the storage object:
key_arn — the key ARN from step 1 (not an alias), in the bucket’s region.
bucket_key — true if you enabled S3 Bucket Keys in step 2.
Infino verifies the key during setup by writing and reading back a probe object and
confirming it is encrypted under exactly this key. If the grant is missing or the
key is unusable, verification fails — restore the grant and re-verify.
Create a Cloud KMS key and set it as the bucket default
Create a Cloud KMS key in the same location as your bucket and set it as the
bucket’s default encryption key.
2
Grant the Cloud Storage service agent use of the key
Grant the Cloud Storage service agent of the bucket’s project the role
roles/cloudkms.cryptoKeyEncrypterDecrypter on that key. On GCS, encryption
happens service-side — the storage service’s own service agent calls KMS, not
Infino — so this grant is what lets your bucket encrypt and decrypt with your key.
Infino verifies by reading a probe object’s reported KMS key name back and
confirming it matches the key you named — version-agnostically, so key rotation
needs no action.
On Azure, the storage service caches your key, so a revocation (disable or delete)
takes effect on a delay of roughly 7–30 minutes, not the near-immediate effect
on AWS and GCP — see What revocation does.
Azure CMEK requires a container default encryption scope backed by your Key
Vault key — a storage-account key with no scope is not supported, because Infino
verifies the key by reading the scope back off the data.
1
Create a default encryption scope on the container
Create a default encryption scope on the container, backed by your Key Vault
key, and deny per-blob encryption-scope override so every blob is forced onto
the scope’s key.
2
Grant the storage account's identity access to the key
Grant the storage account’s identity access to the key in Key Vault (via an access
policy or Azure RBAC) so the storage service can wrap and unwrap with it. Encryption
is service-side on Azure, as on GCP.
3
Name the key and scope when you create the database
Your key is a control you hold. The mechanism is the same on every cloud; the
timing differs: on AWS and GCP a disable or deletion bites on the next access
refresh (about five minutes), while on Azure the storage service caches your
key, so a revocation takes roughly 7–30 minutes to take effect.
Any of the following makes the database unavailable to Infino within roughly one
access-refresh interval — about five minutes on AWS and GCP, roughly 7–30 minutes
on Azure — plus a brief eviction:
Disabling the key,
Scheduling the key for deletion (while still within the KMS waiting period), or
Revoking Infino’s access to the key (AWS/GCP: remove the key-policy statement
or grant; Azure: remove the storage account identity’s Key Vault access).
When this happens, Infino’s periodic access refresh exercises your key — it
reads a byte of an object your database already holds, which forces a decrypt (it
writes nothing). Finding the key can no longer decrypt, it takes the safe path: it
stops serving the database and clears its cached data from Infino’s compute —
including any cache left behind after the database scaled to zero — so nothing the
key once protected keeps being served from a local copy. Your data in your bucket
is untouched, and so is the database’s record in Infino.
Two honest limits. The timing is bounded by the refresh cadence, not
instantaneous — a database serving entirely from its local cache does not touch
your key until the next refresh (plus, on Azure, the storage service’s key-cache
delay). And the refresh checks that the key still works, not that it is still the
same key: key identity is verified at create time and on an explicit
re-verify, not on every refresh.
To restore service: re-enable the key (or restore the grant), then re-verify. A
reserved (always-on) database re-verifies itself on its next refresh. A non-reserved
database that was evicted is not running, so a plain request to it is refused while
it is marked unreachable — call
POST /v1/databases/{name}/storage/verify to heal it, and serving resumes. No data
was lost.
Deleting the key (the hard kill switch — irreversible)
If you let the key’s deletion complete — past the KMS waiting period — the data
encrypted under it becomes permanently unreadable by everyone, Infino included.
There is no recovery, by design, because the key material that could decrypt the
objects no longer exists. Use the waiting period as your window to change your mind.
Key rotation needs no action. Objects already written stay readable because each
was wrapped under the key version in effect when it was written, and that version
continues to decrypt it. New writes use the current version. You do not need to tell
Infino, re-verify, or re-create anything when you rotate.
Unavailable within ~one refresh interval (about 5 min on AWS/GCP; roughly 7–30 min on Azure) plus eviction
Untouched
Yes — re-enable or re-grant, then re-verify
Complete key deletion (past the waiting period)
Permanently unreadable, for everyone
Encrypted objects become unrecoverable
No
Rotate the key
No effect; keeps serving
Untouched
n/a — no action needed
For how Infino separates control, compute, and storage, see
Architecture. To enable CMEK on AWS, GCP, or Azure, contact
your Infino representative.
Last modified on October 30, 2026
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Infino","description":"Infino is an open-source retrieval engine for full-text, vector, and SQL search, with your data stored as Apache Parquet on object storage.","colors":{"primary":"#d24011","light":"#e8623a","dark":"#d24011"},"logo":{"light":"https://mintcdn.com/infino-29/sXqDYmwcZ7BW4kvO/logo/infino-logo.png?fit=max\u0026auto=format\u0026n=sXqDYmwcZ7BW4kvO\u0026q=85\u0026s=6bf8ba5e6249a14bb302a90e30e5e18f","dark":"https://mintcdn.com/infino-29/sXqDYmwcZ7BW4kvO/logo/infino-logo.png?fit=max\u0026auto=format\u0026n=sXqDYmwcZ7BW4kvO\u0026q=85\u0026s=6bf8ba5e6249a14bb302a90e30e5e18f","href":"https://infino.ai"},"favicon":"https://mintcdn.com/infino-29/LrgKEC9MS1pd7XX7/favicon.png?fit=max\u0026auto=format\u0026n=LrgKEC9MS1pd7XX7\u0026q=85\u0026s=e08bd7081efa9de5d611ea206ba6e46c","navbar":{"links":[{"href":"https://infino.ai","label":"Home"},{"href":"https://infino.ai/vs","label":"Compare"},{"href":"https://infino.ai/cloud","label":"Infino Cloud"},{"href":"https://github.com/infino-ai/infino","label":"GitHub"}],"primary":{"type":"button","label":"Talk to us","href":"mailto:info@infino.ai"}},"footer":{"socials":{"github":"https://github.com/infino-ai/infino"},"links":[{"header":"Resources","items":[{"label":"GitHub","href":"https://github.com/infino-ai/infino"},{"label":"Issues","href":"https://github.com/infino-ai/infino/issues"}]}]},"search":{"prompt":"Search the Infino docs…"},"seo":{"metatags":{"canonical":"https://infino.ai/docs","og:site_name":"Infino","og:type":"website","og:image":"/images/og-card.png","twitter:card":"summary_large_image","twitter:image":"/images/og-card.png"},"indexing":"all"},"fonts":{"family":"Inter"},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"metadata":{"timestamp":true},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"infino-29","hasAudioNarration":false,"actualSubdomain":"infino-29","customDomains":["infino.ai"],"gitSource":{"type":"github","owner":"infino-ai","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"collectionId":"3b327719-300a-4e6d-9a77-2f4c2319b6e0","liveDeploymentHistoryId":"6ae435a8492eee9d6caa8294","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae435a8492eee9d6caa8294"},"feedback":{"agentFeedback":true,"thumbs":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ae435a8492eee9d6caa8294","clientVersion":"0.0.4054","searchFilterCounts":[{"language":"default","tag":"Documentation","count":25},{"language":"default","tag":"API Reference","count":21},{"language":"default","tag":"REST API","count":18},{"language":"default","tag":"Infino Cloud","count":9},{"language":"default","tag":"Guides","count":9},{"language":"default","tag":"Search","count":7},{"language":"default","tag":"Reference","count":4},{"language":"default","tag":"Databases","count":4},{"language":"default","tag":"Tables","count":4},{"language":"default","tag":"SDKs \u0026 CLI","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"/docs","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"cloud/customer-managed-keys","slug":"/cloud/customer-managed-keys","pageMetadata":{"title":"Customer-Managed Encryption Keys","icon":"lock","tag":"Enterprise","description":"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino's access to the data at any time, independently of Infino.","href":"/cloud/customer-managed-keys"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino’s access to the data at any time, independently of Infino.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Note,Step,Steps,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Customer-managed encryption keys (CMEK, also called BYOK) let you encrypt a\n`,_jsx(_components.a,{href:`/cloud/bring-your-own-bucket`,children:`bring-your-own-bucket (BYOB)`}),` database with a key\n`,_jsx(_components.strong,{children:`you own and control`}),` in your own cloud KMS. Because the key is yours, you can\nrevoke Infino’s ability to read the data at any time, independently of Infino.`]}),`\n`,_jsxs(_components.p,{children:[`CMEK applies only to BYOB databases — databases whose data lives in `,_jsx(_components.strong,{children:`your`}),` cloud\nbucket. The key is configured on `,_jsx(_components.strong,{children:`your`}),` bucket, in `,_jsx(_components.strong,{children:`your`}),` KMS, and Infino is\nonly ever granted `,_jsx(_components.em,{children:`use`}),` of it. `,_jsx(_components.strong,{children:`Infino never holds your key material.`})]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`CMEK, like BYOB, is an `,_jsx(_components.strong,{children:`enterprise feature`}),` enabled per account by Infino —\n`,_jsx(_components.a,{href:`https://infino.ai/talk`,children:`contact your Infino representative`}),` to turn it on. Set up\nthe BYOB database first (see `,_jsx(_components.a,{href:`/cloud/bring-your-own-bucket`,children:`Bring Your Own Bucket`}),`);\nCMEK adds a key to that same storage binding.`]})}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`CMEK is available for BYOB on `,_jsx(_components.strong,{children:`Amazon S3`}),` (AWS KMS), `,_jsx(_components.strong,{children:`Google Cloud Storage`}),`\n(Cloud KMS), and `,_jsx(_components.strong,{children:`Azure Blob Storage`}),` (Key Vault). One Azure-specific note:\nrevoking a key takes effect on a delay, because the storage service caches the\nkey for a time — see `,_jsx(_components.a,{href:`#what-revocation-does-and-how-fast`,children:`What revocation does`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`how-it-works`,children:`How it works`}),`\n`,_jsx(_components.p,{children:`Three things make a CMEK-encrypted BYOB database work, and they are the same on\nevery cloud:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Your bucket encrypts with your key.`}),` You configure your bucket’s default\nencryption to use your customer-managed key, so every object written into it is\nencrypted under that key — including everything Infino writes.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`You grant Infino’s identity use of the key.`}),` The same role or grant Infino\nalready uses to read and write your bucket is additionally allowed to `,_jsx(_components.em,{children:`encrypt\nand decrypt with the key`}),` — nothing more. It can never export the key, change\nit, or use it for anything but your bucket.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Infino verifies the key before serving.`}),` When you create the database (or on\nan explicit re-verify), Infino confirms your bucket’s default encryption is the\nkey `,_jsx(_components.strong,{children:`you named`}),` and that it can write and read under it. On each later access\nrefresh it re-checks only that the key is still `,_jsx(_components.em,{children:`usable`}),`. If the key cannot be\nused, Infino refuses to serve the database rather than fall back to a weaker key.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Because the key lives in your KMS, `,_jsx(_components.strong,{children:`disabling, deleting, or un-granting it is your\nlever`}),`: it makes the database unavailable to Infino within one access-refresh\ninterval, and deleting the key makes the data permanently unreadable by anyone.`]}),`\n`,_jsx(Heading,{level:`2`,id:`aws-amazon-s3-+-aws-kms`,children:`AWS (Amazon S3 + AWS KMS)`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Create a customer-managed KMS key`,children:[_jsxs(_components.p,{children:[`In the `,_jsx(_components.strong,{children:`same region as your bucket`}),`, create a `,_jsx(_components.strong,{children:`customer-managed`}),` symmetric KMS\nkey (not an AWS-managed key). Note its `,_jsx(_components.strong,{children:`key ARN`}),`:`]}),_jsx(CodeBlock,{numberOfLines:`2`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`arn:aws:kms:us-east-1:123456789012:key/abcd1234-5678-90ab-cdef-EXAMPLE11111`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),_jsx(Warning,{children:_jsxs(_components.p,{children:[`Name the key by its `,_jsx(_components.strong,{children:`key ARN`}),`, not an alias ARN. An alias\n(`,_jsx(_components.code,{children:`arn:aws:kms:...:alias/...`}),`) can be repointed to a different key later, so Infino\nscopes access to the key itself and `,_jsx(_components.strong,{children:`rejects an alias ARN`}),` at setup. The key and\nthe bucket must also be in the `,_jsx(_components.strong,{children:`same region`}),` — S3 SSE-KMS requires it, and Infino\nchecks the key ARN’s region against the bucket’s when you create the database.`]})})]}),_jsxs(Step,{title:`Set the bucket's default encryption to SSE-KMS`,children:[_jsxs(_components.p,{children:[`On the BYOB bucket, set `,_jsx(_components.strong,{children:`default encryption`}),` to `,_jsx(_components.strong,{children:`SSE-KMS`}),` and select the key\nfrom step 1. Every object Infino writes then lands encrypted under your key\nautomatically.`]}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`S3 Bucket Keys`}),` collapse per-object key derivations to roughly one per bucket\nand substantially cut your KMS request cost for a write-heavy workload like an\nindex, so we recommend enabling them. The tradeoff: with a bucket key, S3 caches a\nbucket-level data key for a short window, so a key `,_jsx(_components.em,{children:`disable`}),` can take effect a\nlittle later than with per-object derivation. If you need the tightest revocation,\nleave Bucket Keys off and set `,_jsx(_components.code,{children:`bucket_key`}),` to `,_jsx(_components.code,{children:`false`}),` when you create the database;\nInfino honours that choice on every write.`]}),_jsxs(_components.p,{children:[`Infino confirms the bucket default at setup by reading your bucket’s encryption\nconfiguration, so the BYOB role also needs `,_jsx(_components.strong,{children:_jsx(_components.code,{children:`s3:GetEncryptionConfiguration`})}),` on\nthe bucket. This is a configuration read, not an object write.`]})]}),_jsxs(Step,{title:`Grant Infino's role use of the key`,children:[_jsxs(_components.p,{children:[`The role Infino assumes for your bucket must be allowed to encrypt and decrypt with\nyour key. Add a statement to the `,_jsx(_components.strong,{children:`KMS key policy`}),` (or an equivalent grant):`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`12`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Sid\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"AllowInfinoRoleUseOfTheKey\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Effect\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Allow\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Principal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"AWS\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"arn:aws:iam::123456789012:role/your-infino-byob-role\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Action\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"kms:GenerateDataKey\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"kms:Decrypt\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Resource\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"*\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"Condition\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"StringEquals\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"kms:ViaService\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"s3.us-east-1.amazonaws.com\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`kms:GenerateDataKey`}),` wraps a data key on write; `,_jsx(_components.code,{children:`kms:Decrypt`}),` unwraps it on\nread. Those two actions are all Infino needs, and all you should grant.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`\"Resource\": \"*\"`}),` in a `,_jsx(_components.strong,{children:`key policy`}),` means `,_jsx(_components.em,{children:`this key`}),` — the policy is attached to\nthe key itself and grants no access to any other key.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Recommended: the `,_jsx(_components.code,{children:`kms:ViaService`}),` condition`]}),` (set to your bucket’s region). It\nconfines the grant to calls S3 makes on the role’s behalf, so a leaked role\ncredential still cannot call KMS outside S3.`]}),`\n`]})]}),_jsxs(Step,{title:`Add the key to the database's storage binding`,children:[_jsxs(_components.p,{children:[`Create the BYOB database as in\n`,_jsx(_components.a,{href:`/cloud/bring-your-own-bucket`,children:`Bring Your Own Bucket`}),`, adding an `,_jsx(_components.code,{children:`encryption`}),` block\nto the `,_jsx(_components.code,{children:`storage`}),` object:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`jsonc`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`jsonc`,children:_jsxs(_components.code,{language:`jsonc`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"encryption\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"kind\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"aws_kms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"key_arn\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"arn:aws:kms:us-east-1:123456789012:key/abcd1234-5678-90ab-cdef-EXAMPLE11111\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"bucket_key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`key_arn`}),` — the `,_jsx(_components.strong,{children:`key ARN`}),` from step 1 (not an alias), in the bucket’s region.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`bucket_key`}),` — `,_jsx(_components.code,{children:`true`}),` if you enabled S3 Bucket Keys in step 2.`]}),`\n`]}),_jsx(_components.p,{children:`Infino verifies the key during setup by writing and reading back a probe object and\nconfirming it is encrypted under exactly this key. If the grant is missing or the\nkey is unusable, verification fails — restore the grant and re-verify.`})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`gcp-google-cloud-storage-+-cloud-kms`,children:`GCP (Google Cloud Storage + Cloud KMS)`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Create a Cloud KMS key and set it as the bucket default`,children:_jsxs(_components.p,{children:[`Create a Cloud KMS key in the `,_jsx(_components.strong,{children:`same location as your bucket`}),` and set it as the\nbucket’s `,_jsx(_components.strong,{children:`default encryption key`}),`.`]})}),_jsx(Step,{title:`Grant the Cloud Storage service agent use of the key`,children:_jsxs(_components.p,{children:[`Grant the `,_jsx(_components.strong,{children:`Cloud Storage service agent of the bucket’s project`}),` the role\n`,_jsx(_components.code,{children:`roles/cloudkms.cryptoKeyEncrypterDecrypter`}),` on that key. On GCS, encryption\nhappens service-side — the storage service’s own service agent calls KMS, not\nInfino — so this grant is what lets your bucket encrypt and decrypt with your key.`]})}),_jsxs(Step,{title:`Name the key when you create the database`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`jsonc`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`jsonc`,children:_jsxs(_components.code,{language:`jsonc`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"encryption\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"kind\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"gcp_kms\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"key_name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"projects/\u003cproject>/locations/\u003clocation>/keyRings/\u003cring>/cryptoKeys/\u003ckey>\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsx(_components.p,{children:`Infino verifies by reading a probe object’s reported KMS key name back and\nconfirming it matches the key you named — version-agnostically, so key rotation\nneeds no action.`})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`azure-azure-blob-storage-+-key-vault`,children:`Azure (Azure Blob Storage + Key Vault)`}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`On Azure, the storage service caches your key, so a revocation (disable or delete)\ntakes effect on a delay of `,_jsx(_components.strong,{children:`roughly 7–30 minutes`}),`, not the near-immediate effect\non AWS and GCP — see `,_jsx(_components.a,{href:`#what-revocation-does-and-how-fast`,children:`What revocation does`}),`.`]})}),`\n`,_jsxs(_components.p,{children:[`Azure CMEK requires a container `,_jsx(_components.strong,{children:`default encryption scope`}),` backed by your Key\nVault key — a storage-account key with no scope is not supported, because Infino\nverifies the key by reading the scope back off the data.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Create a default encryption scope on the container`,children:_jsxs(_components.p,{children:[`Create a `,_jsx(_components.strong,{children:`default encryption scope`}),` on the container, backed by your Key Vault\nkey, and `,_jsx(_components.strong,{children:`deny per-blob encryption-scope override`}),` so every blob is forced onto\nthe scope’s key.`]})}),_jsx(Step,{title:`Grant the storage account's identity access to the key`,children:_jsx(_components.p,{children:`Grant the storage account’s identity access to the key in Key Vault (via an access\npolicy or Azure RBAC) so the storage service can wrap and unwrap with it. Encryption\nis service-side on Azure, as on GCP.`})}),_jsxs(Step,{title:`Name the key and scope when you create the database`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`jsonc`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`jsonc`,children:_jsxs(_components.code,{language:`jsonc`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"encryption\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"kind\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"azure_vault\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"key_id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://\u003cvault>.vault.azure.net/keys/\u003ckey-name>\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"encryption_scope\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\u003cscope-name>\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsx(_components.p,{children:`Infino verifies by reading a probe blob’s reported encryption scope back and\nconfirming it matches the scope you named.`})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`what-revocation-does-and-how-fast`,children:`What revocation does, and how fast`}),`\n`,_jsxs(_components.p,{children:[`Your key is a control you hold. The `,_jsx(_components.strong,{children:`mechanism`}),` is the same on every cloud; the\n`,_jsx(_components.strong,{children:`timing`}),` differs: on AWS and GCP a disable or deletion bites on the next access\nrefresh (about five minutes), while on `,_jsx(_components.strong,{children:`Azure`}),` the storage service caches your\nkey, so a revocation takes `,_jsx(_components.strong,{children:`roughly 7–30 minutes`}),` to take effect.`]}),`\n`,_jsx(Heading,{level:`3`,id:`making-the-database-unavailable-reversible`,children:`Making the database unavailable (reversible)`}),`\n`,_jsxs(_components.p,{children:[`Any of the following makes the database `,_jsx(_components.strong,{children:`unavailable to Infino`}),` within roughly one\naccess-refresh interval — about five minutes on AWS and GCP, roughly 7–30 minutes\non Azure — plus a brief eviction:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Disabling`}),` the key,`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Scheduling the key for deletion`}),` (while still within the KMS waiting period), or`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Revoking Infino’s access`}),` to the key (AWS/GCP: remove the key-policy statement\nor grant; Azure: remove the storage account identity’s Key Vault access).`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`When this happens, Infino’s periodic access refresh `,_jsx(_components.strong,{children:`exercises your key`}),` — it\nreads a byte of an object your database already holds, which forces a decrypt (it\nwrites nothing). Finding the key can no longer decrypt, it takes the safe path: it\n`,_jsx(_components.strong,{children:`stops serving the database and clears its cached data`}),` from Infino’s compute —\nincluding any cache left behind after the database scaled to zero — so nothing the\nkey once protected keeps being served from a local copy. `,_jsx(_components.strong,{children:`Your data in your bucket\nis untouched`}),`, and so is the database’s record in Infino.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`Two honest limits. The timing is `,_jsx(_components.strong,{children:`bounded by the refresh cadence, not\ninstantaneous`}),` — a database serving entirely from its local cache does not touch\nyour key until the next refresh (plus, on Azure, the storage service’s key-cache\ndelay). And the refresh checks that the key still `,_jsx(_components.em,{children:`works`}),`, not that it is still the\n`,_jsx(_components.em,{children:`same key`}),`: key `,_jsx(_components.strong,{children:`identity`}),` is verified at create time and on an explicit\nre-verify, not on every refresh.`]})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`To restore service:`}),` re-enable the key (or restore the grant), then re-verify. A\nreserved (always-on) database re-verifies itself on its next refresh. A non-reserved\ndatabase that was evicted is not running, so a plain request to it is refused while\nit is marked unreachable — call\n`,_jsx(_components.code,{children:`POST /v1/databases/{name}/storage/verify`}),` to heal it, and serving resumes. No data\nwas lost.`]}),`\n`,_jsx(Heading,{level:`3`,id:`deleting-the-key-the-hard-kill-switch-—-irreversible`,children:`Deleting the key (the hard kill switch — irreversible)`}),`\n`,_jsxs(_components.p,{children:[`If you let the key’s deletion complete — `,_jsx(_components.strong,{children:`past the KMS waiting period`}),` — the data\nencrypted under it becomes `,_jsx(_components.strong,{children:`permanently unreadable by everyone, Infino included`}),`.\nThere is no recovery, by design, because the key material that could decrypt the\nobjects no longer exists. Use the waiting period as your window to change your mind.`]}),`\n`,_jsx(Heading,{level:`3`,id:`rotating-the-key`,children:`Rotating the key`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Key rotation needs no action.`}),` Objects already written stay readable because each\nwas wrapped under the key version in effect when it was written, and that version\ncontinues to decrypt it. New writes use the current version. You do not need to tell\nInfino, re-verify, or re-create anything when you rotate.`]}),`\n`,_jsx(Heading,{level:`2`,id:`summary`,children:`Summary`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Action on your key`}),_jsx(_components.th,{children:`Effect on the database`}),_jsx(_components.th,{children:`Your bucket data`}),_jsx(_components.th,{children:`Reversible?`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Disable, schedule-for-delete, or un-grant`}),_jsx(_components.td,{children:`Unavailable within ~one refresh interval (about 5 min on AWS/GCP; roughly 7–30 min on Azure) plus eviction`}),_jsx(_components.td,{children:`Untouched`}),_jsx(_components.td,{children:`Yes — re-enable or re-grant, then re-verify`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Complete key deletion (past the waiting period)`}),_jsx(_components.td,{children:`Permanently unreadable, for everyone`}),_jsx(_components.td,{children:`Encrypted objects become unrecoverable`}),_jsx(_components.td,{children:_jsx(_components.strong,{children:`No`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Rotate the key`}),_jsx(_components.td,{children:`No effect; keeps serving`}),_jsx(_components.td,{children:`Untouched`}),_jsx(_components.td,{children:`n/a — no action needed`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`For how Infino separates control, compute, and storage, see\n`,_jsx(_components.a,{href:`/cloud/architecture`,children:`Architecture`}),`. To enable CMEK on AWS, GCP, or Azure, contact\nyour Infino representative.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Customer-Managed Encryption Keys","icon":"lock","tag":"Enterprise","description":"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino's access to the data at any time, independently of Infino.","href":"/cloud/customer-managed-keys"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"How it works","slug":"how-it-works","depth":2,"children":[]},{"title":"AWS (Amazon S3 + AWS KMS)","slug":"aws-amazon-s3-+-aws-kms","depth":2,"children":[]},{"title":"GCP (Google Cloud Storage + Cloud KMS)","slug":"gcp-google-cloud-storage-+-cloud-kms","depth":2,"children":[]},{"title":"Azure (Azure Blob Storage + Key Vault)","slug":"azure-azure-blob-storage-+-key-vault","depth":2,"children":[]},{"title":"What revocation does, and how fast","slug":"what-revocation-does-and-how-fast","depth":2,"children":[{"title":"Making the database unavailable (reversible)","slug":"making-the-database-unavailable-reversible","depth":3,"children":[]},{"title":"Deleting the key (the hard kill switch — irreversible)","slug":"deleting-the-key-the-hard-kill-switch-—-irreversible","depth":3,"children":[]},{"title":"Rotating the key","slug":"rotating-the-key","depth":3,"children":[]}]},{"title":"Summary","slug":"summary","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/infino-29/645d308d2f9fae79/structured-data.js","/docs/_mintlify/custom/infino-29/ec3d5239f2e7ff69/same-tab-links.js","/docs/_mintlify/custom/infino-29/cf391a6d1558677e/context7-widget.js"],"subdomain":"infino-29","siteName":"Infino","title":"Customer-Managed Encryption Keys - Infino","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-30T06:14:04.907Z","gitLastModified":"2026-10-30T06:13:56.000Z","originalFileLocation":"cloud/customer-managed-keys.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino\u0026#x27;s access to the data at any time, independently of Infino.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Infino\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Customer-Managed Encryption Keys - Infino\">\u003cmeta data-mint-head property=\"og:description\" content=\"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino\u0026#x27;s access to the data at any time, independently of Infino.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Infino\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://infino.ai/docs/cloud/customer-managed-keys\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://infino-29.mintlify.app/images/og-card.png\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Customer-Managed Encryption Keys - Infino\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino\u0026#x27;s access to the data at any time, independently of Infino.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://infino-29.mintlify.app/images/og-card.png\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/infino-29/QxzEBvRaDzIUbPUA/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Infino\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#d24011\">\u003clink data-mint-head rel=\"canonical\" href=\"https://infino.ai/docs/cloud/customer-managed-keys\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/cloud/customer-managed-keys.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://infino.ai/#organization\",\"name\":\"Infino\",\"url\":\"https://infino.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/infino-29/sXqDYmwcZ7BW4kvO/logo/infino-logo.png?fit=max\u0026auto=format\u0026n=sXqDYmwcZ7BW4kvO\u0026q=85\u0026s=6bf8ba5e6249a14bb302a90e30e5e18f\"}},{\"@type\":\"WebSite\",\"@id\":\"https://infino.ai/docs#website\",\"name\":\"Infino\",\"url\":\"https://infino.ai/docs\",\"publisher\":{\"@id\":\"https://infino.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://infino.ai/docs/cloud/customer-managed-keys#webpage\",\"url\":\"https://infino.ai/docs/cloud/customer-managed-keys\",\"name\":\"Customer-Managed Encryption Keys\",\"description\":\"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino's access to the data at any time, independently of Infino.\",\"dateModified\":\"2026-10-30T06:13:56.000Z\",\"isPartOf\":{\"@id\":\"https://infino.ai/docs#website\"},\"breadcrumb\":{\"@id\":\"https://infino.ai/docs/cloud/customer-managed-keys#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://infino.ai/docs/cloud/customer-managed-keys#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Infino Cloud\",\"item\":\"https://infino.ai/docs/cloud/index\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Customer-Managed Encryption Keys\",\"item\":\"https://infino.ai/docs/cloud/customer-managed-keys\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://infino.ai/docs/cloud/customer-managed-keys#article\",\"headline\":\"Customer-Managed Encryption Keys\",\"name\":\"Customer-Managed Encryption Keys\",\"description\":\"Encrypt a bring-your-own-bucket database with a key you own and control in your own cloud KMS — AWS KMS, Google Cloud KMS, or Azure Key Vault — so you can revoke Infino's access to the data at any time, independently of Infino.\",\"url\":\"https://infino.ai/docs/cloud/customer-managed-keys\",\"mainEntityOfPage\":{\"@id\":\"https://infino.ai/docs/cloud/customer-managed-keys#webpage\"},\"image\":\"https://infino.ai/images/og-card.png\",\"dateModified\":\"2026-10-30T06:13:56.000Z\",\"publisher\":{\"@id\":\"https://infino.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://infino.ai/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Infino\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Infino","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get started","pages":[{"title":"Infino: open-source retrieval engine for AI apps","icon":"house","href":""},{"title":"Quickstart: install Infino and run your first search","icon":"rocket","href":"/quickstart"},{"title":"Core concepts: how Infino indexes and queries Parquet","icon":"diagram-project","href":"/core-concepts"}]},{"group":"Guides","pages":[{"title":"Connect \u0026 storage: memory, disk, S3, and Azure","icon":"cloud","href":"/guides/storage"},{"title":"Tables: schemas, rows, updates, and compaction","icon":"table","href":"/guides/tables"},{"title":"Embeddings: bring your own vectors to Infino","icon":"vector-square","href":"/guides/embeddings"},{"title":"Indexing: BM25 full-text and IVF vector indexes","icon":"sitemap","href":"/guides/indexing"},{"title":"Search: BM25, vector, hybrid, and SQL retrieval","icon":"magnifying-glass","href":"/guides/search"},{"title":"Implementing hybrid search on Apache Parquet files","icon":"layer-group","href":"/guides/hybrid-search-on-parquet"},{"title":"Integrating SQL analytics with vector and full-text search","icon":"table","href":"/guides/sql-analytics-with-search"},{"title":"Building a hybrid RAG pipeline over company documents","icon":"file-lines","href":"/guides/hybrid-rag-over-documents"},{"title":"Parquet interop: read Infino tables with DuckDB and pandas","icon":"lock-open","href":"/guides/parquet-interop"}]},{"group":"Infino Cloud","pages":[{"title":"Infino Cloud","icon":"building","href":"/cloud/index"},{"title":"Quickstart","icon":"cloud","href":"/cloud/quickstart"},{"title":"Authentication","icon":"key","href":"/cloud/authentication"},{"title":"Architecture","icon":"sitemap","href":"/cloud/architecture"},{"title":"Bring Your Own Bucket","icon":"bucket","tag":"Enterprise","description":"Host an Infino Cloud database in your own S3, GCS, or Azure bucket — your data stays in your account, reached through an identity you authorize, while Infino runs the control plane and serving layer.","href":"/cloud/bring-your-own-bucket"},{"title":"Customer-Managed Encryption Keys","icon":"lock","tag":"Enterprise","href":"/cloud/customer-managed-keys"},{"title":"Errors \u0026 retries","icon":"arrows-rotate","description":"Infino Cloud starts databases on demand, so the first request to an idle or brand-new database can briefly return a transient 503. Learn which errors clear on a retry and how to handle them.","href":"/cloud/errors"},{"title":"Limits","icon":"gauge-high","href":"/cloud/limits"},{"title":"FAQ","icon":"circle-question","href":"/cloud/faq"}]},{"group":"Reference","pages":[{"title":"SQL reference for Infino queries and search functions","icon":"database","href":"/sql-reference"},{"title":"Infino FAQ: servers, durability, search, and embeddings","icon":"circle-question","href":"/faq"},{"title":"Infino tradeoffs: where it fits and where it doesn't","icon":"scale-balanced","href":"/tradeoffs"},{"title":"Troubleshooting common Infino errors and fixes","icon":"wrench","href":"/troubleshooting"}]}]},{"tab":"Integrations","pages":[{"title":"Integrations","href":"/integrations/mcp"}]},{"tab":"Tutorials","pages":[{"title":"Tutorials","href":"/tutorials"}]},{"tab":"Use Cases","pages":[{"title":"Use Cases","href":"/use-cases"}]},{"tab":"Demos","pages":[{"title":"Demos","href":"/demos"}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference"}]}]},"basePath":"","title":"Customer-Managed Encryption Keys - Infino","buildId":"dpl_GWQzn6k13MqphA3qck3hQKoQXDzM","deploymentId":"dpl_GWQzn6k13MqphA3qck3hQKoQXDzM","dynamics":[],"chunks":[]}