github cloudposse/atmos v1.198.0

latest release: v1.199.0-rc.0
10 hours ago
docs: Enhance atmos auth env documentation @osterman (#1778) ## Summary

Comprehensive documentation improvements for atmos auth env command addressing real-world usage patterns discovered in community feedback. Adds missing --login flag documentation, shell integration guidance, and practical examples including a provider-agnostic identity switching helper function.

Changes

  • Documents --login flag for explicit authentication triggering
  • Clarifies that command outputs environment variables (doesn't modify parent shell)
  • Adds "How It Works" section with typical workflow
  • Adds "Shell Integration" section with profile setup and Warp terminal integration
  • Includes provider-agnostic use-identity helper function
  • Documents provider-specific environment variables (AWS, GitHub OIDC)
  • Adds clear guidance on when to use auth env vs auth shell
  • Improves accuracy of all technical explanations

Context

Addresses questions raised by users about using atmos auth env in shell profiles without triggering login prompts, and documents the --login flag that was previously undocumented.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added --login flag to atmos auth env command for explicit authentication control. By default, cached credentials are used unless the flag is specified.
  • Documentation

    • Updated command documentation with comprehensive usage examples, shell integration guidance, and detailed authentication flow information for AWS and GitHub OIDC providers.
Add animated typing effect to homepage hero @osterman (#1707)

what

  • Added Framer Motion library for smooth React animations
  • Created new TypingAnimation component that types and erases text in a loop
  • Updated homepage hero heading to cycle through tool names: Terraform, OpenTofu, Packer, Helmfile, and more
  • Includes realistic typing/erasing animation with blinking cursor

why

  • Static text doesn't showcase the full range of tools Atmos supports
  • Animated typing effect draws attention to the hero section
  • Makes it easy to highlight multiple tool integrations without cluttering the layout
  • Provides modern, engaging user experience that matches current web design trends

references

  • Uses Framer Motion (industry-standard React animation library)
  • Typing speed: 100ms per character
  • Erasing speed: 50ms per character
  • Pause time: 2 seconds after typing completes
  • Easily extensible by adding more tool names to the array

Summary by CodeRabbit

  • New Features

    • Animated hero section with dynamic typing text and eyebrow messaging
    • Interactive feature cards grid displaying key capabilities with icons
    • Enhanced demo showcase with lazy loading for improved performance
  • Documentation

    • Expanded changelog with routing updates and improved navigation
    • Blog post metadata updates for better author attribution and organization
  • Style

    • Modern blog and changelog visual redesign with improved typography
    • Enhanced terminal component styling and color consistency
    • Dark theme support and responsive layout improvements
    • Radial glow effects in hero section
feat: Add git root discovery for default base path @osterman (#1773) ## Summary
  • Enables running Atmos from any subdirectory like Git automatically discovers repository root
  • Local configuration always takes precedence over git root discovery
  • Feature controlled by ATMOS_GIT_ROOT_BASEPATH environment variable

Test Plan

  • All unit tests passing (18 new test cases in git_root_basepath_test.go)
  • Existing CLI tests passing with ATMOS_GIT_ROOT_BASEPATH=false set
  • Build successful with make build
  • Code follows architectural patterns and linting rules

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Automatic Git repository root discovery: Atmos can run from subdirectories and use the repo root as the base path.
  • Behavior

    • Local config files/directories in the current directory take precedence; discovery applies only when no local config is present.
    • Discovery can be disabled via an environment variable for tests or opt-out.
  • Documentation

    • New docs and blog post with examples, rollout guidance, and migration notes.
  • Tests

    • Added tests covering discovery, local-config detection, env override, and edge cases.
  • Other

    • Additional trace logs to aid debugging and rollout validation.
Fix test output logging to be subtest-aware @osterman (#1776)

Summary

Replace t.Cleanup()/t.Failed() pattern with immediate error logging in test helpers. The old approach would log output if ANY part of the test failed, even if the specific operation succeeded. Now we log only when the actual operation fails.

Changes

  • runTerraformApply() now logs terraform output immediately on error
  • TestCliValidateSchemaWithMockServer logs schema output immediately on validation failure

This provides more precise debugging info by showing output only for operations that actually fail.

🤖 Generated with Claude Code

Add theme system with 349 embedded themes and UI framework integration @osterman (#1764)

what

  • Comprehensive theme system with 349 embedded terminal themes from charmbracelet/vhs (MIT licensed)
  • Full UI framework integration making all CLI output theme-aware
  • Theme commands for listing and previewing available themes
  • Configuration via ATMOS_THEME env var, atmos.yaml, or defaults
  • 89.6% test coverage with 73 comprehensive tests

why

  • Users can customize the appearance of all Atmos CLI output to match their preferred color scheme and terminal theme
  • Improves accessibility and readability for different lighting conditions and personal preferences
  • Provides consistent, professional-looking output across markdown, tables, logs, and status messages
  • Eliminates hard-coded colors that don't work well in all terminal themes

references

  • Related to theme system implementation research
  • Includes MIT-licensed themes from https://github.com/charmbracelet/vhs
  • Implements theme registry pattern for extensibility
  • Integrates with existing UI framework (pkg/ui/) for seamless theme switching

Summary by CodeRabbit

  • New Features

    • Full terminal theme system: browseable gallery, themed previews, and new CLI theme commands (list, show).
  • Configuration

    • Set active theme via ATMOS_THEME / THEME or new terminal theme setting in config.
  • Refactor

    • Formatter, markdown rendering and logging now use theme-backed styling; legacy hard-coded colors deprecated.
  • Documentation

    • Docs, usage examples, website gallery and theme attribution/license added.
  • Tests

    • Extensive unit/integration tests for themes, registry, conversion, styles, tables, and logs.
  • Chores

    • License/NOTICE updates and website build support for themes.
feat: Add core unified flag parsing infrastructure @osterman (#1762)

what

  • Add foundational pkg/flags/ package with StandardParser, builder pattern, and flag registry
  • Implement command registry integration via CommandProvider interface
  • Provide reference implementations (version and about commands) demonstrating both simple and complex patterns
  • Include 12 PRD documents covering architecture, patterns, and integration guides
  • Add Claude agent (.claude/agents/flag-handler.md) to help developers implement new commands
  • Update root.go to use global flag builder pattern
  • Add error constants for flag validation

Size: 55 files, ~17,000 lines (vs. 50,000 in original unified-flag-parsing branch)

why

The original unified-flag-parsing PR grew to 50,000+ lines across 136 files, making it impossible to review effectively. This PR extracts the core infrastructure only, providing:

  • Foundation for future work: Establishes patterns and architecture for migrating all commands
  • Reviewable size: 90% reduction (50,000 → 5,000 lines) makes thorough review possible
  • Low risk: Only touches version/about commands (informational only), no changes to critical commands
  • Clear migration path: Reference implementations show exactly how to migrate other commands
  • Educational value: PRDs and Claude agent provide comprehensive guidance for developers

Future PRs will migrate individual tool commands (terraform, helmfile, packer, etc.) to use this infrastructure, each as focused, reviewable changes.

references

  • Original branch: unified-flag-parsing (50,000+ lines, 136 files)
  • Reference implementations: cmd/version/version.go, cmd/about/about.go
  • Architecture docs: docs/prd/flag-handling/unified-flag-parsing.md
  • Developer agent: .claude/agents/flag-handler.md
  • Command registry: cmd/internal/registry.go, cmd/internal/command.go

Key architectural decisions:

  • All commands MUST use CommandProvider interface (no direct flag parsing)
  • StandardParser uses functional options pattern for type safety
  • Global flags inherited via embedding
  • Viper integration for environment variable precedence
  • 80%+ test coverage requirement

Summary by CodeRabbit

  • New Features

    • Added global --identity flag for interactive selection or explicit NAME across commands.
  • Improvements

    • Clarified help text wording (e.g., -C/--chdir, --config-path) and formatting.
    • Changed default log level display from Info to Warning.
    • Improved flag parsing and validation behavior for more reliable CLI argument handling.
  • Documentation

    • Added comprehensive flag-handling design and migration guides.
feat: Add --identity=false flag to disable authentication @osterman (#1765)

what

This PR adds support for explicitly disabling Atmos identity authentication via --identity=false (or ATMOS_IDENTITY=false), allowing users to fall back to standard cloud provider SDK credential resolution.

Changes

  • Core Implementation

    • Added IdentityFlagDisabledValue constant (__DISABLED__)
    • Implemented normalizeIdentityValue() to detect boolean false values (false, 0, no, off)
    • Updated TerraformPreHook() to check for disabled state and skip authentication
  • Testing (80-100% coverage)

    • TestNormalizeIdentityValue - 20 test cases covering all boolean variants
    • TestGetIdentityFromFlags - 13 test cases including disabled scenarios
    • TestIsAuthenticationDisabled - 5 test cases for sentinel detection
    • TestTerraformPreHook_DisabledIdentity - 3 scenarios with/without auth config
    • All existing tests continue to pass
  • Documentation

    • New section in auth docs: "Disabling Identity Authentication"
    • Updated terraform command docs with disable examples
    • Updated all describe command docs with disable examples
    • Updated internal technical documentation
    • Added comprehensive PRD at docs/prd/disable-identity-flag.md
    • Made all language cloud-provider agnostic (not AWS-specific)

why

Users needed a way to disable Atmos authentication in CI/CD environments (especially GitHub Actions with OIDC) where different credential mechanisms are preferred. Previously, this required complex workarounds:

  • Using yq commands to remove auth configuration at runtime
  • Maintaining separate atmos.yaml files for different environments
  • No clean solution for mixed local/CI environments

This feature enables users to:

  • Use GitHub Actions OIDC credentials instead of Atmos-managed identities
  • Temporarily use local cloud provider profiles during development
  • Test without Atmos authentication
  • Support mixed environments seamlessly

Use Case Example

# GitHub Actions workflow
- name: Configure AWS credentials via OIDC
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
    aws-region: us-east-1

- name: Deploy with Atmos (using GitHub OIDC credentials)
  env:
    ATMOS_IDENTITY: false  # Disable Atmos auth, use GitHub-provided credentials
  run: atmos terraform apply mycomponent --stack=prod

references

  • PRD: docs/prd/disable-identity-flag.md
  • Resolves use case from Slack discussion about GitHub Actions OIDC authentication
  • Related to RFC: Atmos Profiles (this provides interim solution)
feat: Add agent-developer meta-agent for scaling Atmos with specialized agents @osterman (#1761)

what

  • Added agent-developer meta-agent for creating and maintaining Claude agents
  • Established agent-per-subsystem pattern for scaling Atmos development
  • Implemented self-updating mechanism with PRD dependency tracking
  • Added mandatory user confirmation for all agent/PRD modifications
  • Created comprehensive agent architecture PRD documentation

why

  • Scale Atmos development through specialized domain expertise as core functionality grows
  • Ensure agents always implement current architectural patterns via PRD awareness
  • Maintain consistency across codebase with focused, self-maintaining agents
  • Provide human oversight for all architectural changes via user confirmation
  • Establish foundation for creating subsystem-specific agents (command-registry, cobra-flag, stack-processor, etc.)

references

  • Related PRD: docs/prd/claude-agent-architecture.md - Agent architecture patterns
  • Implements strategic vision for agent-per-subsystem development model
  • Foundation for future specialized agents as Atmos subsystems mature

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • Documentation

    • Added comprehensive Claude Agents framework documentation, including architecture, development guidelines, and coordination patterns.
  • Chores

    • Updated GitHub Actions workflows to validate multiple markdown files with enhanced size checking capabilities.
test: Replace flaky schema test with GitHub Actions validation @osterman (#1758)

what

  • Replaced flaky schema validation test that depended on external URL (json.schemastore.org/bower.json) with comprehensive mock HTTP server implementation
  • Updated test to use GitHub Actions workflow schema as a realistic, modern example instead of obsolete bower.json
  • Test now validates three schema sources: file-based (package.json), HTTP (mock server), and inline JSON
  • Includes complex schema features: patternProperties, oneOf, nested objects
  • Multiple jobs workflow demonstrates real-world GitHub Actions usage

why

  • External dependency on json.schemastore.org was causing test failures with 503 errors
  • Bower.json is an obsolete package manager and not relevant to modern development
  • Mock HTTP server eliminates network dependency and makes tests reliable and reproducible
  • GitHub Actions workflows are widely used and more relevant for demonstrating schema validation
  • Tests should be independent of external services to ensure consistent CI/CD execution

references

  • Fixes flaky test failures when jsonschema.org has service interruptions
  • Uses httptest.NewServer for controlled, offline test execution
  • All test files created in temporary directory via t.TempDir() for proper test isolation
fix: Reduce template processing log noise by changing to trace level @osterman (#1737)

Summary

Changed three log statements in ProcessTmplWithDatasources from Debug to Trace level to reduce log noise when processing templates. These logs were generating hundreds of repetitive lines during operations like atmos list instances.

Changes

  • Initial template processing log → Trace level
  • Per-evaluation loop log → Trace level (most noisy)
  • Template completion log → Trace level
  • Added logKeyTemplate constant to satisfy linter

These detailed template processing logs are more appropriate at Trace level since they provide very granular execution details that are typically only needed for deep debugging.

Test Plan

  • Code compiles without errors
  • All tests pass (TestProcessTmplWithDatasourcesGomplate)
  • Linter passes (golangci-lint)
  • Pre-commit hooks pass
  • No golden snapshots contain these log messages (verified)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Internal logging adjusted to improve diagnostic tracing and consistency; log entries now use more granular trace-level output for template processing paths.

Note: This release contains internal improvements with no user-facing changes. All existing functionality remains unchanged.

feat: Add component-aware stack tab completion @osterman (#1736)

When specifying a component for terraform commands, the --stack flag
completion now filters suggestions to only show stacks that contain
the specified component. This improves UX by reducing cognitive load
and preventing invalid stack/component combinations.

Example: atmos terraform plan vpc --stack <TAB> now only suggests
stacks that contain the vpc component.

  • Modified stackFlagCompletion() to extract component from args
  • Added listStacksForComponent() helper function
  • Reuses existing FilterAndListStacks() logic from pkg/list
  • Added comprehensive test case with fixtures
  • Includes blog post documenting the feature

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Tab completion for the --stack flag now filters stacks by a specified component, showing only relevant stacks.
  • Tests

    • Added tests and snapshot updates to validate component-aware stack completion (including cases for existing, missing, and empty component).
  • Documentation

    • Added a blog post describing component-aware stack completion with examples and usage across Terraform commands.
Implement global UI formatter pattern for simplified output @osterman (#1714)

what

  • Implements package-level output functions that encode destination in the function name
  • Eliminates the need to decide "where should this output go?" (stdout vs stderr)
  • Adds pkg/io/ for I/O channel management with automatic routing and secret masking
  • Adds pkg/ui/ for stderr output with automatic formatting and icons
  • Adds pkg/terminal/ for terminal capability detection
  • Adds --mask flag for controlling automatic secret masking
  • Enforces programmatic consistency across all commands

why

The Core Problem

In the main branch, developers must constantly decide:

  • "Should this go to stdout or stderr?"
  • "Is this data or a message?"
  • "Do I need fmt.Fprintf(os.Stdout, ...) or fmt.Fprintf(os.Stderr, ...)?"

This creates inconsistency - different developers make different choices, leading to:

  • Help text appearing on stderr in some commands, stdout in others
  • Status messages mixed with data output
  • Inconsistent use of colors and formatting

The Solution

The function name IS the destination. Developers no longer think about streams:

// ❌ OLD: Developer decides where output goes
fmt.Fprintf(os.Stderr, "Starting...\n")  // Why stderr?
fmt.Fprintf(os.Stdout, result)          // Why stdout?

// ✅ NEW: Function name encodes destination
ui.Write("Starting...\n")   // Obviously stderr (it's UI)
data.Write(result)          // Obviously stdout (it's data)

Key insight: ui.* functions always go to stderr. data.* functions always go to stdout. No decisions, no mistakes, no inconsistency.

Key Changes

Eliminates Stream Decision Making

Old pattern (main branch):

// Developer must know:
// - stdout vs stderr semantics
// - When to use which stream
// - How to format output consistently

fmt.Fprintf(os.Stderr, "Starting deployment...\n")
fmt.Fprintf(os.Stdout, "%s\n", jsonOutput)
fmt.Println("Done!")  // Wait, where does this go? stdout? Is that right?

New pattern (this PR):

// Developer thinks in terms of WHAT, not WHERE:
// - Is this a message for the user? → ui.*
// - Is this data to pipe/process? → data.*
// Function name = destination. No thinking required.

ui.Write("Starting deployment...\n")  // Message → stderr (automatic)
data.Write(jsonOutput)                // Data → stdout (automatic)
ui.Success("Done!")                   // Status → stderr with ✓ icon (automatic)

Enforces Consistency

Before: Each command could do it differently

// Command A
fmt.Fprintf(os.Stderr, "Error: %s\n", err)

// Command B
fmt.Fprintf(os.Stdout, "Error: %s\n", err)  // Wrong stream!

// Command C
fmt.Println("Error:", err)  // Wrong stream! No color!

After: All commands use the same pattern

// Command A, B, C - all identical, all correct
ui.Error(err.Error())  // Always stderr, always red, always ✗ icon

Complete API

Data Output (stdout - pipeable)

Use when: Output should be processed by other tools (jq, grep, etc.)

Available via pkg/io global writers:

  • io.Data - Global stdout writer with automatic masking
  • Can use with fmt.Fprintf(io.Data, ...) or pass to third-party libraries

Convenience functions via pkg/data:

  • data.Write(text) - plain text → stdout
  • data.Writef(format, args...) - formatted text → stdout
  • data.Writeln(text) - text with newline → stdout
  • data.WriteJSON(v) - JSON → stdout
  • data.WriteYAML(v) - YAML → stdout

UI Output (stderr - human messages)

Use when: Output is for human eyes (status, errors, prompts)

  • ui.Success(text) - ✓ text → stderr (green with icon)
  • ui.Error(text) - ✗ text → stderr (red with icon)
  • ui.Warning(text) - ⚠ text → stderr (yellow with icon)
  • ui.Info(text) - ℹ text → stderr (cyan with icon)
  • ui.Write(text) - plain text → stderr (no icon, no color)
  • ui.Writef(format, args...) - formatted text → stderr
  • ui.Writeln(text) - text with newline → stderr

Markdown Rendering

Function name encodes destination:

  • ui.Markdown(content) - rendered markdown → stdout (help/docs are pipeable)
  • ui.MarkdownMessage(content) - rendered markdown → stderr (error messages are UI)

Why two functions? Because markdown can be either:

  • Documentation (help, usage) → stdout → use ui.Markdown()
  • Messages (errors, warnings) → stderr → use ui.MarkdownMessage()

The function name tells you where it goes. No guessing.

Example: The Decision Elimination

Before - Developer must think about streams:

// 🤔 "Help text... is that data or UI? stdout or stderr?"
// 🤔 "Let me check what other commands do..."
// 🤔 "I think help should be pipeable, so stdout?"
fmt.Fprintf(os.Stdout, "%s\n", helpText)

// 🤔 "Status messages... definitely stderr, right?"
fmt.Fprintf(os.Stderr, "Processing...\n")

// 🤔 "JSON output... that's data, so stdout"
fmt.Fprintf(os.Stdout, "%s\n", jsonData)

// 🤔 "Success message... stderr? or stdout? should it be green?"
fmt.Fprintf(os.Stderr, "Done!\n")

After - Function name IS the answer:

// Help is documentation → Markdown → stdout
ui.Markdown(helpText)

// Status is a message → UI → stderr
ui.Write("Processing...\n")

// JSON is data → data channel → stdout
data.WriteJSON(result)

// Success is UI feedback → UI → stderr with formatting
ui.Success("Done!")

Zero cognitive overhead. The function name encodes:

  • Destination (stdout vs stderr)
  • Formatting (plain, colored, icons)
  • Behavior (automatic masking, terminal detection)

Automatic Secret Masking

All output (stdout and stderr) is automatically masked using 8 built-in patterns covering common secrets:

  • AWS credentials (AKIA*, access keys, session tokens)
  • GitHub tokens (ghp_, gho_, github_pat_*)
  • GitLab tokens (glpat-*)
  • OpenAI API keys (sk-*)
  • Bearer tokens
  • Environment variables (AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, etc.)

Command line:

atmos terraform apply --mask=false  # Disable for debugging

Environment:

export ATMOS_MASK=false

Config file:

settings:
  terminal:
    mask:
      enabled: true
      replacement: "***MASKED***"

Precedence: --mask flag > ATMOS_MASK env > config > default (true)

Programmatic API:

import iolib "github.com/cloudposse/atmos/pkg/io"

// Register custom secrets
iolib.RegisterSecret("my-api-key-abc123")           // Masks literal + encodings
iolib.RegisterPattern(`COMPANY_KEY_[A-Z0-9]{32}`)   // Masks regex pattern
iolib.RegisterValue(os.Getenv("CUSTOM_SECRET"))     // Masks literal only

// Pass global writers to third-party libraries
logger := log.New(iolib.Data, "", 0)  // Automatically masked
bar := progressbar.NewOptions(100, progressbar.OptionSetWriter(iolib.UI))

Future: Config-based pattern registration (schema exists, loading not implemented yet):

settings:
  terminal:
    mask:
      patterns: ['ACME_[A-Z0-9]{32}']  # Custom regex patterns
      literals: ['my-secret']          # Literal values to mask

Benefits

1. Programmatic Consistency

  • All commands use identical patterns
  • ui.Success() always behaves the same way
  • data.WriteJSON() always goes to stdout
  • No per-command variations

2. No Stream Knowledge Required

  • Don't need to understand stdout vs stderr
  • Don't need to know POSIX conventions
  • Function name = destination
  • "Is this a message or data?" → use ui.* or data.*

3. Automatic Correctness

  • Can't accidentally write data to stderr
  • Can't accidentally write UI to stdout
  • Can't forget to add colors/icons
  • Secrets automatically masked

4. Simple Mental Model

Is it for users to read? → ui.*  (goes to stderr)
Is it for tools to process? → data.* (goes to stdout)

That's it. That's the whole model.

Architecture

  • pkg/io/ - I/O context, streams, masking engine, global writers, terminal detection
  • pkg/ui/ - Formatter, markdown renderer, stderr output functions
  • pkg/data/ - Stdout output functions (wraps io.Data)
  • pkg/terminal/ - Terminal capabilities (color, TTY, width)

All initialized automatically in cmd/root.go - commands just import and call.

Documentation

  • Secret Masking Configuration - User guide for masking
  • I/O and UI Output Guide - Decision tree and examples
  • Logging Guidelines - UI vs logging distinction
  • I/O Handling Strategy PRD - Architecture details
  • Secrets Masking PRD - Implementation and future considerations
  • CLAUDE.md - Developer guidelines

Testing

  • 17+ test cases for I/O context and masking
  • Unit tests for all output functions
  • Terminal capability detection tests
  • Integration tests with golden snapshots
  • 42 help command snapshots verify --mask flag presence

references

  • Eliminates "where should this go?" decisions
  • Enforces programmatic consistency across all commands
  • Makes correct output handling automatic and effortless
  • Prevents secret leakage with automatic masking

Summary by CodeRabbit

  • New Features

    • Automatic masking of sensitive data in command output (8 built-in patterns).
    • New global flags: --force-color, --force-tty, --mask (with env var support).
    • Clear separation of machine-readable data (stdout) and human UI output (stderr); improved UI formatting including Markdown rendering.
    • Global writers (io.Data, io.UI) for third-party library integration.
    • Programmatic API for registering custom secrets and patterns.
  • Documentation

    • Added comprehensive I/O/UI, masking, terminal, and logging guides; published blog post about zero-config terminal output.

🚀 Enhancements

Support GitHub OIDC Assume Roles with Web Identity @goruha (#1738)

what

  • Updated the GitHub OIDC provider to use AWS AssumeRoleWithWebIdentity authentication, referencing the AWS GitHub Actions implementation.

why

  • Fix bug when GitHub OIDC auth got JWT token, but did not authenticate on AWS

Summary by CodeRabbit

  • New Features

    • Added OIDC (web identity) support for AWS authentication to allow web-identity-based sign-in.
  • Bug Fixes

    • Ensure AWS credentials always include a valid region (defaults to us-east-1) and improved region/duration handling.
  • Tests

    • Expanded test coverage for OIDC/web-identity flows, combined credential paths, duration parsing, error cases, and anonymous/ambient credential scenarios.
  • Documentation

    • Updated license/NOTICE references to reflect bumped dependency versions.
  • Dependencies

    • Bumped AWS SDK v2, Azure identity, and related dependency versions.
fix: Enable YAML function authentication in terraform commands with --identity flag @aknysh (#1769)

what

  • Fix critical authentication bug where YAML functions (!terraform.state, !terraform.output) fail to access AWS credentials when using --identity flag with terraform commands
  • Fix identity flag parsing issue where --identity value (space-separated) fails with "Unknown command" error in describe commands
  • Create shared auth.CreateAndAuthenticateManager() helper to eliminate code duplication
  • Thread AuthManager through terraform command execution pipeline
  • Fix logger configuration timing so auth pre-hooks respect --logs-level flag
  • Fix debug log misalignment from concurrent stderr writes (spinner + logger)

why

Critical Bug: Terraform commands didn't create or authenticate AuthManager from --identity flag, causing YAML functions to fail with AWS IMDS timeout errors when attempting to access S3 state.

Root Causes:

  1. Missing authentication pipeline - ExecuteTerraform() didn't create AuthManager from info.Identity
  2. AuthManager not threaded - ProcessStacks() and ProcessComponentConfig() didn't accept AuthManager parameter
  3. Critical bug during implementation - Initial fix created AuthManager but forgot to call Authenticate(), leaving AuthContext empty

Identity Flag Parsing Bug:
4. NoOptDefVal parsing issue - Cobra's NoOptDefVal feature caused space-separated flag values (--identity value) to be misinterpreted as subcommands when used with describe commands that have positional arguments

  • Root cause: NoOptDefVal in pkg/flags/global_registry.go and cmd/describe.go
  • Fix: Removed NoOptDefVal from identity flag definition
  • Result: Both --identity=value and --identity value formats now work correctly

Secondary Issues:
5. Logger timing - Auth pre-hooks executed before global logger configured with --logs-level flag
6. Log misalignment - Multiline YAML/JSON values and concurrent spinner writes caused misaligned debug messages (200+ character indents)

Solution:

  • Created shared authentication helper in pkg/auth/manager_helpers.go to eliminate duplicate code between cmd/identity_flag.go and internal/exec/terraform.go
  • Threaded AuthManager through terraform execution pipeline following same pattern as PR #1742 for describe commands
  • Removed NoOptDefVal from identity flag in global registry and describe command to fix space-separated value parsing
  • Moved logger configuration before processStackConfigs() so auth hooks see correct log level
  • Log summaries instead of full multiline values, disable spinner in debug mode to prevent concurrent stderr writes

Impact:

  • ✅ All terraform commands now properly authenticate when using --identity flag
  • ✅ YAML functions can access AWS resources with authenticated credentials
  • ✅ No more IMDS timeout errors
  • ✅ Multi-account role assumption works correctly
  • ✅ Both --identity=value and --identity value formats work correctly in all commands
  • ✅ Auth pre-hooks respect --logs-level flag
  • ✅ Clean debug output with no misalignment
  • ✅ Code reduction (eliminated 90+ lines of duplicate code)

references

  • PRD: docs/prd/terraform-command-yaml-function-authentication.md - Comprehensive documentation of implementation, bug discovery, and verification
  • Related Fix: #1742 - Fixed describe commands but missed terraform commands

Summary by CodeRabbit

  • New Features

    • Centralized authentication helper to resolve identities, auto-detect, and support interactive selection for Terraform YAML functions.
  • Documentation

    • Added PRD and detailed guides for !terraform.state and !terraform.output authentication flows.
  • Improvements

    • Auth context threaded into stack/component processing so YAML/template functions run with authenticated credentials.
    • Log level applied earlier so pre-hooks observe configured logging.
    • CLI identity flag help clarified.
  • Tests

    • New unit tests for auth helpers and config merging; added AWS credentials test precondition.
  • Bug Fixes & Other

    • New encode/decode error sentinels, minor dependency/license updates, and log-level handling tweaks.
fix: Upgrade containerd to v2.1.5 to address CVE-2024-25621 and CVE-2025-64329 @osterman (#1770)

Summary

Upgrades github.com/containerd/containerd/v2 from v2.1.4 to v2.1.5 to address two security vulnerabilities.

Security Fixes

CVE-2024-25621 (High Severity)

Local privilege escalation via wide permissions on CRI directory

  • Impact: Directory permissions were overly broad, allowing local users to access sensitive data
    • /var/lib/containerd created with 0o711 instead of 0o700
    • /run/containerd/io.containerd.grpc.v1.cri created with 0o755 instead of 0o700
    • /run/containerd/io.containerd.sandbox.controller.v1.shim created with 0o711 instead of 0o700
  • Risk: Local users could access metadata store, content store, and Kubernetes local volumes
  • Fix: v2.1.5 automatically updates existing directory permissions on upgrade

CVE-2025-64329 (Moderate Severity)

Host memory exhaustion through Attach goroutine leak

  • Impact: Repetitive CRI Attach calls (e.g., kubectl attach) could leak goroutines
  • Risk: Memory exhaustion on the host over time
  • Fix: Proper goroutine cleanup in CRI Attach implementation

Changes

  • Upgraded github.com/containerd/containerd/v2 from v2.1.4 to v2.1.5
  • Updated go.mod and go.sum

Testing

  • make build - Build successful
  • make test-short - Tests pass (pre-existing failures unrelated to this change)

References

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • Chores
    • Updated containerd dependency to version 2.1.5
fix: Make --chdir flag work with terraform/helmfile/packer commands @osterman (#1767)

what

  • Fixed --chdir flag to work correctly with terraform, helmfile, and packer commands
  • Added manual argument parsing for --chdir/-C flags when Cobra flag parsing is disabled

why

  • Commands with DisableFlagParsing=true (terraform, helmfile, packer) were not processing the --chdir flag before atmos.yaml was loaded
  • Cobra doesn't parse flags when DisableFlagParsing=true, but PersistentPreRun runs before the command's Run function where flags would be manually parsed
  • This caused --chdir to be ignored, making it impossible to run these commands from subdirectories

references

  • Related to PR #1751 (original chdir implementation)
  • Fixes issue where atmos --chdir /path terraform plan would fail to find atmos.yaml
  • Supersedes PR #1766
fix: AWS user identity should reuse valid session credentials instead of regenerating @osterman (#1760) ## what
  • Fixed AWS user identity authentication to check for and reuse existing valid session credentials before generating new ones
  • AWS user identity Authenticate() method now calls LoadCredentials() first to check for existing valid session credentials in AWS files
  • Only generates new session tokens via GetSessionToken STS API call when no valid credentials exist or when they have expired
  • Added comprehensive tests to verify credential reuse behavior and expiration handling

why

  • The previous implementation always called GetSessionToken to generate new session tokens, even when valid session credentials already existed
  • This caused authentication failures in terraform commands, workflows, and custom commands when base credentials were expired or invalid
  • Users reported that atmos auth exec worked correctly but atmos terraform plan failed with "InvalidClientTokenId: The security token included in the request is invalid"
  • The issue occurred because each authentication attempt tried to generate new tokens using potentially expired base credentials, rather than reusing valid existing session credentials
  • This fix prevents unnecessary AWS STS API calls and authentication failures by properly reusing valid credentials across all command types

references

  • Related to previous session token keyring fix in PR #1757
  • Fixes authentication failures reported where terraform/workflow commands failed while auth exec worked
  • Impacts all authentication flows: auth exec, terraform commands, workflows, and custom commands
feat(cli): show message when no components or stacks found in `list` command @RoseSecurity (#1754)

why

  • This improves the user experience for the list_components and list_stacks commands by providing clearer feedback when no results are found. Instead of displaying nothing, the commands now print a helpful message to inform the user.

what

  • cmd/list_components.go: Added a message to inform the user when no components are found, using the appropriate color for informational messages.
  • cmd/list_stacks.go: Added a message to inform the user when no stacks are found, using the appropriate color for informational messages.

usage

Example usage:

atmos list components
cp/configurationatmos list stacks
acme
labatmos list stacks -c cp/configuration
acme
labatmos list stacks -c cp/not-a-component
No stacks found

Summary by CodeRabbit

  • Bug Fixes
    • Commands now print a clear informational message when no components or stacks are found instead of emitting empty output.
  • Tests
    • Expanded test coverage for empty-result and no-match scenarios, including integration-style checks to validate behavior when components or stacks are missing.
Add OpenTofu 1.8+ module source interpolation support @aknysh (#1756)

what

  • Added automatic OpenTofu 1.8+ module source interpolation support
  • Implemented two-tier OpenTofu detection (fast path: basename check, slow path: version command)
  • Added intelligent validation skipping for OpenTofu-specific features
  • Created comprehensive test suite with 67+ unit tests and 3 integration tests
  • Added complete user documentation for OpenTofu 1.8+ features
  • Fixed linter warnings by creating named constant for repeated string literal

why

  • Users with OpenTofu 1.8+ were unable to use module source variable interpolation (source = "${var.context.build.module_path}") because Atmos's terraform-config-inspect validation rejected it before any OpenTofu commands could execute
  • The validation library uses Terraform's HCL parser which doesn't support OpenTofu-specific syntax
  • Zero-configuration solution ensures users don't need manual workarounds or special flags
  • Automatic detection respects user's configured command (when using command: "tofu")
  • Enables dynamic module loading based on runtime configuration

references

Summary by CodeRabbit

Release Notes

  • New Features

    • Automatic OpenTofu 1.8+ module source interpolation support enabled with zero-configuration requirements
    • Validation errors for known OpenTofu-specific patterns are automatically skipped
    • Full backward compatibility maintained for Terraform users
  • Documentation

    • Added comprehensive guide for OpenTofu 1.8+ module source interpolation support
    • Included configuration examples, migration notes, and troubleshooting guidance
  • Chores

    • Updated dependencies
fix: MFA authentication by preventing session token keyring overwrite @osterman (#1757) ## what
  • Fixed MFA authentication issue where users had to run atmos auth user configure every ~30 seconds
  • Session tokens no longer overwrite long-lived credentials in keyring
  • Credential expiration times now display in user's local timezone instead of UTC

why

  • Session tokens were being cached in keyring, overwriting the long-lived credentials needed for subsequent authentication attempts
  • This caused users to lose their MFA configuration and session duration settings after the first authentication
  • Timezone inconsistency made it confusing for users to understand when credentials would expire (UTC vs local time)

references

  • Internal Slack discussion about MFA authentication failures
  • Session tokens are already persisted to AWS credential files via LoadCredentials() - no benefit to caching them in keyring
  • Long-lived credentials in keyring are needed to generate new session tokens

Summary by CodeRabbit

  • New Features

    • Session tokens are no longer cached, preserving long-lived credentials in storage.
  • Bug Fixes

    • Credential expiration timestamps now display in local timezone for improved readability.
  • Tests

    • Added validation for session token handling and long-lived credential preservation.
  • Chores

    • Updated ignore rules for temporary analysis files.
Fix vendor authentication: token injection bugs, credential precedence, and YAML templating @osterman (#1647)

what

This PR fixes multiple critical issues in the Git vendoring and authentication system:

Token Injection Infrastructure Fixes (New)

  1. inject_*_token settings completely ignored: The Detect() method logged InjectGithubToken but never checked it before calling injectToken(), making the setting useless
  2. Missing defaults for Bitbucket/GitLab: Only GitHub had inject_github_token: true as default; Bitbucket and GitLab defaulted to false, breaking authentication
  3. Poor code testability: Monolithic Detect() method with nested conditionals made it difficult to test and maintain
  4. Extracted pure helper functions: Added shouldInjectTokenForHost(), isSupportedHost(), and needsTokenInjection() for better testability
  5. Comprehensive test coverage: Added 60+ test cases covering all token injection scenarios

Original Vendor.yaml Fixes

  1. Token fallback regression: Fixed CustomGitDetector to properly fall back to GITHUB_TOKEN when ATMOS_GITHUB_TOKEN is not set
  2. User credential precedence: Ensured user-provided credentials in URLs always take precedence over automatic token injection
  3. OCI authentication: Fixed OCI registry authentication to respect Docker credentials before falling back to environment tokens
  4. Credential masking: Changed credential masking from "xxx" to "***" for clarity and professional appearance
  5. YAML parser upgrade documentation: Documented breaking changes in nested quote handling due to YAML parser v3 upgrade

GHCR Authentication Breaking Change

  1. GitHub username required for GHCR: GHCR authentication now requires both github_username and a token (ATMOS_GITHUB_TOKEN/GITHUB_TOKEN). This fixes authentication failures where token-as-username was incorrectly assumed to work.
  2. Username environment variable binding: Added support for ATMOS_GITHUB_USERNAME, GITHUB_ACTOR, and GITHUB_USERNAME environment variables with proper precedence
  3. GitHub Actions compatibility: GITHUB_ACTOR is automatically used when running in GitHub Actions CI

Test Coverage Improvements

  1. GHCR authentication tests: Added 380 lines of comprehensive tests achieving 100% coverage for getGHCRAuth() (previously 0%)
    • 8 test functions with 36+ test cases
    • Tests cover token precedence, username requirements, whitespace handling, special characters, auth source formatting, and consistency
    • Discovered and fixed whitespace handling bug during testing
  2. Config loading tests: Added 211 lines of tests for github_username environment variable precedence
    • 5 test functions with 20+ test cases
    • Verifies ATMOS_GITHUB_USERNAME > GITHUB_ACTOR > GITHUB_USERNAME precedence order
    • Tests GitHub Actions compatibility and override behavior
    • All tests use t.Setenv() for automatic cleanup per lintroller rules

why

Token Injection Infrastructure Issues (New)

Settings Ignored Bug:
The code would inject tokens regardless of the inject_github_token setting. Users couldn't disable token injection even if they wanted to use alternative authentication methods. This was a critical oversight where the setting existed but was never actually checked.

Missing Defaults Bug:
Bitbucket and GitLab token injection defaulted to false (bool zero value), causing authentication failures for users with private repositories on these platforms. Only GitHub worked out-of-the-box, creating an inconsistent user experience.

Testability Issues:
The Detect() method had high cognitive complexity with mixed concerns (URL parsing, host validation, token injection, query manipulation). This made it difficult to test edge cases in isolation, leading to bugs slipping through code review.

Original Vendor.yaml Issues

Token Fallback Issue:
Users running Atmos v1.194.1+ experienced fatal: could not read Username for 'https://github.com': No such device or address errors when vendoring from private repositories, even with GITHUB_TOKEN set. The resolveToken logic only checked ATMOS_GITHUB_TOKEN when inject_github_token was true (default), never falling back to GITHUB_TOKEN.

User Credential Precedence Issue:
When users explicitly provided credentials in their vendor.yaml URLs (e.g., https://user:token@github.com/repo), Atmos would still inject tokens, potentially overwriting user credentials or causing authentication conflicts.

OCI Authentication Issue:
OCI registry authentication wasn't respecting Docker credentials stored in ~/.docker/config.json, causing unnecessary authentication failures when valid credentials were available.

Credential Masking Issue:
The masking used "xxx" which has unfortunate associations. Changed to use "REDACTED" internally with post-processing to "***" for output, avoiding URL encoding issues while maintaining traditional credential masking appearance.

GHCR Authentication Breaking Change

Username Requirement:
GHCR (GitHub Container Registry at ghcr.io) requires both username and password for authentication. The previous implementation incorrectly assumed token-as-username would work, causing authentication failures. This breaking change ensures proper GHCR authentication by requiring users to configure github_username via environment variables (ATMOS_GITHUB_USERNAME, GITHUB_ACTOR, or GITHUB_USERNAME) or the atmos.yaml settings.

GitHub Actions Compatibility:
In GitHub Actions, the GITHUB_ACTOR environment variable is automatically set. The new implementation automatically picks this up, making GHCR authentication work out-of-the-box in CI without additional configuration.

Test Coverage Rationale

Critical Gap Addressed:
The GHCR authentication changes represented a breaking change with 0% test coverage. This created significant risk for users relying on GHCR for OCI vendoring. The new comprehensive test suite:

  • Validates all authentication paths and edge cases
  • Discovered and fixed a whitespace handling bug before it reached users
  • Ensures the breaking change works correctly across all environments
  • Provides confidence for future maintenance and refactoring

references

  • Closes #1900 - Original issue reporting token fallback regression
  • Related to the YAML parser v3 upgrade that changed quote handling behavior
  • Fixes authentication issues reported by users in Slack (see commit history for context)

Summary by CodeRabbit

  • New Features

    • Token-injection toggles for GitLab and Bitbucket; GitHub username setting exposed for registry auth.
  • Improvements

    • Unified credential precedence for Git/OCI (user creds → env tokens → Docker/registry creds → anonymous).
    • Host-aware token injection that preserves user-specified credentials and stronger log redaction of secrets.
  • Documentation

    • Expanded docs on credential precedence, token-injection settings, template evaluation, and YAML quoting.
  • Tests

    • Extensive unit and end-to-end tests and fixtures covering token injection, template parsing, GHCR auth, and masking.
Add `omitempty` tag for atlantis generate repo-config @albertorm95 (#1749)

what

Add the omitempty tag to the JSON, YAML, and mapstructure tags, so when not defined in the template the generated terraform_version, apply_requirements and delete_source_branch_on_merge attributes are omitted.

why

terraform_version

Atlantis have the capability to discover the Terraform version to use base on the root module required_version.

With the current implementation you are forced to write a terraform version otherwise the generated repo-config is terraform_version = ""

apply_requirements

Allowing apply_requirements to be omitted in the repo-config allow the Atlantis Server-side config to work.

The current implementation generates apply_requirements = [] which makes Atlantis think that there is a overwritten apply_requirements which is not, just omitting it from the repo-config solves this issue.

This has enforced us to setup this config on the Server-side:

   allowed_overrides:
      - apply_requirements
      - delete_source_branch_on_merge

delete_source_branch_on_merge

Basically same scenario as apply_requirements if present in repo-config then you need to explicitly allow it on the allowed_overrides list.

Currently when omitted the output is: delete_source_branch_on_merge: false, which is the actual default in Atlantis when the configuration is not present at all.

references

https://www.runatlantis.io/docs/terraform-versions.html#via-terraform-config
https://www.runatlantis.io/docs/server-side-repo-config.html#:~:text=Custom%20Workflows.-,delete_source_branch_on_merge,-bool

Behaviours

# atmos.yaml
integrations:
  atlantis:
    path: "atlantis.yaml"
    config_templates:
      config-1:
        version: 3
        parallel_plan: true
    project_templates:
      project-1:
        name: "{namespace}-{tenant}-{stage}-{environment}_{component}"
        workspace: "{workspace}"
        dir: "{component-path}"
        workflow: atmos-terraform
        autoplan:
          enabled: true
          when_modified:
            - "**/*.tf"

Current behaviour

# atlantis.yaml
version: 3
automerge: false
delete_source_branch_on_merge: false <-----
parallel_plan: true
parallel_apply: false
allowed_regexp_prefixes: []
projects:
  - name: foo
    workspace:foo
    workflow: atmos-terraform
    dir: components/terraform/dynamodb
    terraform_version: "" <-----
    delete_source_branch_on_merge: false <-----
    autoplan:
      enabled: true
      when_modified:
        - '**/*.tf'
    apply_requirements: [] <-----

Wanted behaviour

# atlantis.yaml
version: 3
automerge: false
parallel_plan: true
parallel_apply: false
allowed_regexp_prefixes: []
projects:
  - name: foo
    workspace:foo
    workflow: atmos-terraform
    dir: components/terraform/dynamodb
    autoplan:
      enabled: true
      when_modified:
        - '**/*.tf'

Summary by CodeRabbit

  • Bug Fixes
    • Configuration exports now properly omit empty Terraform version fields when serializing, resulting in cleaner and more readable configuration output. This behavior is now consistently applied across all supported configuration formats for improved user experience.
Fix HCL format in `atmos generate backends` @aknysh (#1750)

what

  • Fixed atmos terraform generate backends to properly handle nested maps in HCL format
  • Added recursive type converter GoToCty() in pkg/utils/cty_utils.go to convert Go types to cty values
  • Simplified WriteTerraformBackendConfigToFileAsHcl() in pkg/utils/hcl_utils.go to use the new converter
  • Added comprehensive test coverage with 4 new test functions and 13 sub-tests
  • Created test fixture at tests/fixtures/scenarios/backend-nested-maps/
  • Created PRD documentation at docs/prd/backend-nested-maps-support.md
  • Created blog post at website/blog/2025-01-04-nested-backend-maps-support.mdx

why

  • Users reported that nested maps like assume_role in S3 backend configurations were silently dropped when generating HCL format
  • This prevented users from using advanced backend features like IAM role assumption, custom encryption keys, and other nested configurations
  • The old implementation only handled primitive types (string, bool, int, float) and silently ignored complex types (maps, slices)
  • JSON and backend-config formats worked correctly, but HCL format was broken due to incomplete type handling in the HCL generator

fix

Root Cause:
The WriteTerraformBackendConfigToFileAsHcl function used a type switch that only handled primitive types. When encountering a map[string]any or []any, it fell through the if-else chain and did nothing, effectively dropping the value.

Solution:
Created a recursive GoToCty() helper function that:

  • Handles all Go types (primitives, maps, slices)
  • Recursively converts nested structures
  • Mirrors the existing CtyToGo() pattern for symmetry
  • Supports arbitrary nesting depth

Before (40+ lines):

if v == nil { ... }
else if i, ok := v.(string); ok { ... }
else if i, ok := v.(bool); ok { ... }
// ... many more type checks
// ❌ No handler for maps or slices!

After (3 lines):

ctyVal := GoToCty(v)
backendBlockBody.SetAttributeValue(name, ctyVal)

tests

Added comprehensive test coverage to prevent regression:

1. TestBackendGenerationWithNestedMaps (3 sub-tests)

  • Validates nested assume_role maps work in HCL format
  • Tests JSON format via generateComponentBackendConfig helper
  • Tests backend-config format with nested structures

2. TestBackendGenerationWithDifferentBackendTypes (3 sub-tests)

  • S3 backend with assume_role configuration
  • GCS backend with nested encryption_key configuration
  • AzureRM backend with client authentication settings

3. TestBackendGenerationErrorHandling (2 sub-tests)

  • Validates all three formats (hcl, json, backend-config)
  • Tests graceful handling of empty backend configurations

4. TestGenerateComponentBackendConfigFunction (5 sub-tests)

  • Cloud backend with {terraform_workspace} token replacement
  • Cloud backend without workspace (no token replacement)
  • S3 backend standard structure validation
  • Critical test: preserves nested maps in backend config
  • Local backend configuration

Test Results:

  • All 56 backend-related sub-tests pass ✅
  • Zero regressions in existing functionality ✅
  • Zero linter issues ✅

Coverage Improvement:

  • Before: 17 test functions, no nested map coverage
  • After: 21 test functions (+4), 100% nested map coverage

real-world impact

Before (broken):

backend:
  s3:
    assume_role:
      role_arn: "arn:aws:iam::123456:role/terraform"

Generated HCL: Missing assume_role

After (fixed):

terraform {
  backend "s3" {
    assume_role = {
      role_arn = "arn:aws:iam::123456:role/terraform"
    }
  }
}

Generated HCL: All nested fields present ✅

backward compatibility

✅ Fully backward compatible

  • No breaking changes
  • Existing configurations continue to work
  • Only adds previously missing functionality
  • All existing tests still pass

documentation

  • Created comprehensive PRD: docs/prd/backend-nested-maps-support.md
  • Created user-facing blog post: website/blog/2025-01-04-nested-backend-maps-support.mdx
    • Explains the problem with real examples
    • Shows before/after comparisons
    • Provides real-world use cases (S3 role assumption, GCS encryption, Azure configs)
    • Includes upgrade instructions
  • Added inline code comments
  • Test fixture serves as working example

references

Summary by CodeRabbit

  • New Features

    • Preserve full nested maps in Terraform backend outputs (e.g., assume_role, encryption_key) across HCL, JSON, and backend-config formats.
  • Bug Fixes

    • Fixed loss of nested backend configuration fields when generating HCL output.
  • Documentation

    • Added product spec and blog post describing nested-backend-maps support and verification; updated integration docs with tooling version bump.
  • Tests

    • Added extensive fixtures and tests covering nested maps, arrays, multiple backends, formats, and round-trip conversions.

🐛 Bug Fixes

fix: Upgrade containerd to v2.1.5 to address CVE-2024-25621 and CVE-2025-64329 @osterman (#1770)

Summary

Upgrades github.com/containerd/containerd/v2 from v2.1.4 to v2.1.5 to address two security vulnerabilities.

Security Fixes

CVE-2024-25621 (High Severity)

Local privilege escalation via wide permissions on CRI directory

  • Impact: Directory permissions were overly broad, allowing local users to access sensitive data
    • /var/lib/containerd created with 0o711 instead of 0o700
    • /run/containerd/io.containerd.grpc.v1.cri created with 0o755 instead of 0o700
    • /run/containerd/io.containerd.sandbox.controller.v1.shim created with 0o711 instead of 0o700
  • Risk: Local users could access metadata store, content store, and Kubernetes local volumes
  • Fix: v2.1.5 automatically updates existing directory permissions on upgrade

CVE-2025-64329 (Moderate Severity)

Host memory exhaustion through Attach goroutine leak

  • Impact: Repetitive CRI Attach calls (e.g., kubectl attach) could leak goroutines
  • Risk: Memory exhaustion on the host over time
  • Fix: Proper goroutine cleanup in CRI Attach implementation

Changes

  • Upgraded github.com/containerd/containerd/v2 from v2.1.4 to v2.1.5
  • Updated go.mod and go.sum

Testing

  • make build - Build successful
  • make test-short - Tests pass (pre-existing failures unrelated to this change)

References

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • Chores
    • Updated containerd dependency to version 2.1.5

Don't miss a new atmos release

NewReleases is sending notifications on new releases.