fnox-security-best-practices

Fnox - Security Best Practices

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "fnox-security-best-practices" with this command: npx skills add thebushidocollective/han/thebushidocollective-han-fnox-security-best-practices

Fnox - Security Best Practices

Security guidelines and best practices for managing secrets with Fnox.

Encryption Fundamentals

Always Encrypt Sensitive Data

Bad: Plain text secrets committed to git

[secrets] DATABASE_PASSWORD = "super-secret-password" API_KEY = "sk-live-12345"

Good: Encrypted secrets

[providers.age] type = "age" public_keys = ["age1ql3z..."]

[secrets] DATABASE_PASSWORD = { provider = "age", value = "age[...]" } API_KEY = { provider = "age", value = "age[...]" }

Use Strong Encryption

Good: age encryption (modern, secure)

age-keygen -o ~/.config/fnox/keys/identity.txt

Good: Cloud KMS (managed encryption)

[providers.kms] type = "aws-kms" key_id = "arn:aws:kms:us-east-1:..."

Key Management

Protect Private Keys

Store age private key securely

chmod 600 ~/.config/fnox/keys/identity.txt

Never commit private keys

echo "*.txt" >> ~/.config/fnox/keys/.gitignore

Separate Public and Private Keys

fnox.toml (committed) - public keys only

[providers.age] type = "age" public_keys = ["age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"]

fnox.local.toml (gitignored) - private keys

[providers.age] identity = "~/.config/fnox/keys/identity.txt"

Rotate Keys Regularly

Generate new age key

age-keygen -o ~/.config/fnox/keys/identity-2025.txt

Re-encrypt all secrets with new key

fnox get --all | fnox set --provider age-new

Access Control

Use Least Privilege

Good: Separate secrets by environment

[profiles.production] [profiles.production.providers.prod-secrets] type = "aws-sm" region = "us-east-1"

[profiles.production.secrets] DATABASE_URL = { provider = "prod-secrets", value = "prod/db" }

[profiles.development] [profiles.development.secrets] DATABASE_URL = "postgresql://localhost/dev" # Non-sensitive

Team Access Control

Multiple age recipients for team

[providers.age] type = "age" public_keys = [ "age1ql3z...", # Alice (admin) "age1qw4r...", # Bob (developer)

Don't include contractors or temporary team members

]

Role-Based Secrets

Backend secrets

[providers.backend] type = "aws-sm" region = "us-east-1"

Frontend secrets (different access level)

[providers.frontend] type = "aws-sm" region = "us-east-1"

[secrets] BACKEND_DB_PASSWORD = { provider = "backend", value = "backend/db-pass" } FRONTEND_API_ENDPOINT = { provider = "frontend", value = "frontend/api-url" }

Git Security

Never Commit Sensitive Data

.gitignore

fnox.local.toml *.age-identity.txt *.key *.pem .env

Audit Git History

Check for accidentally committed secrets

git log -p | grep -i "password|secret|key"

Remove secrets from git history (if found)

git filter-branch --force --index-filter
'git rm --cached --ignore-unmatch fnox.local.toml'
--prune-empty --tag-name-filter cat -- --all

Use Pre-Commit Hooks

.git/hooks/pre-commit

#!/bin/bash if git diff --cached --name-only | grep -q "fnox.local.toml"; then echo "Error: Attempting to commit fnox.local.toml" exit 1 fi

Check for plain text secrets

if git diff --cached | grep -q "password.=."[^a]"; then echo "Warning: Possible plain text password detected" exit 1 fi

Environment Separation

Separate Development and Production

fnox.toml (development)

[secrets] DATABASE_URL = "postgresql://localhost/dev" DEBUG = "true"

fnox.production.toml (production secrets)

[providers.prod] type = "aws-sm" region = "us-east-1"

[secrets] DATABASE_URL = { provider = "prod", value = "prod/db-url" } DEBUG = "false"

Use Profiles for Environments

Development

fnox exec -- node app.js

Staging

FNOX_PROFILE=staging fnox exec -- node app.js

Production

FNOX_PROFILE=production fnox exec -- node app.js

Cloud Provider Security

AWS Best Practices

Use IAM roles instead of access keys

[providers.aws-sm] type = "aws-sm" region = "us-east-1"

No access_key_id or secret_access_key

Uses IAM role or AWS credentials chain

Restrict by resource tags

[providers.aws-sm] type = "aws-sm" region = "us-east-1"

Ensure IAM policy limits access to specific secrets

Azure Best Practices

Use managed identity

[providers.azure] type = "azure-kv" vault_url = "https://my-vault.vault.azure.net"

Authentication via Azure managed identity

GCP Best Practices

Use service account with minimal permissions

[providers.gcp] type = "gcp-sm" project_id = "my-project"

Service account with only secretmanager.versions.access

Audit and Monitoring

Log Secret Access

Enable audit logging in cloud providers

AWS CloudTrail for Secrets Manager

Azure Monitor for Key Vault

GCP Cloud Audit Logs for Secret Manager

Monitor for Anomalies

Check which secrets are accessed

fnox list

Verify provider configuration

fnox doctor

Test provider connectivity

fnox provider test aws-sm

Regular Security Audits

List all secrets

fnox list

Verify encryption status

fnox doctor

Check for plain text secrets

grep -r "password.=."[^a]" fnox.toml

Secrets Lifecycle

Rotate Secrets Regularly

Generate new secret

NEW_PASSWORD=$(openssl rand -base64 32)

Update in fnox

echo "$NEW_PASSWORD" | fnox set DATABASE_PASSWORD

Update in actual service (database, API, etc.)

Then verify application still works

Remove Obsolete Secrets

Remove unused secret

fnox unset OLD_API_KEY

Clean up from cloud provider

aws secretsmanager delete-secret --secret-id old/api-key

Document Secret Purpose

[secrets] STRIPE_API_KEY = { provider = "age", value = "age[...]", description = "Stripe secret key for payment processing. Rotate quarterly." }

DATABASE_PASSWORD = { provider = "aws-sm", value = "prod/db-password", description = "PostgreSQL master password. Last rotated: 2025-01-01" }

CI/CD Security

Use Dedicated CI Keys

Separate age key for CI/CD

[providers.age] type = "age" public_keys = [ "age1ql3z...", # Developer key "age1ci3d...", # CI/CD key (limited access) ]

Restrict CI Secret Access

.github/workflows/deploy.yml

env: FNOX_PROFILE: production

Use GitHub secrets for age identity

AGE_IDENTITY: ${{ secrets.AGE_IDENTITY }}

steps:

  • name: Load secrets run: | echo "$AGE_IDENTITY" > /tmp/identity.txt chmod 600 /tmp/identity.txt fnox exec -- ./deploy.sh rm /tmp/identity.txt

Minimal CI Permissions

CI profile with minimal secrets

[profiles.ci] [profiles.ci.secrets] DEPLOY_TOKEN = { provider = "age", value = "age[...]" }

Don't include database passwords or API keys

Best Practices Summary

DO

✅ Always encrypt sensitive secrets ✅ Use strong encryption (age, KMS) ✅ Store private keys securely ✅ Separate dev and prod secrets ✅ Use .gitignore for local overrides ✅ Rotate keys and secrets regularly ✅ Use cloud provider managed identities ✅ Audit secret access ✅ Document secret purpose ✅ Use profiles for environments

DON'T

❌ Never commit private keys ❌ Never use plain text for sensitive data ❌ Don't share private keys between team members ❌ Don't hardcode credentials ❌ Don't mix dev and prod secrets ❌ Don't skip encryption in production ❌ Don't ignore security warnings ❌ Don't use weak passwords as secrets

Common Threats and Mitigations

Threat: Accidental Commit

Mitigation: Pre-commit hooks

cat > .git/hooks/pre-commit <<'EOF' #!/bin/bash if git diff --cached fnox.local.toml > /dev/null; then echo "Error: fnox.local.toml should not be committed" exit 1 fi EOF chmod +x .git/hooks/pre-commit

Threat: Key Compromise

Mitigation: Immediate rotation

1. Generate new key

age-keygen -o ~/.config/fnox/keys/identity-new.txt

2. Re-encrypt all secrets

fnox get --all | fnox set --provider age-new

3. Update public keys

4. Revoke old key

Threat: Unauthorized Access

Mitigation: Use cloud provider IAM

[providers.aws-sm] type = "aws-sm" region = "us-east-1"

Restrict with IAM policies:

- Limit to specific secret ARNs

- Require MFA

- Restrict by IP range

Related Skills

  • configuration: Managing fnox.toml securely

  • providers: Choosing secure providers

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

php security patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Security

sip-authentication-security

No summary provided by upstream source.

Repository SourceNeeds Review
Security

kubernetes-security

No summary provided by upstream source.

Repository SourceNeeds Review
Security

graphql-inspector-audit

No summary provided by upstream source.

Repository SourceNeeds Review