Skip to main content

AWS S3

Prepare AWS for issuing Scoped Credentials: the OIDC trust between Keycloak and AWS IAM, and the roles Katta assumes. This setup is required before you upload a storage profile using Scoped Credentials referencing the resulting role ARNs.

Prerequisites

This setup assumes Katta is already deployed and running on AWS, including its Keycloak realm. Set up the deployment first using Terraform (AWS).

Terraform

A deployment with Terraform (AWS) already runs katta setup aws and uploads a matching storage profile, see Default Storage Profile.

info

Alternatively configure S3 with long-lived access keys supplied at vault creation, continue with Storage Profiles.

OIDC Provider and Roles​

Using Katta Admin CLI, katta setup aws prepares the AWS account so Keycloak-issued tokens can be exchanged for temporary S3 credentials:

  • reads the Keycloak realm URL and client IDs from the public configuration of Katta Server at <hub-url>/api/config;
  • registers the Keycloak realm as an OpenID Connect identity provider in AWS IAM for the cryptomator, cryptomatorhub and cryptomatorvaults clients;
  • creates the IAM roles and policies for bucket creation (restricted to the configured bucket prefix) and for bucket access via role chaining with tagged sessions, restricted to a single S3 bucket used for the vault.
tip

It is idempotent — re-run it to pick up policy changes. Renewed Keycloak TLS certificates need no re-run, see Identity Provider.

tip

Requires AWS credentials with IAM permissions in the environment (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, or an AWS profile).

export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_SESSION_TOKEN=
export HUB_URL=[your Katta Server URL, e.g. https://hub.example.com]
katta setup aws --hubUrl "${HUB_URL}"
tip

The katta command prints the Keycloak realm URL and client IDs it uses, and the equivalent aws iam … for the role and policy API calls it performs.

Resources Created in AWS​

Sample Configuration

These are sample configurations for resources automatically created with katta setup aws in AWS for reference only.

Everything below is created with the defaults --roleNamePrefix katta- and --bucketPrefix katta-. Substitute your own prefixes if you pass different values. The command creates no buckets, no IAM users and no access keys — only one identity provider and three roles, each with a single inline policy of the same name as the role.

Identity Provider​

An IAM OpenID Connect identity provider for the Keycloak realm:

ARNarn:aws:iam::<account-id>:oidc-provider/keycloak.example.com/realms/cryptomator
Provider URL<keycloakUrl>/realms/<keycloakRealm> from <hub-url>/api/config
Audiencescryptomator (Katta Desktop), cryptomatorhub (Katta Web), cryptomatorvaults (Vault Access)

The audiences are the client IDs keycloakClientIdCryptomator, keycloakClientIdHub and keycloakClientIdCryptomatorVaults from <hub-url>/api/config.

No certificate thumbprint is set. AWS verifies the TLS certificate of the Keycloak endpoint against its library of trusted root certificate authorities, so renewed certificates need no update. If Keycloak uses a certificate not signed by one of these CAs, add its thumbprint to the identity provider in IAM manually.

If a provider for the same URL already exists and its audience list covers all client IDs, it is left unchanged. If the audience list differs, the provider is deleted and recreated with the full list. The ARN is derived from the provider URL and therefore stays the same across recreation.

Role katta-create-bucket​

Assumed by Katta Desktop and by Katta Server with an OIDC access token to create the vault bucket and upload the vault template. Its ARN goes into the storage profile fields stsRoleCreateBucketClient and stsRoleCreateBucketHub.

Trust policy:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::<account-id>:oidc-provider/keycloak.example.com/realms/cryptomator"},
"Action": "sts:AssumeRoleWithWebIdentity"
}]
}

Inline permission policy:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:GetBucketPolicy"
],
"Resource": "arn:aws:s3:::katta-*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::katta-*/*.uvf",
"arn:aws:s3:::katta-*/*/"
]
}
]
}

The second statement is deliberately narrow. It permits only the initial upload of the vault metadata file vault.uvf and the root directory objects, not writing arbitrary vault contents.

Role katta-access-bucket-web-identity-role​

First hop of the role chain. Assumed with an OIDC access token, it may do nothing but assume the second role with a session tag. Its ARN goes into the storage profile field stsRoleAccessBucketAssumeRoleWithWebIdentity.

Trust policy:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Federated": "arn:aws:iam::<account-id>:oidc-provider/keycloak.example.com/realms/cryptomator"},
"Action": ["sts:AssumeRoleWithWebIdentity", "sts:TagSession"]
}]
}

Inline permission policy:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["sts:AssumeRole", "sts:TagSession"],
"Resource": "arn:aws:iam::<account-id>:role/katta-access-bucket-tagged-session-role"
}]
}

Role katta-access-bucket-tagged-session-role​

Second hop of the role chain and the only role that can read and write vault contents. The client passes the vault UUID as the session tag Vault, so the resulting credentials reach exactly the bucket katta-<vault-id> and nothing else. Its ARN goes into the storage profile field stsRoleAccessBucketAssumeRoleTaggedSession, and stsSessionTag is set to Vault.

Trust policy:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<account-id>:role/katta-access-bucket-web-identity-role"},
"Action": ["sts:AssumeRole", "sts:TagSession"],
"Condition": {
"ForAnyValue:StringEquals": {"sts:TransitiveTagKeys": "${aws:RequestTag/Vault}"}
}
}]
}

Inline permission policy:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:GetBucketVersioning",
"s3:ListBucketVersions"
],
"Resource": "arn:aws:s3:::katta-${aws:PrincipalTag/Vault}"
}, {
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::katta-${aws:PrincipalTag/Vault}/*"
}]
}

On re-runs​

For a role that already exists, both its trust policy and its inline policy are overwritten with the documents above. Manual edits to those policies are lost. --maxSessionDuration is applied only when a role is created; on an existing role the session duration stays as it is, and AWS defaults to one hour for a role created without the option.

Next step​

Unless the storage profile was uploaded by the Terraform deployment, upload a matching storage profile — see Storage Profiles in the Admin Guide.