Skip to content

feat: file based secret management#1486

Closed
kmendell wants to merge 1 commit intomainfrom
feat/file-based-secrets
Closed

feat: file based secret management#1486
kmendell wants to merge 1 commit intomainfrom
feat/file-based-secrets

Conversation

@kmendell
Copy link
Member

@kmendell kmendell commented Jan 15, 2026

  • Update Documentation
  • Add E2E Tests

Disclaimer Greptiles Reviews use AI, make sure to check over its work

Greptile Summary

This PR implements a comprehensive file-based secret management system for Arcane, allowing users to securely store and mount secrets into Docker containers.

Key Changes:

  • Adds encrypted secret storage with AES-GCM encryption, storing secrets both in the database and as encrypted files on disk
  • Implements Docker secret mounting at /run/secrets/<name> with read-only permissions (0400)
  • Creates plaintext temporary files for container mounts with automatic cleanup on container stop/delete
  • Adds compose-compatible secret files in a separate directory for docker-compose integration
  • Provides full CRUD API endpoints for secret management with proper authentication
  • Includes database migrations for both PostgreSQL and SQLite
  • Adds complete frontend UI for secret management with proper validation

Security Considerations:

  • Secrets are encrypted using AES-GCM before storage in both database and files
  • Encrypted files use restrictive 0400 permissions (read-only for owner)
  • Plaintext temporary files created for container mounts are properly tracked and cleaned up
  • Compose secret files use 0600 permissions to allow docker-compose read access
  • Secret names are validated to prevent path traversal attacks

Architecture:

  • SecretService manages the full lifecycle: creation, encryption, file persistence, container mounting, and cleanup
  • Temporary files are tracked per container ID and cleaned up when containers stop or are deleted
  • Supports configurable secrets directory via settings (default: /app/data/secrets)
  • Integrates with existing container lifecycle in ContainerService

Confidence Score: 4/5

  • This PR is largely safe to merge with one minor security issue that should be addressed
  • The implementation is well-structured with proper encryption, error handling, and cleanup mechanisms. One race condition exists in the temp file creation where permissions are set after writing content, which could briefly expose secrets. The rest of the code follows Go best practices and handles edge cases appropriately.
  • Pay attention to backend/internal/utils/crypto/file_encryption.go which has a permission race condition in DecryptToTempFile

Important Files Changed

Filename Overview
backend/internal/utils/crypto/file_encryption.go Adds file-based encryption utilities; contains a race condition in DecryptToTempFile where permissions are set after content is written
backend/internal/services/secret_service.go Implements comprehensive secret management service with proper encryption, file handling, and cleanup mechanisms
backend/internal/huma/handlers/secrets.go Adds REST API handlers for secret CRUD operations with proper authentication and error handling
backend/internal/services/container_service.go Integrates secret cleanup with container lifecycle (stop/restart/delete operations)
backend/internal/huma/handlers/containers.go Adds secret mount preparation during container creation with proper cleanup on errors

Context used:

  • Rule from dashboard - GoLang Best Practices

description: 'Instructions for writing Go code following idiomatic Go pra... (source)

Copy link
Member Author

kmendell commented Jan 15, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@kmendell kmendell marked this pull request as ready for review January 15, 2026 05:03
@kmendell kmendell requested a review from a team January 15, 2026 05:03
@github-actions
Copy link

github-actions bot commented Jan 15, 2026

🔍 Deadcode Analysis

Found 1 unreachable functions in the backend.

View details
internal/utils/crypto/file_encryption.go:29:6: unreachable func: DecryptToTempFile

Only remove deadcode that you know is 100% no longer used.

Analysis from commit 4c13db5

@kmendell kmendell force-pushed the feat/file-based-secrets branch from c0633ae to 34d0ebf Compare January 15, 2026 05:04
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

34 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@getarcaneappbot
Copy link
Contributor

getarcaneappbot commented Jan 15, 2026

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit ad28d45

@kmendell kmendell added this to the v1.14.0 milestone Jan 15, 2026
@kmendell kmendell force-pushed the feat/file-based-secrets branch from 34d0ebf to 51c35f0 Compare January 15, 2026 05:17
@kmendell
Copy link
Member Author

@greptileai

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

34 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@github-actions
Copy link

This pull request has merge conflicts. Please resolve the conflicts so the PR can stay up-to-date and reviewed.

@kmendell kmendell force-pushed the feat/file-based-secrets branch 2 times, most recently from 970aecc to a40d961 Compare January 15, 2026 05:57
if err != nil {
return "", err
}
defer tmpFile.Close()
@kmendell kmendell force-pushed the feat/file-based-secrets branch 3 times, most recently from 6bb2a44 to fd6bbc5 Compare January 18, 2026 03:13
@kmendell kmendell changed the base branch from main to graphite-base/1486 January 18, 2026 03:13
@kmendell kmendell changed the base branch from graphite-base/1486 to release/v1.14.0 January 18, 2026 03:13
@kmendell kmendell force-pushed the feat/file-based-secrets branch 7 times, most recently from 5da1163 to 524cd63 Compare January 19, 2026 18:41
@kmendell kmendell force-pushed the feat/file-based-secrets branch 4 times, most recently from 2d2c20e to 82c5d24 Compare February 1, 2026 04:09
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 82c5d24

@kmendell kmendell force-pushed the feat/file-based-secrets branch from 82c5d24 to 5d31679 Compare February 1, 2026 18:09
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 5d31679

@kmendell kmendell force-pushed the feat/file-based-secrets branch from 5d31679 to d0227c5 Compare February 1, 2026 20:15
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit d0227c5

@kmendell kmendell force-pushed the feat/file-based-secrets branch from d0227c5 to 709a320 Compare February 1, 2026 20:28
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 709a320

@kmendell kmendell force-pushed the feat/file-based-secrets branch from 709a320 to 73bf2e3 Compare February 1, 2026 22:54
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 73bf2e3

@kmendell kmendell force-pushed the feat/file-based-secrets branch from 73bf2e3 to ef936c1 Compare February 2, 2026 05:00
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit ef936c1

@kmendell kmendell force-pushed the feat/file-based-secrets branch 2 times, most recently from 658dc30 to 0b05013 Compare February 3, 2026 05:03
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 0b05013

@kmendell kmendell force-pushed the feat/file-based-secrets branch from 0b05013 to a77b176 Compare February 3, 2026 05:30
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit a77b176

@kmendell kmendell force-pushed the feat/file-based-secrets branch from a77b176 to f142c2f Compare February 3, 2026 05:43
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit f142c2f

@kmendell kmendell force-pushed the feat/file-based-secrets branch from f142c2f to 52889c2 Compare February 4, 2026 02:26
@getarcaneappbot
Copy link
Contributor

Container images for this PR have been built successfully!

  • Manager: ghcr.io/getarcaneapp/arcane:pr-1486
  • Agent: ghcr.io/getarcaneapp/arcane-headless:pr-1486

Built from commit 52889c2

@kmendell kmendell force-pushed the feat/file-based-secrets branch 2 times, most recently from 7ce6658 to 4e7cf37 Compare February 4, 2026 23:25
@kmendell kmendell force-pushed the feat/file-based-secrets branch from 4e7cf37 to ad28d45 Compare February 4, 2026 23:37
@kmendell
Copy link
Member Author

kmendell commented Feb 5, 2026

Will make this better in the future... Closing this for now.

@kmendell kmendell closed this Feb 5, 2026
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.

2 participants