feat: Add ECR authentication
what
Implements ECR authentication integration for Atmos, allowing automatic Docker login to AWS ECR registries using Atmos-managed identities.
New auth.integrations Section
auth:
identities:
dev-admin:
kind: aws/permission-set
via:
provider: company-sso
principal:
name: AdministratorAccess
account: dev
integrations: # Auto-trigger on login
- dev/ecr
integrations:
dev/ecr:
kind: aws/ecr
identity: dev-admin
spec:
registries:
- account_id: "123456789012"
region: us-east-2
New atmos auth ecr-login Command
# Using a named integration
atmos auth ecr-login dev/ecr
# Using an identity's linked integrations
atmos auth ecr-login --identity dev-admin
# Explicit registries (ad-hoc)
atmos auth ecr-login --registry 123456789012.dkr.ecr.us-east-1.amazonaws.com
Implementation
| Component | File | Description |
|---|---|---|
| Schema | pkg/schema/schema_auth.go |
Integration struct, Integrations on AuthConfig and Identity |
| Integration System | pkg/auth/integrations/ |
Type system, registry pattern, factory functions |
| ECR Integration | pkg/auth/integrations/aws/ecr.go |
aws/ecr kind implementation |
| ECR Token Fetcher | pkg/auth/cloud/aws/ecr.go |
AWS SDK GetAuthorizationToken wrapper |
| Docker Config | pkg/auth/cloud/docker/config.go |
XDG-based config manager with file locking |
| Manager | pkg/auth/manager.go |
triggerIntegrations(), ExecuteIntegration() methods |
| CLI Command | cmd/auth_ecr_login.go |
Standalone ECR login command |
| Errors | errors/errors.go |
Sentinel errors for ECR/integration failures |
why
-
Eliminates manual ECR authentication - No more
aws ecr get-login-password | docker loginincantations -
Configuration as code - ECR registries defined in
atmos.yamlalongside identities -
Automatic login - Identities can auto-trigger ECR login via
integrationslist - Multi-registry support - Single identity can authenticate to multiple ECR registries
-
Isolated credentials - Docker config at
~/.config/atmos/docker/config.json(XDG) -
Non-blocking failures - Integration errors during
atmos auth logindon't block authentication
Design Decisions
Why integrations not identities?
ECR login and EKS kubeconfig are client-only credential materializations, not identities:
| Concept | IAM User | ECR Login | EKS kubeconfig |
|---|---|---|---|
| Stored identity object | β | β | β |
| Policy attachment | β | β | β |
| Server-side lifecycle | β | β | β |
| Client-only materialization | β | β | β |
Integrations use an identity to derive credentials for specific services.
references
- PRD:
docs/prd/ecr-authentication.md - Blog post:
website/blog/2025-12-15-ecr-authentication-integration.mdx - Future: EKS integration (
aws/ekskind) follows same pattern
Summary by CodeRabbit
-
New Features
- Added
atmos auth ecr-logincommand supporting explicit registries, named integrations, and identity-based ECR authentication. - Introduced integration framework for automating credential materialization and service login flows.
- Docker credentials manager with file locking for secure concurrent access.
- Multi-registry support across AWS accounts and regions with DOCKER_CONFIG environment variable management.
- Added
-
Documentation
- Added comprehensive PRD detailing ECR authentication design and implementation.
- Published blog post covering ECR integration use cases and configuration examples.
-
Chores
- Added AWS SDK v2 ECR dependency.
βοΈ Tip: You can customize this high-level summary in your review settings.
Dependency Review
β No vulnerabilities or license issues found.Scanned Files
- go.mod
Codecov Report
:x: Patch coverage is 24.28198% with 290 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 72.87%. Comparing base (54f9778) to head (52158ea).
:x: Your patch check has failed because the patch coverage (24.28%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.
Additional details and impacted files
@@ Coverage Diff @@
## main #1859 +/- ##
==========================================
- Coverage 73.19% 72.87% -0.33%
==========================================
Files 609 614 +5
Lines 56883 57266 +383
==========================================
+ Hits 41634 41730 +96
- Misses 12312 12586 +274
- Partials 2937 2950 +13
| Flag | Coverage Ξ | |
|---|---|---|
| unittests | 72.87% <24.28%> (-0.33%) |
:arrow_down: |
Flags with carried forward coverage won't be shown. Click here to find out more.
| Files with missing lines | Coverage Ξ | |
|---|---|---|
| errors/errors.go | 100.00% <ΓΈ> (ΓΈ) |
|
| pkg/schema/schema_auth.go | 100.00% <ΓΈ> (ΓΈ) |
|
| internal/exec/terraform_output_utils.go | 66.40% <0.00%> (-1.59%) |
:arrow_down: |
| pkg/auth/integrations/registry.go | 46.15% <46.15%> (ΓΈ) |
|
| pkg/auth/cloud/docker/config.go | 67.85% <67.85%> (ΓΈ) |
|
| pkg/auth/integrations/aws/ecr.go | 4.44% <4.44%> (ΓΈ) |
|
| cmd/auth_ecr_login.go | 5.26% <5.26%> (ΓΈ) |
|
| pkg/auth/cloud/aws/ecr.go | 14.92% <14.92%> (ΓΈ) |
|
| pkg/auth/manager.go | 75.28% <9.47%> (-10.34%) |
:arrow_down: |
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
π Walkthrough
Walkthrough
Adds ECR authentication: schema and integration types, integration registry, AWS ECR helpers, Docker config manager with locking, CLI auth ecr-login, auth-manager wiring to trigger and run integrations, sentinel errors, tests, docs, and an aws-sdk ECR dependency.
Changes
| Cohort / File(s) | Change Summary |
|---|---|
Documentation docs/prd/ecr-authentication.md, website/blog/2025-12-15-ecr-authentication-integration.mdx, website/docs/cli/commands/auth/ecr-login.mdx, website/docs/tutorials/ecr-authentication.mdx, website/docs/cli/commands/auth/auth-login.mdx |
New PRD, blog post, CLI command docs, tutorial, and auth-login docs describing ECR integrations, usage patterns, examples, rollout and CI guidance. |
CLI command & tests cmd/auth_ecr_login.go, cmd/auth_console_test.go |
New atmos auth ecr-login Cobra command (explicit registries / named integration / identity modes); added mock/test stubs for new AuthManager methods. |
Schema pkg/schema/schema_auth.go |
Added Integration types, AuthConfig.Integrations, IntegrationVia, IntegrationSpec, and ECRRegistry fields. |
Integration framework pkg/auth/integrations/types.go, pkg/auth/integrations/registry.go |
New Integration interface, factory type, kind constants (aws/ecr, aws/eks), and a thread-safe registry with Register/Create/ListKinds/IsRegistered. |
ECR integration implementation pkg/auth/integrations/aws/ecr.go |
New ECRIntegration registered on init; validates config, fetches ECR token, writes credentials via Docker config manager, sets DOCKER_CONFIG env var, and logs outcomes. |
AWS ECR helpers & tests pkg/auth/cloud/aws/ecr.go, pkg/auth/cloud/aws/ecr_test.go |
Added GetAuthorizationToken, ECRAuthResult, Build/Parse registry URL utilities, IsECRRegistry, and unit tests for URL parsing/validation. |
Docker config manager & tests pkg/auth/cloud/docker/config.go, pkg/auth/cloud/docker/config_test.go |
New ConfigManager using DOCKER_CONFIG or default ~/.docker, per-instance mutex + file lock, WriteAuth/RemoveAuth/GetAuthenticatedRegistries, atomic save semantics, and tests. |
Auth manager & interfaces pkg/auth/manager.go, pkg/auth/types/interfaces.go, pkg/auth/types/mock_interfaces.go |
Extended AuthManager interface with ExecuteIntegration, ExecuteIdentityIntegrations, GetIntegration; manager triggers linked integrations non-fatally post-auth; mocks updated. |
Integration registry wiring & registration pkg/auth/manager.go, pkg/auth/integrations/... |
Wiring for creating/looking-up integrations and registration of AWS ECR integration; auto_provision integrations triggered after authentication. |
Registry tests pkg/auth/integrations/registry_test.go |
Tests for registration, Create success/failure, factory errors, and unknown-kind handling. |
Error sentinels errors/errors.go |
Added sentinel errors for integration and ECR/docker-config failure modes (e.g., ErrIntegrationNotFound, ErrECRAuthFailed, ErrDockerConfigWrite). |
Internal/test stubs internal/exec/terraform_output_utils.go, pkg/auth/hooks_test.go, pkg/auth/providers/aws/saml_test.go, cmd/auth_console_test.go |
Added stub/mock methods (ExecuteIntegration, ExecuteIdentityIntegrations, GetIntegration) to satisfy new interface; some non-test stubs panic if invoked. |
Dependency / manifest go.mod |
Added github.com/aws/aws-sdk-go-v2/service/ecr v1.54.4. |
Tests / test harness tests/cli_test.go, tests/snapshots/... |
Ignore socket files when copying home in tests; CLI help snapshot updated to include ecr-login. |
Sequence Diagram(s)
sequenceDiagram
autonumber
participant CLI as atmos CLI
participant AuthMgr as AuthManager
participant Reg as Integration Registry
participant AWS as AWS ECR API
participant DockerCfg as Docker Config Manager
CLI->>AuthMgr: auth ecr-login (explicit / named / identity)
alt named integration or identity-linked
AuthMgr->>Reg: Lookup/Create integration (kind "aws/ecr")
Reg-->>AuthMgr: ECRIntegration
AuthMgr->>AuthMgr: Authenticate identity -> obtain creds
else explicit registries
CLI->>AuthMgr: use env-provided AWS creds
end
AuthMgr->>AWS: GetAuthorizationToken(creds, account, region)
AWS-->>AuthMgr: token + proxyEndpoint + expiresAt
AuthMgr->>DockerCfg: WriteAuth(registryURL, username, password)
DockerCfg-->>AuthMgr: success / error
AuthMgr-->>CLI: report results, export DOCKER_CONFIG on success
Estimated code review effort
π― 4 (Complex) | β±οΈ ~45 minutes
- Focus areas:
- pkg/auth/cloud/aws/ecr.go β AWS SDK usage, credential/region resolution, token decoding and expiry handling.
- pkg/auth/cloud/docker/config.go β concurrency, file locking, atomic writes, permissions.
- pkg/auth/manager.go & pkg/auth/types/interfaces.go β integration trigger semantics, non-fatal vs surfaced errors, credential lifecycle.
- internal/exec/terraform_output_utils.go β panic stubs in non-test code warrant scrutiny.
- cmd/auth_ecr_login.go & pkg/auth/integrations/aws/ecr.go β DOCKER_CONFIG handling and environment interactions.
Possibly related PRs
- cloudposse/atmos#1742 β touches AuthManager interface and auth-context plumbing related to ExecuteIntegration/ExecuteIdentityIntegrations/GetIntegration.
- cloudposse/atmos#1684 β modifies auth subsystem and mocks; related to CLI/auth integration changes.
- cloudposse/atmos#1712 β exposes integration-execution methods and auth hooks similar to this PR.
Suggested reviewers
- osterman
- aknysh
Pre-merge checks and finishing touches
β Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | β οΈ Warning | Docstring coverage is 39.02% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
β Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | β Passed | Check skipped - CodeRabbitβs high-level summary is enabled. |
| Title check | β Passed | The title 'feat: Add ECR authentication' directly describes the main feature added in the changesetβECR authentication integration for Atmos. |
β¨ Finishing touches
- [ ] π Generate docstrings
π§ͺ Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
Benbentwo/atmos-auth-ecr
π Recent review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
π₯ Commits
Reviewing files that changed from the base of the PR and between 6e61999685f7e361223f73cfb49ffa546d0072c9 and 52158ea74af1c87a7de1c36ea45851b2546fac75.
π Files selected for processing (2)
-
tests/cli_test.go(1 hunks) -
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden(1 hunks)
π§° Additional context used
π Path-based instructions (2)
**/*.go
π CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations All code must pass golangci-lint checks Follow Go's error handling idioms: use meaningful error messages, wrap errors with context usingfmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors Follow standard Go coding style: usegofmtandgoimportsto format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables Document all exported functions, types, and methods following Go's documentation conventions Document complex logic with inline comments in Go code Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging
**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead All comments must end with periods (enforced by godot linter) Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils Adddefer perf.Track(atmosConfig, "pkg.FuncName")()+ blank line to all public functions for performance tracking; use nil if no atmosConfig param All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly Use go.uber.org/mock/mockgen with //go:generate directives for mock generation; never create manual mocks Keep files small...
Files:
-
tests/cli_test.go
**/*_test.go
π CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)
**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages Use table-driven tests for testing multiple scenarios in Go Include integration tests for command flows and test CLI end-to-end when possible with test fixtures
**/*_test.go: Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking
Files:
-
tests/cli_test.go
π§ Learnings (11)
π Common learnings
Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.
Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.
π Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*_test.go : Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking
Applied to files:
-
tests/cli_test.go
π Learning: 2025-01-19T15:49:15.593Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 955
File: tests/snapshots/TestCLICommands_atmos_validate_editorconfig_--help.stdout.golden:0-0
Timestamp: 2025-01-19T15:49:15.593Z
Learning: In future commits, the help text for Atmos CLI commands should be limited to only show component and stack parameters for commands that actually use them. This applies to the example usage section in command help text.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-09-13T16:39:20.007Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: cmd/markdown/atmos_toolchain_aliases.md:2-4
Timestamp: 2025-09-13T16:39:20.007Z
Learning: In the cloudposse/atmos repository, CLI documentation files in cmd/markdown/ follow a specific format that uses " $ atmos command" (with leading space and dollar sign prompt) in code blocks. This is the established project convention and should not be changed to comply with standard markdownlint rules MD040 and MD014.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-10-07T00:25:16.333Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1498
File: website/src/components/Screengrabs/atmos-terraform-metadata--help.html:25-55
Timestamp: 2025-10-07T00:25:16.333Z
Learning: In Atmos CLI, subcommands inherit flags from their parent commands via Cobra's command inheritance. For example, `atmos terraform metadata --help` shows `--affected` and related flags inherited from the parent `terraform` command (defined in cmd/terraform.go), even though the metadata subcommand doesn't explicitly define these flags. This is expected Cobra behavior and auto-generated help screengrabs accurately reflect this inheritance.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2024-12-07T16:16:13.038Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 825
File: internal/exec/helmfile_generate_varfile.go:28-31
Timestamp: 2024-12-07T16:16:13.038Z
Learning: In `internal/exec/helmfile_generate_varfile.go`, the `--help` command (`./atmos helmfile generate varfile --help`) works correctly without requiring stack configurations, and the only change needed was to make `ProcessCommandLineArgs` exportable by capitalizing its name.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-03-18T12:26:25.329Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1149
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:7-7
Timestamp: 2025-03-18T12:26:25.329Z
Learning: In the Atmos project, typos or inconsistencies in test snapshot files (such as "terrafrom" instead of "terraform") may be intentional as they capture the exact output of commands and should not be flagged as issues requiring correction.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-09-27T20:50:20.564Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1533
File: pkg/config/load.go:585-637
Timestamp: 2025-09-27T20:50:20.564Z
Learning: In the cloudposse/atmos repository, command merging prioritizes precedence over display ordering. Help commands are displayed lexicographically regardless of internal array order, so the mergeCommandArrays function focuses on ensuring the correct precedence chain (top-level file wins) rather than maintaining specific display order.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-01-30T19:30:59.120Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/workflow.go:74-74
Timestamp: 2025-01-30T19:30:59.120Z
Learning: Error handling for `cmd.Usage()` is not required in the Atmos CLI codebase, as confirmed by the maintainer.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-09-10T21:17:55.273Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 1466
File: toolchain/http_client_test.go:3-10
Timestamp: 2025-09-10T21:17:55.273Z
Learning: In the cloudposse/atmos repository, imports should never be changed as per samtholiya's coding guidelines.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
π Learning: 2025-02-14T23:12:38.030Z
Learnt from: Listener430
Repo: cloudposse/atmos PR: 1061
File: tests/snapshots/TestCLICommands_atmos_vendor_pull_ssh.stderr.golden:8-8
Timestamp: 2025-02-14T23:12:38.030Z
Learning: Test snapshots in the Atmos project, particularly for dry run scenarios, may be updated during the development process, and temporary inconsistencies in their content should not be flagged as issues.
Applied to files:
-
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden
𧬠Code graph analysis (1)
tests/cli_test.go (1)
pkg/telemetry/telemetry.go (1)
Options(17-21)
β° Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Acceptance Tests (windows)
- GitHub Check: Summary
π Additional comments (2)
tests/snapshots/TestCLICommands_atmos_auth_invalid-command.stderr.golden (1)
9-9: Golden snapshot correctly updated.The new "ecr-login" subcommand is properly added to the valid auth subcommands list in alphabetical order.
tests/cli_test.go (1)
846-852: LGTM! Good defensive fix for cross-platform test reliability.The socket filtering logic is correct and solves the macOS SSH agent socket copy issue. Using
os.ModeSocketwith a bitwise check is the proper Go idiom for detecting socket files.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
[!WARNING]
This PR exceeds the recommended limit of 1,000 lines.
Large PRs are difficult to review and may be rejected due to their size.
Please verify that this PR does not address multiple issues. Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.
[!WARNING]
This PR exceeds the recommended limit of 1,000 lines.
Large PRs are difficult to review and may be rejected due to their size.
Please verify that this PR does not address multiple issues. Consider refactoring it into smaller, more focused PRs to facilitate a smoother review process.
[!WARNING]
Changelog Entry Required
This PR is labeled
minorormajorbut doesn't include a changelog entry.Action needed: Add a new blog post in
website/blog/to announce this change.Example filename:
website/blog/2025-12-15-feature-name.mdxAlternatively: If this change doesn't require a changelog entry, remove the
minorormajorlabel.
Why do we have multiple registries in a single definition, instead of having more definitions?
integrations:
dev/ecr:
kind: aws/ecr
identity: dev-admin
spec:
registries:
- account_id: "123456789012"
region: us-east-2
This would work better with deep merging, and be more consistent with how we defined identities and providers.
integrations:
dev/ecr/foo:
kind: aws/ecr
identity: dev-admin
spec:
registry:
account_id: "123456789012"
region: us-east-2
Why do identities specify the integrations, instead of integrations specify their required identity?
auth:
identities:
dev-admin:
kind: aws/permission-set
via:
provider: company-sso
principal:
name: AdministratorAccess
account: dev
integrations: # Auto-trigger on login
- dev/ecr
Instead I think it should be:
auth:
identities:
dev-admin:
kind: aws/permission-set
via:
provider: company-sso
principal:
name: AdministratorAccess
account: dev
And then...
integrations:
dev/ecr/foo:
kind: aws/ecr
via:
identity: dev-admin
spec:
auto_provision: true
registry:
account_id: "123456789012"
region: us-east-2
π₯ This pull request now has conflicts. Could you fix it @Benbentwo? π
π₯ This pull request now has conflicts. Could you fix it @Benbentwo? π