--- title: S3 storage setup --- ## Preparation First, create a user on your S3 storage provider and get access credentials (hereafter referred to as `access_key` and `secret_key`). You will also need the S3 API endpoint that authentik will use (hereafter referred to as `https://s3.provider`). When using AWS S3, there’s no need to set the endpoint, but for S3-compatible services like Azure Blob Storage or Cloudflare R2, use the provider's endpoint URL. Create or pick a bucket for authentik data, for example `authentik-data`. Adjust the name to your provider’s bucket naming rules. The domain you use to access authentik is referred to as `authentik.company` in the examples below. You will also need the AWS CLI available locally. ## S3 configuration ### Bucket creation Create the bucket that authentik will use for media files: ```bash AWS_ACCESS_KEY_ID=access_key AWS_SECRET_ACCESS_KEY=secret_key aws s3api --endpoint-url=https://s3.provider create-bucket --bucket=authentik-data --acl=private ``` If using AWS S3, you can omit `--endpoint-url`, but you may need to specify `--region`. Some regions require `--create-bucket-configuration LocationConstraint=`. The bucket ACL is set to private. Depending on your provider you can alternatively disable ACLs and rely on bucket policies. ### Bucket policy The following actions need to be allowed on the bucket: ```text ListObjectsV2 GetObject PutObject CreateMultipartUpload CompleteMultipartUpload AbortMultipartUpload DeleteObject HeadObject ``` The following policy can be used in AWS: ```json IAM policy { "Version": "2012-10-17", "Statement": [ { "Sid": "ListObjectsInBucket", "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": "arn:aws:s3:::" }, { "Sid": "ObjectLevelAccess", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:AbortMultipartUpload", "s3:CreateMultipartUpload", "s3:CompleteMultipartUpload", "s3:HeadObject" ], "Resource": "arn:aws:s3:::/*" } ] } ``` ### CORS policy Apply a CORS policy to the bucket, allowing the authentik web interface to access images directly. Save the following as `cors.json` (use your deployment’s origin; include scheme and port if non‑standard): ```json { "CORSRules": [ { "AllowedOrigins": ["https://authentik.company"], "AllowedHeaders": ["Authorization"], "AllowedMethods": ["GET"], "MaxAgeSeconds": 3000 } ] } ``` If authentik is accessed from multiple domains, include each one in `AllowedOrigins`. Apply the policy to the bucket: ```bash AWS_ACCESS_KEY_ID=access_key AWS_SECRET_ACCESS_KEY=secret_key aws s3api --endpoint-url=https://s3.provider put-bucket-cors --bucket=authentik-data --cors-configuration=file://cors.json ``` ### Content-Type Browsers rely on the HTTP `Content-Type` header to determine how to handle files; render HTML, display an image, or perform another action. Ensure that files uploaded to S3 have the correct `Content-Type` header set. If this header is missing or incorrect, browsers may fail to render content properly. For example, images might not display at all. The following command updates the `Content-Type` header for all PNG images in an AWS S3 bucket, and can be adapted for other file types: ```bash aws s3 cp \ s3:/// s3:/// \ --exclude "*" --include "*.png" \ --no-guess-mime-type \ --content-type "image/png" \ --metadata-directive "REPLACE" \ --recursive ``` :::note Terraform uploads The `Content-Type` header is not set when files are programmatically uploaded to S3 via Terraform. ::: ### Configuring authentik Add the following to your `.env` file: ```env AUTHENTIK_STORAGE__BACKEND=s3 AUTHENTIK_STORAGE__S3__ACCESS_KEY=access_key AUTHENTIK_STORAGE__S3__SECRET_KEY=secret_key AUTHENTIK_STORAGE__S3__BUCKET_NAME=authentik-data ``` If you are using AWS S3, add: ```env AUTHENTIK_STORAGE__S3__REGION=us-east-1 # Use the region of the bucket ``` If you are using an S3‑compatible provider (non‑AWS), add: ```env AUTHENTIK_STORAGE__S3__ENDPOINT=https://s3.provider AUTHENTIK_STORAGE__S3__CUSTOM_DOMAIN=s3.provider/authentik-media ``` If your provider only supports legacy S3 signatures, also set: ```env AUTHENTIK_STORAGE__S3__SIGNATURE_VERSION=s3 ``` By default, authentik uses signature version `s3v4`. The `AUTHENTIK_STORAGE__S3__ENDPOINT` setting controls how authentik communicates with the S3 provider. When set, it overrides region/`USE_SSL`. The `AUTHENTIK_STORAGE__S3__CUSTOM_DOMAIN` setting controls how media URLs are built for the web interface. It must include the bucket name and must not include a scheme. For a path-style domain, set `AUTHENTIK_STORAGE__S3__CUSTOM_DOMAIN=s3.provider/authentik-media`. The object `application-icons/application.png` will be available at `https://s3.provider/authentik-media/application-icons/application.png`. Whether URLs use HTTPS is controlled by `AUTHENTIK_STORAGE__S3__SECURE_URLS` (defaults to `true`). Depending on your provider, you can also use a virtual hosted-style domain such as `authentik-data.s3.provider`. :::info You can omit `ACCESS_KEY` and `SECRET_KEY` when using AWS SDK authentication (instance roles or profiles). See `AUTHENTIK_STORAGE__S3__SESSION_PROFILE` and related options in the configuration reference](../../install-config/configuration/configuration.mdx#storage-settings). ::: For more options (including `AUTHENTIK_STORAGE__S3__USE_SSL`, session profiles, and security tokens), see the [configuration reference](../../install-config/configuration/configuration.mdx#storage-settings). ## Migrating between storage backends The following assumes the local storage path is `/data` and the bucket is `authentik-data`. Ensure your `aws` CLI is configured to talk to your provider (add `--endpoint-url` or `--region` as needed). ### From file to s3 Follow the setup steps above, then sync files from the local directory to S3 (to the bucket root): ```bash aws s3 sync /data s3://authentik-data/ # For non-AWS providers, include the endpoint: # aws --endpoint-url=https://s3.provider s3 sync /data s3://authentik-data/ ``` ### From s3 to file ```bash aws s3 sync s3://authentik-data/ /data # For non-AWS providers: # aws --endpoint-url=https://s3.provider s3 sync s3://authentik-data/ /data ```