Sunday, October 4, 2026

How Exadata, Exascale, and Autonomous Dedicated on Oracle Database@AWS Use Your AWS KMS Key for TDE (Without Storing Any AWS Keys)

Valid as of October 4, 2026. Oracle Database@AWS is a relatively new service that's growing fast, with new features and improvements landing regularly. Steps, screens, and limits may have changed since this was written. Check the current Oracle and AWS docs before you rely on it.

Three Oracle Database@AWS services can keep their TDE master encryption keys in AWS KMS, using a customer managed key you own:

ServiceAWS KMS integration GADocs
Exadata Database Service on Dedicated Infrastructure (ExaDB-D)November 18, 2025ExaDB-D AWS KMS
Autonomous AI Database on Dedicated Infrastructure (ADB-D)January 20, 2026ADB-D AWS KMS
Exadata Database Service on Exascale Infrastructure (ExaDB-XS)August 2026ExaDB-XS AWS KMS, ODB@AWS Protect Exascale Database

All three use the same mechanism. The only real difference is which VM cluster carries the identity: an Exadata VM cluster, an Exascale VM cluster, or an Autonomous VM cluster. I'll explain it with ExaDB-D, then cover what changes for the others in their own section.

That raises an obvious question. The VM cluster is an OCI resource: it's managed from the OCI console and has an OCI identity. AWS KMS only trusts AWS IAM principals. So how does a VM that AWS knows nothing about get permission to use your KMS key?

The answer is OIDC federation, the same idea behind GitHub Actions or EKS pods getting AWS access without access keys. This post goes through how it works, piece by piece.

Not covered here: Autonomous Serverless (ADB-S). ADB-S uses a different model. There's no OIDC provider or identity connector. Instead, you create an IAM role in your account that trusts an Oracle-owned AWS role (the "OCI trusted service account role ARN" shown in the console), usually protected with an external ID (database, compartment, or tenancy OCID). That role then gets key-user access to your KMS key (ADB-S AWS KMS). It deserves its own post.


The short version

  1. OCI vouches for the VM cluster. Your OCI identity domain acts as an identity provider and issues a signed token that says "this is VM cluster ocid1…".
  2. AWS trusts OCI's signature. An IAM OIDC identity provider in your AWS account trusts that identity domain. An IAM role trusts tokens from that provider.
  3. STS swaps the token for temporary AWS credentials for that role.
  4. KMS lets the role unwrap the database's master key, because your key policy allows it.

Nothing long-lived is stored on the VM. Every KMS call is checked against your key policy and logged in CloudTrail.


The pieces and who trusts whom

PieceWhereWhat it does
OCI identity domainOCIActs as the OIDC issuer. It authenticates the database so it can reach AWS KMS. Created automatically during ODB@AWS onboarding for accounts linked after GA.
IAM OIDC identity providerAWSTells AWS to trust tokens signed by that OCI identity domain URL. There's one per AWS account.
IAM role (WebIdentityRole)AWSWhat the VM cluster becomes in AWS. Its trust policy accepts tokens from the OIDC provider and can be limited to one VM cluster OCID.
KMS customer managed keyAWSSymmetric encrypt/decrypt key, backed by KMS or CloudHSM. Its key policy grants the role DescribeKey, Encrypt, and Decrypt.
Identity connectorOCILinks the VM cluster to the IAM role ARN. Created when you associate the role with the cluster.
Registered AWS keyOCIAn OCI resource (oracle-db-aws-keys) that points to your KMS key ARN, so OCI can show it in the database encryption settings.
OCI IAM policyOCIAllows the VM cluster's resource principal (type cloudvmcluster) to read registered AWS keys.
ODB network integrationsAWS AZSTS and KMS service integrations must be on so the VMs can reach those AWS endpoints privately.
PKCS#11 multicloud driverVM clusterInstalled automatically when you enable AWS key management. The database talks to it like a hardware security module (HSM), and it talks to STS and KMS.

A resource principal is OCI's way of giving a resource (here, the VM cluster) its own identity, so it can call services as itself instead of as a user. The policy that unlocks it looks like this:

Allow any-user to read oracle-db-aws-keys in compartment id <compartment-ocid>
  where all { request.principal.type = 'cloudvmcluster' }

If the registered key and the VM cluster are in different compartments, Oracle's docs say you need the policy in both compartments.


Setup, mapped to what each step creates

Following Oracle's step-by-step tutorial:

StepWhere you clickWhat it builds
1. Verify the OCI identity domainAWS console → Oracle Database@AWS → SettingsThe OIDC issuer on the OCI side
2. Turn on STS + KMS in the ODB networkAWS console → ODB networks → ModifyThe network path from the VMs to STS and KMS
3. Run the CloudFormation stackVM cluster → IAM service roles → CloudFormation linkIAM OIDC provider + IAM role. Leave OIDCProviderArn blank the first time and reuse it after that.
4. Associate the IAM roleVM cluster → IAM service roles → AssociateThe identity connector (status "Connected")
5. Create the KMS keyAWS KMS → Customer managed keysThe key and a key policy granting the role access
6. Register the key in OCIOCI → Database Multicloud Integrations → AWS Integration → AWS KeysA registered AWS key (Discover needs DescribeKey)
7. Enable AWS key managementOCI → VM cluster → EnableThe PKCS#11 driver on the VMs
8. Use itNew database, or "Change" on an existing oneA database whose master keys are protected by KMS

The CloudFormation stack, demystified

The stack creates two things:

  • The OIDC provider. It records the OCI identity domain URL as a trusted issuer.
  • The IAM role. It allows sts:AssumeRoleWithWebIdentity from that provider.

The ResourceOcid and RoleName parameters give you per-resource isolation: the role only accepts tokens for that one VM cluster. Leave them blank if you don't need that isolation.

A trust policy of that kind generally looks like this. It's illustrative only, so check the real one in your stack:

{
  "Effect": "Allow",
  "Principal": { "Federated": "arn:aws:iam::<account>:oidc-provider/<identity-domain-host>" },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringEquals": { "<identity-domain-host>:sub": "<vm-cluster-ocid>" }
  }
}

The KMS key policy from Oracle's docs grants the role these actions:

{ "Sid": "KMSKeyMetadata", "Effect": "Allow",
  "Principal": { "AWS": "<role-arn>" }, "Action": ["kms:DescribeKey"], "Resource": "*" },
{ "Sid": "KeyUsage", "Effect": "Allow",
  "Principal": { "AWS": "<role-arn>" }, "Action": ["kms:Encrypt", "kms:Decrypt"], "Resource": "*" }

What happens at runtime

When the database opens its keystore (at startup, when a PDB opens, or on key rotation), the flow is:

  1. The database asks the PKCS#11 driver for its master key. To the database, AWS KMS looks like an HSM keystore.
  2. The driver asks the OCI identity domain for a token as the VM cluster's resource principal.
  3. The identity domain returns a signed OIDC token (JWT) that identifies the VM cluster.
  4. The driver calls STS AssumeRoleWithWebIdentity with that token and the role ARN from the identity connector.
  5. STS checks the token against the OIDC provider (signature and issuer) and the role's trust policy (for example, the VM cluster OCID).
  6. STS returns temporary credentials. They expire on their own.
  7. The driver calls kms:Decrypt with an encryption context naming the master key ID (MKID = ORACLE.TDE.HSM.MK.…).
  8. KMS checks the key policy, including any Deny rules, and logs the call to CloudTrail.
  9. KMS returns the unwrapped master key to the driver.
  10. The database uses it in memory to unlock the tablespace keys.

Steps 2–6 are the standard OIDC web identity flow, and the documented parts (identity domain as issuer, OIDC provider, IAM role, STS integration) fit it. Oracle doesn't publish the driver's internal call sequence, so treat the exact ordering as my reading of the docs rather than an official spec.


Three layers of keys

TDE already uses two layers of keys. KMS adds a third on top:

  1. AWS KMS key. It never leaves KMS (or CloudHSM), and you control it.
  2. TDE master encryption keys. There's one per container (CDB$ROOT and each PDB), each with its own MKID. These are what go to KMS to be wrapped and unwrapped.
  3. Tablespace and column keys. They're stored encrypted in datafile headers and unlocked locally with the master key.

Your data, redo, and backups never go to AWS KMS. Only small key blobs do.

You can see the mapping on the VM:

dbaascli tde getHSMKeys --dbname <db>

The output lists each container's master_key_id next to the KMS key ARN. In SQL:

select key_id, con_id, creation_time, key_use from v$encryption_keys;

Controls you get

Kill switch for one PDB. Add a Deny to the key policy for that PDB's MKID. The other PDBs keep working. From Oracle's docs:

{
  "Effect": "Deny",
  "Principal": "*",
  "Action": ["kms:Encrypt", "kms:Decrypt"],
  "Resource": "<kms-key-arn>",
  "Condition": { "StringEquals": { "kms:EncryptionContext:MKID": "ORACLE.TDE.HSM.MK.<mkid>" } }
}

Kill switch for everything. Disable the key or remove the role from the key policy. The databases won't be able to open their keystore the next time they need the master key.

Rotation. "Rotate" on a CDB or PDB generates a new encryption context for the same KMS key.

Audit. Every Encrypt/Decrypt call shows up in CloudTrail under the IAM role.

Isolation. With ResourceOcid set, a role only works for one VM cluster.


Same model for Exascale and Autonomous Dedicated

The ExaDB-XS and ADB-D AWS KMS pages follow the same steps as ExaDB-D:

  1. Verify the OCI identity domain.
  2. Turn on STS and KMS in the ODB network.
  3. Run the CloudFormation stack.
  4. Associate the IAM role.
  5. Create the key.
  6. Create the OCI policy.
  7. Register the key.
  8. Enable AWS KMS.

Everything in the diagrams above applies. Swap "Exadata VM cluster" for an Exascale VM cluster or an Autonomous VM cluster. For ADB-D, also swap the database for an Autonomous Container Database (ACD) and its Autonomous Databases.

What's different:


ExaDB-DExaDB-XS (Exascale)ADB-D
Resource that holds the identityExadata VM clusterExascale VM clusterAutonomous VM cluster
CloudFormation link and "Associate IAM role"Exadata VM cluster → IAM service rolesExascale VM cluster → IAM service roles (one stack per cluster)Autonomous VM cluster → IAM service roles
Resource principal type in the OCI policycloudvmclusterexadbvmclustercloudautonomousvmcluster
Where AWS KMS is enabledVM cluster → AWS Key Management → EnableVM cluster → AWS Customer Managed Encryption Key → EnableAutonomous Exadata VM cluster → Multicloud information → AWS KMS → Enable
Where you choose the keyNew database, or "Change" on an existing oneNew database, or "Change" on an existing oneWhen you create the ACD (Encryption key → AWS KMS)
RotationCDB or PDB → RotateCDB or PDB → RotateACD or Autonomous Database → Rotate encryption key
PKCS#11 driver on the VMsYes, you can update itYes, you can update itNot mentioned in the ADB-D docs (no customer OS access, so presumably Oracle-managed)
Cross-region DR with AWS KMSData Guard with a Multi-Region keyNot described on the Exascale page as of todayCross-region Autonomous Data Guard with a Multi-Region key

The OCI policy differs only in the principal type:

# ExaDB-D
Allow any-user to read oracle-db-aws-keys in compartment id <compartment-ocid>
  where all { request.principal.type = 'cloudvmcluster' }

# ExaDB-XS (Exascale)
Allow any-user to read oracle-db-aws-keys in compartment id <compartment-ocid>
  where all { request.principal.type = 'exadbvmcluster' }

# ADB-D
Allow any-user to read oracle-db-aws-keys in compartment id <compartment-ocid>
  where all { request.principal.type = 'cloudautonomousvmcluster' }

Using the wrong principal type is an easy mistake when you copy a policy from one service to another.

Exascale notes:

  • One stack per Exascale VM cluster. Oracle's Exascale page says to create a CloudFormation stack for each cluster. Reuse the account's existing OIDCProviderArn after the first run.
  • Same two-choice rule. After enabling, new databases on the cluster can use only Oracle Wallet or AWS KMS, and only keys registered in OCI are listed.
  • The ODB@AWS Exascale protect page is thin. As of today it lists AWS KMS as an option but doesn't show the steps. The detail is in the Exascale service docs linked above.

ADB-D notes:

  • Same two-choice rule. Once AWS KMS is enabled on the Autonomous VM cluster, new databases can use only Oracle Wallet or AWS KMS.
  • Plan for Multi-Region early. If cross-region Autonomous Data Guard is even a possibility, create the key as Multi-Region, because you can't change it later. For the standby, create a replica key in the standby region, give the standby Autonomous VM cluster's IAM role usage permission on it, and use Replicate AWS key in OCI. The standby region needs its own CloudFormation stack, role association, and OCI setup.
  • Cross-region restore is a separate question. Cross-region Data Guard is documented, but the ADB-D restore page says cross-region restore (cloning from S3 backups into another region) isn't supported for databases using AWS KMS.
  • One OIDC provider per AWS account. It's shared across ExaDB-D, ExaDB-XS, and ADB-D. After the first CloudFormation run, pass the existing OIDCProviderArn.

Operational notes and gotchas

  • Two choices only. Once AWS KMS is enabled on a VM cluster, new databases there can use only Oracle Wallet or AWS KMS. OCI Vault and Oracle Key Vault aren't offered.
  • Disabling breaks databases. Turning off AWS key management at the cluster level affects any database still using it, so move those databases off first.
  • One cloud driver per cluster. Only one PKCS#11 multicloud driver (AWS, Azure, or Google Cloud) can be active per VM cluster.
  • Driver updates need database restarts. Updates to the driver (dbaascli admin updateMCKMS) restart databases, either rolling one VM at a time or all at once.
  • Cross-region needs planning up front. Cross-region restore and Data Guard with AWS KMS depend on Multi-Region keys replicated to the target region, plus OCI-side key replication. You can't convert an existing single-Region key, so choose Multi-Region at creation if you might need it.
    • ExaDB-D: as of today, the ExaDB-D KMS page still has an older note saying cross-region restore isn't supported, next to a full cross-region restore procedure. I read that as a stale note, but confirm with Oracle.
    • ADB-D: cross-region Autonomous Data Guard is documented. Cross-region restore with AWS KMS is stated as unsupported.

Sources

Content from Oracle and AWS documentation was paraphrased for this post. The diagrams are my own and show my understanding of the documented components. The runtime call order is inferred, not taken from an Oracle diagram.

Valid as of October 4, 2026. Oracle Database@AWS changes frequently, so check the current documentation before you rely on these details.


No comments:

Post a Comment