rekey
Add new recipients and rotate encryption keys for environment files.
Synopsis
Section titled “Synopsis”kiln rekey --file <file> --add-recipient <name=key> [options]The rekey command safely adds new recipients to encrypted environment files by re-encrypting the file with an updated recipient list, enabling secure team member onboarding and access management.
Arguments
Section titled “Arguments”--file,-f: Environment file to rekey (required)--add-recipient: Add named recipient inname=keyformat (required, repeatable)--force: Skip confirmation prompts
Examples
Section titled “Examples”Add Single Recipient
Section titled “Add Single Recipient”kiln rekey --file production --add-recipient "alice=age1234567890abcdef..."Add Multiple Recipients
Section titled “Add Multiple Recipients”kiln rekey --file staging \ --add-recipient "bob=ssh-ed25519 AAAAC3NzaC1..." \ --add-recipient "charlie=age0987654321fedcba..."Add from SSH Key File
Section titled “Add from SSH Key File”kiln rekey --file development --add-recipient "dave=~/.ssh/id_ed25519.pub"Force Without Confirmation
Section titled “Force Without Confirmation”kiln rekey --file production --add-recipient "admin=age1new...key" --forceRecipient Format
Section titled “Recipient Format”Recipients must be specified in name=key format:
Age Public Keys
Section titled “Age Public Keys”--add-recipient "alice=age1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"SSH Public Keys
Section titled “SSH Public Keys”--add-recipient "bob=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGbM7..."--add-recipient "carol=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB..."From Files
Section titled “From Files”--add-recipient "dave=$(cat ~/.ssh/id_ed25519.pub)"--add-recipient "eve=./keys/eve.pub"Security Model
Section titled “Security Model”Access Control Updates
Section titled “Access Control Updates”The rekey operation:
- Validates new recipient public keys
- Adds recipients to configuration
- Updates file access control lists
- Re-encrypts file for all authorized recipients
Recipient Validation
Section titled “Recipient Validation”- Public key format validation (age or SSH)
- Duplicate recipient detection
- Private key rejection (common mistake prevention)
File Re-encryption
Section titled “File Re-encryption”- Decrypts existing environment file
- Adds new recipients to encryption list
- Re-encrypts with updated recipient set
- Atomic file replacement
Configuration Updates
Section titled “Configuration Updates”Automatic Configuration
Section titled “Automatic Configuration”The command automatically updates kiln.toml:
Before:
[recipients]alice = "age1234...existing"
[files.production]filename = "prod.env"access = ["alice"]After:
[recipients]alice = "age1234...existing"bob = "ssh-ed25519 AAAAC3..."
[files.production]filename = "prod.env"access = ["alice", "bob"]Access Control Rules
Section titled “Access Control Rules”- New recipients are added to the file’s access list
- Existing access patterns are preserved
- Wildcard access (
"*") includes new recipients automatically
Error Handling
Section titled “Error Handling”Duplicate Recipients
Section titled “Duplicate Recipients”kiln rekey --file prod --add-recipient "alice=age1234...different"# Error: configuration error: recipient 'alice' already exists with different key (use different name or remove existing recipient first)Invalid Public Key
Section titled “Invalid Public Key”kiln rekey --file prod --add-recipient "bob=invalid-key"# Error: invalid recipient: 'bob=invalid-key': invalid public key formatPrivate Key Provided
Section titled “Private Key Provided”kiln rekey --file prod --add-recipient "carol=AGE-SECRET-KEY-..."# Error: invalid recipient: 'carol=AGE-SECRET-KEY-...': private key provided instead of public keyAccess Denied
Section titled “Access Denied”kiln rekey --file production --add-recipient "dave=age1234..."# Error: security error: access denied for 'production' (check file permissions in kiln.toml)File Not Found
Section titled “File Not Found”kiln rekey --file nonexistent --add-recipient "user=key"# Error: configuration error: file 'nonexistent' not configured (check kiln.toml file definitions)Workflow Examples
Section titled “Workflow Examples”Team Member Onboarding
Section titled “Team Member Onboarding”# New developer joins the team# 1. They generate their keyssh-keygen -t ed25519 -f ~/.ssh/kiln_key
# 2. They share their public keycat ~/.ssh/kiln_key.pub# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGb... [email protected]
# 3. Admin adds them to development environmentkiln rekey --file development --add-recipient "newdev=ssh-ed25519 AAAAC3..."
# 4. Later, add to staging when readykiln rekey --file staging --add-recipient "newdev=ssh-ed25519 AAAAC3..."Production Access Grant
Section titled “Production Access Grant”# Senior developer needs production accesskiln rekey --file production --add-recipient "senior-dev=age1senior...key"
# DevOps engineer for deploymentskiln rekey --file production --add-recipient "devops=$(cat ./keys/devops.pub)"Key Rotation for External Access
Section titled “Key Rotation for External Access”# CI/CD system key rotation# 1. Generate new CI keykiln init key --path ./ci-new.key
# 2. Add new key while keeping old onekiln rekey --file production --add-recipient "ci-new=$(cat ./ci-new.key.pub)"
# 3. Update CI system to use new key# 4. Remove old key access (requires manual config edit)Bulk Team Addition
Section titled “Bulk Team Addition”# Add multiple team members at oncekiln rekey --file staging \ --add-recipient "frontend-dev=ssh-ed25519 AAAAC3..." \ --add-recipient "backend-dev=ssh-rsa AAAAB3..." \ --add-recipient "qa-engineer=age1qa...key" \ --add-recipient "designer=~/.ssh/designer.pub"Performance Considerations
Section titled “Performance Considerations”File Size Impact
Section titled “File Size Impact”- Re-encryption time scales with file size
- Multiple recipients add minimal overhead
- Network transfer time for large files
Concurrent Operations
Section titled “Concurrent Operations”- Only one rekey operation per file at a time
- Other commands may be blocked during re-encryption
- Consider coordination for shared environments
Best Practices
Section titled “Best Practices”- Verify recipient keys before adding
- Test access after making changes
- Use descriptive recipient names
- Start new team members with development access
Integration with Team Workflows
Section titled “Integration with Team Workflows”GitHub Integration
Section titled “GitHub Integration”# Automated team member addition from GitHubgithub_user="newdeveloper"github_key=$(curl -s "https://github.com/$github_user.keys" | head -n1)kiln rekey --file development --add-recipient "$github_user=$github_key"LDAP/AD Integration
Section titled “LDAP/AD Integration”# Script to sync team access from directory#!/bin/bashldap_users=$(ldapsearch -x -h ldap.company.com -b "ou=developers,dc=company,dc=com" uid | grep "^uid:" | cut -d' ' -f2)
for user in $ldap_users; do if [ -f "./keys/$user.pub" ]; then kiln rekey --file development --add-recipient "$user=$(cat ./keys/$user.pub)" fidoneAutomated Access Reviews
Section titled “Automated Access Reviews”# Generate access reportecho "Current access for production environment:"kiln info --file production
echo "Recipients with access:"grep -A 10 "\[recipients\]" kiln.toml | grep "=" | cut -d'=' -f1Advanced Usage
Section titled “Advanced Usage”Conditional Access Addition
Section titled “Conditional Access Addition”# Add recipient only if not already presentrecipient_name="newuser"recipient_key="age1new...key"
if ! grep -q "^$recipient_name = " kiln.toml; then kiln rekey --file production --add-recipient "$recipient_name=$recipient_key" echo "Added $recipient_name to production"else echo "$recipient_name already has access"fiBatch Processing
Section titled “Batch Processing”# Add same recipient to multiple environmentsrecipient="consultant=age1consultant...key"environments=("development" "staging")
for env in "${environments[@]}"; do kiln rekey --file "$env" --add-recipient "$recipient"doneAccess Validation
Section titled “Access Validation”# Verify new recipient can access after rekeyingnew_recipient="testuser"kiln rekey --file development --add-recipient "$new_recipient=age1test...key"
# Test access (requires recipient's private key)if kiln get DATABASE_URL --file development --key ./testuser.key >/dev/null 2>&1; then echo "✓ $new_recipient access verified"else echo "✗ $new_recipient access failed"fiTroubleshooting
Section titled “Troubleshooting”Rekey Failures
Section titled “Rekey Failures”# Check current configurationkiln info --file production
# Verify file exists and is accessiblels -la prod.env
# Test current accesskiln export --file production >/dev/nullConfiguration Issues
Section titled “Configuration Issues”# Validate recipient key formatecho "age1234..." | kiln init config --recipients "test=$(cat)"
# Check for configuration conflictsgrep "duplicate" kiln.tomlAccess Problems After Rekeying
Section titled “Access Problems After Rekeying”# Verify new configurationkiln info --file production --verify
# Check recipient listgrep -A 20 "\[recipients\]" kiln.toml
# Test specific recipient accesskiln get TEST_VAR --file production --key ./recipient.keyMigration Strategies
Section titled “Migration Strategies”Gradual Access Migration
Section titled “Gradual Access Migration”# Phase 1: Add new recipients alongside existing oneskiln rekey --file production --add-recipient "new-admin=age1new..."
# Phase 2: Verify new access works# (manual verification step)
# Phase 3: Remove old recipients# (requires manual configuration editing)Emergency Access Procedures
Section titled “Emergency Access Procedures”# Emergency admin accessemergency_key=$(kiln init key --path /tmp/emergency.key --force)kiln rekey --file production --add-recipient "emergency-admin=$(cat /tmp/emergency.key.pub)" --force
# Document emergency access grantecho "Emergency access granted at $(date) for incident #12345" >> access.logNext Steps
Section titled “Next Steps”Learn more about team management and security practices:
Add Team Members Access Management Access Control Patterns