Skip to content

File Access Control

File access control determines who can decrypt which files in your kiln project. Each file defines its own security boundary through access policies.

Every file in kiln specifies exactly who can decrypt it through the access array. This granular approach enables precise security boundaries while maintaining operational flexibility.

Core principles:

  • Grant minimum necessary access (principle of least privilege)
  • Make access patterns clear and auditable
  • Align permissions with actual responsibilities
  • Layer multiple controls rather than relying on single boundaries

Grant access to all defined recipients:

[files]
shared-config = {
filename = "shared.env",
access = ["*"]
}

Use cases: Non-sensitive development configuration, team-wide settings, common tool configuration.

Security considerations: Remember that ”*” includes service accounts and all future team members.

Leverage groups for role-based permissions:

[files]
api-secrets = {
filename = "api.env",
access = ["backend-team", "platform-team"]
}

Benefits: Scales with team growth, reflects organizational structure, easier to audit.

Grant access to specific people:

[files]
admin-keys = {
filename = "admin.env",
access = ["alice-admin", "bob-ops"]
}

Use cases: Highly sensitive credentials, personal API keys, emergency access accounts.

Combine multiple access types:

[files]
incident-response = {
filename = "incident.env",
access = ["ops-team", "alice-lead", "emergency-oncall"]
}

Benefits: Flexible access for complex scenarios, handles exceptional cases gracefully.

[files]
local = {
filename = "local.env",
access = ["*"]
}
dev-shared = {
filename = "dev.env",
access = ["developers", "qa-team"]
}

Broad access for collaboration with non-production data.

[files]
staging = {
filename = "staging.env",
access = ["developers", "qa-team", "product-team"]
}
staging-db = {
filename = "staging-db.env",
access = ["senior-developers", "ops-team"]
}
[files]
production = {
filename = "prod.env",
access = ["ops-team", "senior-engineers"]
}
prod-database = {
filename = "prod-db.env",
access = ["dba-team", "alice-architect"]
}
prod-emergency = {
filename = "prod-emergency.env",
access = ["incident-commanders", "cto"]
}

Principle verification:

  • Does each file follow least privilege?
  • Are access patterns justified by business need?
  • Do access levels match actual responsibilities?

Group consistency:

  • Do group memberships reflect current team structure?
  • Are group names clear and descriptive?
  • Are there unused or obsolete groups?

File coverage:

  • Does every file have appropriate access controls?
  • Are there files with overly broad access?
  • Do sensitive files have sufficiently restricted access?

Create scripts to validate access patterns:

#!/bin/bash
# Basic access pattern validation
echo "Files with universal access:"
grep -n 'access.*\*' kiln.toml
echo "Files with single-person access:"
grep -n 'access.*\["[^"]*"\]' kiln.toml
echo "Validating recipient references..."
kiln info --verify

Start restrictive - Begin with minimal access and expand as needed. It’s easier to grant access than revoke it.

Document rationale - Comment your configuration to explain complex access patterns and business justifications.

Regular reviews - Schedule periodic access reviews to ensure patterns still match team structure and needs.

Test changes - Always verify access changes work as expected before considering them complete.

Plan for incidents - Ensure critical systems have emergency access procedures that don’t depend on individual availability.

This approach to access control scales from small teams to enterprise environments while maintaining clarity about who can access what resources.