Skip to content

Feat 1817 add iam auth to mysql and redis#32488

Merged
sgress454 merged 25 commits intomainfrom
feat-1817-add-iam-auth-to-mysql-and-redis
Sep 4, 2025
Merged

Feat 1817 add iam auth to mysql and redis#32488
sgress454 merged 25 commits intomainfrom
feat-1817-add-iam-auth-to-mysql-and-redis

Conversation

@sgress454
Copy link
Copy Markdown
Contributor

@sgress454 sgress454 commented Sep 1, 2025

for #1817

Details

This PR gives Fleet servers the ability to connect to RDS MySQL and Elasticache Redis via AWS Identity and Access Management (IAM). It is based almost entirely on the work of @titanous, branched from his original pull request. The main differences between his branch and this are:

  1. Removal of auto-detection of AWS region (and cache name for Elasticache) in favor of specifying these values in configuration. The auto-detection is admittedly handy but parsing AWS host URLs is not considered a best practice.
  2. Relying on the existence of these new configs to determine whether or not to connect via IAM. This sidesteps a thorny issue of whether to try an IAM-based Elasticache connection when a password is not supplied, since this is technically a valid setup.

Checklist for submitter

If some of the following don't apply, delete the relevant line.

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually - besides using @titanous's excellent test tool, I verified the following end-to-end:
    • regular (non RDS) MySQL connection
    • RDS MySQL connection using username/password
    • RDS MySQL connection using IAM (no role)
    • RDS MySQL connection using IAM (assuming role)
    • regular (non Elasticache) Redis connection
    • Elasticache Redis connection using username/password
    • Elasticache Redis connection using NO password (without IAM)
    • Elasticache Redis connection using IAM (no role)
    • Elasticache Redis connection using IAM (assuming role)

@sgress454 sgress454 requested a review from a team as a code owner September 1, 2025 15:35
@codecov
Copy link
Copy Markdown

codecov Bot commented Sep 1, 2025

Codecov Report

❌ Patch coverage is 19.83122% with 190 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.94%. Comparing base (27560c7) to head (abea1f4).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
server/aws_common/iam_auth.go 0.00% 48 Missing ⚠️
...erver/datastore/mysql/common_mysql/aws_iam_auth.go 0.00% 47 Missing ⚠️
server/datastore/redis/aws_iam_auth.go 0.00% 45 Missing ⚠️
server/datastore/mysql/common_mysql/common.go 25.00% 21 Missing and 6 partials ⚠️
server/datastore/redis/redis.go 26.92% 16 Missing and 3 partials ⚠️
cmd/fleet/serve.go 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #32488      +/-   ##
==========================================
- Coverage   64.02%   63.94%   -0.09%     
==========================================
  Files        1987     1991       +4     
  Lines      195579   195652      +73     
  Branches     6461     6360     -101     
==========================================
- Hits       125221   125100     -121     
- Misses      60560    60746     +186     
- Partials     9798     9806       +8     
Flag Coverage Δ
backend 65.18% <19.83%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread tools/mysql-tests/rds/iam_auth.go
Comment thread tools/redis-tests/elasticache/iam_auth.go Outdated

// Auto-detect ElastiCache and use IAM auth if no password is provided
useIAMAuth := false
if conf.Password == "" && conf.Region != "" && conf.CacheName != "" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the region should be optional, in the vast majority of cases the region will just be whatever the default is from the environment, and here we don't need it because CacheName can be used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, although we do need a region to generate the auth token. I think if we change this to

region:      cfg.Region

it should fall back to the default region if provided.

// Auto-detect RDS and use IAM auth if no password is provided
var iamTokenGen *awsIAMAuthTokenGenerator
useIAMAuth := false
if conf.Password == "" && conf.PasswordPath == "" && conf.Region != "" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sold on requiring the region, is it required for the other AWS integration features?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is -- see the Fleet server configuration docs and the various _region configs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Digging into this deeper, we're doing something similar to what I suggested above where it falls back to the default region if configured (or rather, overrides the default regions in LoadAWSConfig if one is provided).

For MySQL there's a bit of a quandary because, without a flag specifying that you're using RDS, we don't have a good way to determine when to try IAM auth. Your original PR handled this by parsing the server address. This is very handy when it works but introduces an amount of brittleness and edge cases that we'd rather not support. So in the absence of a specific use_iam_auth flag (proposed and rejected due to inconsistency with the rest of the config), the presence of region + absence of password is the best indicator we have that IAM auth is desired.

@sgress454 sgress454 linked an issue Sep 2, 2025 that may be closed by this pull request
30 tasks
Copy link
Copy Markdown
Member

@lucasmrod lucasmrod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Great tooling btw 👌

m.cacheMu.Lock()
defer m.cacheMu.Unlock()

// Double-check in case another goroutine generated a token while we were waiting
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit for the future: (no need to change and re-test)
For simplicity, I would have just used a sync.Mutex and just lock the whole GetToken method. Not sure if there are performance gains, and they are negligible next to network times, etc.

"multiStatements": []string{"true"},
}
if conf.TLSConfig != "" {
if conf.Password == "" && conf.PasswordPath == "" && conf.Region != "" {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I would use if useIAMAuth for clarity. Or add a comment (to not invalidate all the testing already done) that we allow clear text passwords because IAM.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def should use useIAMAuth here rather than repeating this logic, will update

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait this is in another method, we haven't set useIAMAuth here. I could make a helper method for it but for the sake of not running the tests again, I'll leave this be.

}

if conf.UseTLS {
var err error
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, not needed AFAICS.

@sgress454 sgress454 merged commit 602f5a4 into main Sep 4, 2025
40 checks passed
@sgress454 sgress454 deleted the feat-1817-add-iam-auth-to-mysql-and-redis branch September 4, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IAM authentication for MySQL and Redis

4 participants