Working with Monorepos
Kānuka supports two approaches for managing secrets in monorepos. Choose the one that best fits your team’s access control needs.
Option 1: Single secrets store at root
Section titled “Option 1: Single secrets store at root”Initialize Kānuka once at the monorepo root and use selective encryption to manage secrets across all services.
cd my-monorepokanuka secrets initUse file arguments to encrypt or decrypt specific services:
# Encrypt only the API servicekanuka secrets encrypt services/api/.env
# Encrypt multiple serviceskanuka secrets encrypt services/api/.env services/web/.env
# Use glob patterns for all serviceskanuka secrets encrypt "services/*/.env"
# Encrypt a specific directorykanuka secrets encrypt services/api/
# Decrypt just what you needkanuka secrets decrypt services/api/.env.kanuka- Single source of truth - One
.kanukadirectory for all access control - Simpler key management - One set of keys to manage and rotate
- Easier onboarding - New team members only need to be registered once
- Unified audit log - All operations logged in one place
- No per-service access control - All registered users can decrypt all secrets
- Larger key rotation scope - Revoking a user requires re-encrypting all secrets
Best for
Section titled “Best for”- Small to medium teams where everyone needs access to all services
- Projects where access control is handled at the repository level
- Teams prioritizing simplicity over granular permissions
Option 2: Separate secrets stores per service
Section titled “Option 2: Separate secrets stores per service”Initialize Kānuka independently in each service that needs secrets management.
cd my-monorepo/services/apikanuka secrets init
cd ../webkanuka secrets init
cd ../workerkanuka secrets initRun commands from within each service directory:
# In services/apicd services/apikanuka secrets encryptkanuka secrets decrypt
# Register a user for just this service- Per-service access control - Different teams can access different services
- Isolated key rotation - Revoking access only affects one service
- Independent audit logs - Each service has its own operation history
- More management overhead - Multiple
.kanukadirectories to maintain - Repeated onboarding - Users may need to be registered in multiple services
- Must remember context - Commands must be run from the correct directory
Best for
Section titled “Best for”- Large organizations with distinct teams per service
- Projects with different security classifications per service
- Situations requiring strict access separation
Unreadable directories are skipped
Section titled “Unreadable directories are skipped”Monorepos often contain runtime data owned by other users, such as
data/postgres/pgdata/ (owned by the container’s postgres user, mode 0700)
or caddy/pocketid data directories. These directories are unreadable to your
user and typically live in .gitignore — Kānuka never needs to look inside
them.
Commands that scan the project tree (encrypt, decrypt, status, doctor,
export, sync, rotate, and revoke) skip directories they cannot read
instead of failing, and continue with the rest of the tree. Run any of them
with --verbose to list skipped directories:
kanuka secrets encrypt --verbose# [warn] Skipping unreadable directory /path/to/data/postgres/pgdata: open ...: permission deniedIf a directory that actually contains .env files is being skipped, fix its
permissions or pass the files explicitly as shown above.
Recommendation
Section titled “Recommendation”Start with Option 1 (single store at root) unless you have a specific need for per-service access control. It’s simpler to manage and you can always migrate to Option 2 later if needed.
Migration between options
Section titled “Migration between options”From single store to per-service
Section titled “From single store to per-service”- Decrypt all secrets at the root level
- Initialize Kānuka in each service directory
- Register users as needed per service
- Encrypt secrets in each service
- Remove the root
.kanukadirectory
From per-service to single store
Section titled “From per-service to single store”- Decrypt all secrets in each service
- Remove
.kanukadirectories from each service - Initialize Kānuka at the root
- Register all users who need access
- Encrypt all secrets from the root
CI/CD considerations
Section titled “CI/CD considerations”Single store approach
Section titled “Single store approach”Your CI/CD pipeline can decrypt specific services:
# Decrypt only what this job needskanuka secrets decrypt services/api/.env.kanukaPer-service approach
Section titled “Per-service approach”Your pipeline needs to run from the correct directory:
cd services/api && kanuka secrets decryptOr use separate credentials per service for additional isolation.
Next steps
Section titled “Next steps”- Learn about encrypting specific files
- Learn about decrypting specific files
- See the command reference for all options