Discourseの認証をAWSで行うには?設定改善にご協力ください!

Howdy all,

We’re looking at improving how Discourse handles AWS [1] authentication, and we’d love to understand how you’re currently set up before making any changes.

The Current Situation

Right now, there are a few ways to configure AWS authentication in Discourse:

Option 1: Explicit Credentials (via site settings)

  • set s3_access_key_id and s3_secret_access_key in your site settings
  • authentication is per-site

Option 2: Explicit Credentials (via environment variables)

  • set the environment variables:
    DISCOURSE_S3_ACCESS_KEY_ID
    DISCOURSE_S3_SECRET_ACCESS_KEY
  • authentication is the same for all sites in a multisite cluster

Option 3: “Use IAM Profile” Setting

  • enable s3_use_iam_profile site setting or set the environment variable DISCOURSE_S3_USE_IAM_PROFILE=true
  • tells Discourse to let the AWS SDK find credentials automatically
  • originally designed for EC2 instances and obtaining credentials via IMDS, but works in other environments

Why we want to change

1. Confusing Setting Name

The s3_use_iam_profile setting has a misleading name. It suggests it only works with EC2 instance profiles, but it actually enables any AWS SDK credential source:

  • EC2 instance profiles
  • ECS task roles
  • Environment variables
  • AWS credential files
  • IAM role assumption
  • And more…

2. Security: Static Keys vs. Role Assumption

On our metal hosting platform we currently use access keys that get rotated on a regular basis. We’re aiming to switch that to role assumption for better isolation, better opportunities for access control, and to support a better internal process.

Disadvantages of the current approach:

  • access keys do not expire (until rotated)
  • have wide permission scopes
  • can be compromised if leaked
  • require manual rotation procedures

Advantages of instead using role assumption:

  • persistent credentials can be restricted via IP address
  • operations are done using temporary credentials that auto-expire (usually 1 hour)
  • just-in-time access as credentials only exist when needed
  • reduced blast radius since compromised temporary creds expire quickly
  • no key rotation - the role assumption process handles refreshing
  • better audit trails - each session gets tracked separately

What We’re Considering

We’re thinking about either:

  1. Rename the setting to something clearer like aws_credentials_from_environment
  2. Remove the setting entirely and automatically detect when credentials should come from the environment vs. site settings

We Need Your Input!

Please let us know:

  1. How do you authenticate with S3?

    • Explicit access keys in site settings
    • EC2 instance profile (with s3_use_iam_profile enabled)
    • ECS task role (with s3_use_iam_profile enabled)
    • Environment variables (with s3_use_iam_profile enabled)
    • … something else?
  2. If you use s3_use_iam_profile:

    • What environment are you running in? (EC2, ECS, Docker, bare metal, etc.)
    • Did the current name/description cause any confusion?
    • Would a different name be clearer?
  3. Any concerns about changes to this setting?

    • Worried about breaking your current setup?
    • Need time to test changes?
    • Other considerations?

Why This Matters

Better S3 authentication means:

  • More secure - no static keys to manage
  • Easier setup - especially for cloud deployments
  • Less confusion - clearer settings and documentation
  • Better support for modern AWS authentication patterns

Your feedback will help us make improvements that work for everyone. Thanks for taking the time to share your setup!


  1. here read: any S3-compatible object storage provider you’re using ↩︎

「いいね!」 2

Easier to answer this way:

DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: eu-north-1
  DISCOURSE_S3_ACCESS_KEY_ID: <something>
  DISCOURSE_S3_SECRET_ACCESS_KEY: <something>
  DISCOURSE_S3_CDN_URL: https://cdnfoorumi.katiska.eu
  DISCOURSE_S3_BUCKET: <something>
  DISCOURSE_S3_BACKUP_BUCKET: <something>
  DISCOURSE_BACKUP_LOCATION: s3
  S3_ORIGIN_ASSETS: https://foorumi.katiska.eu

Mine is one man, one admin operation. So I don’t need anything fancy, but easiness has high value.

「いいね!」 2

I also use the ENV approach.

The key advantage is resilience / agility - as long as I have the app.yml, I can relaunch my site on a new server with minimal fuss. Or manipulate a staging server with ease.

Also, this tends to be something that you sort out once, when you establish a site. Or maybe perform as a one-off upgrade. So it suits ENV nicely.

Having said that, it is also helpful to have the settings available for troubleshooting without the need to rebuild; once the settings are stable, they can then be migrated to ENV settings.

This may sound nitpicking but I think there are some important nuances here.
The options that you provide are a mixture of HOW settings are being passed and WHAT settings are being passed.

With respect to HOW settings are being passed, two things apply:

  1. the way environment variables are currently being used

The DISCOURSE_WHATEVER environment variables are currently used during the Docker build process to create entries in discourse.conf which are available as GlobalSetting or SiteSetting from within Discourse. Discourse does not perceive these environment variables as such.

  1. the limitations of discourse.conf entries

Although GlobalSettings have the neat treat of being able to suppress and override SiteSettings, they also impose the limitation that in multisite enviroments they apply to all sites in the multisite.

These two combined mean that from within Discourse, SiteSetting is the most flexible. They can be actual SiteSettings, those can optionally come from discourse.conf and those entries can come from DISCOURSE_ environment variables. IMO there is no actual choice there, SiteSetting is the most flexible and does not have disadvantages since they’re a functional superset of the others. You can use GlobalSettings instead if you want, and those could be filled using environment variables.

That implies that the only actual choice is whether to use automatic discovery of credentials or not. In my personal perception, automatic discovery is always very prone to errors, so I would prefer to have something explicit.

I.e. have a SiteSetting that somehow points to actual, concrete, credentials.