fnox-secrets

fnox Secrets Management Skill

16 stars

Best use case

fnox-secrets is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

fnox Secrets Management Skill

Teams using fnox-secrets should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/fnox-secrets/SKILL.md --create-dirs "https://raw.githubusercontent.com/plurigrid/asi/main/plugins/asi/skills/fnox-secrets/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/fnox-secrets/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How fnox-secrets Compares

Feature / Agentfnox-secretsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

fnox Secrets Management Skill

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# fnox Secrets Management Skill

```yaml
name: fnox-secrets
description: Secure secrets management with age encryption, root-protected keys, and GF(3) conservation via DuckDB/ACSet catalog
version: 1.0.0
trit: -1  # Validator/constrainer role in GF(3) triadic system
```

## Overview

fnox is a secrets management tool that encrypts secrets with age and stores them in a git-safe `fnox.toml`. This skill documents the secure setup with root-protected keys and ACSet-aligned DuckDB catalog.

## Architecture

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  FNOX SECURE ARCHITECTURE                                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  /var/keys/age/key.txt ─────────┐   (root:wheel 600)                       │
│                                 │                                           │
│                                 ▼                                           │
│  fnox --age-key-file ──▶ DECRYPTS ──▶ ~/fnox.toml                          │
│                                       (42 age-encrypted secrets)            │
│                                                                             │
│  ~/.config/keys/catalog.duckdb ◀──── ACSet-aligned catalog                 │
│  ~/.config/keys/schema.jl ◀───────── Julia ACSet schema                    │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Installation

```bash
# Install fnox via cargo
cargo install fnox

# Install age via flox (or brew)
flox install age

# Generate age keypair
mkdir -p ~/.age
age-keygen -o ~/.age/key.txt
```

## Configuration

### Initialize fnox

```bash
cd ~
fnox init
fnox provider add myage age
```

### Edit fnox.toml

```toml
[providers.myage]
type = "age"
recipients = ["age1your_public_key_here"]

[profiles.default]
# Default profile secrets

[profiles.prod]
# Production secrets

[profiles.staging]
# Staging secrets
```

## Commands

### Set a Secret

```bash
fnox set SECRET_NAME "secret_value" --provider myage
fnox set DATABASE_URL "postgres://..." --provider myage
fnox set API_KEY "sk-..." --provider myage -p prod  # prod profile
```

### Get a Secret

```bash
fnox get SECRET_NAME --age-key-file ~/.age/key.txt

# With root-protected key
sudo cat /var/keys/age/key.txt > /tmp/k && fnox get SECRET_NAME --age-key-file /tmp/k && rm /tmp/k
```

### List Secrets

```bash
fnox list
fnox list -p prod  # prod profile only
```

### Run Command with Secrets as Env Vars

```bash
fnox exec --age-key-file ~/.age/key.txt -- ./my-app
fnox exec --age-key-file ~/.age/key.txt -- env | grep APTOS
```

### Import/Export

```bash
fnox export --format env > .env.encrypted
fnox import --format env < .env
```

### Profiles

```bash
fnox profiles                    # List profiles
fnox set KEY "val" -p prod      # Set in prod profile
fnox get KEY -p prod            # Get from prod profile
FNOX_PROFILE=prod fnox list     # Use prod by default
```

## Shell Integration

Add to `~/.zshrc`:

```bash
# fnox secret management (GF(3) integrated)
export FNOX_AGE_KEY_FILE=~/.age/key.txt
eval "$(~/.cargo/bin/fnox activate zsh)"
```

For root-protected keys, use the wrapper:

```bash
# /usr/local/bin/fnox-secure
#!/bin/bash
TEMP_KEY=$(mktemp)
trap "rm -f $TEMP_KEY" EXIT
sudo cat /var/keys/age/key.txt > "$TEMP_KEY"
~/.cargo/bin/fnox --age-key-file "$TEMP_KEY" "$@"
```

## Root-Protected Key Setup

### Move Keys to Root Storage

```bash
sudo mkdir -p /var/keys/{age,aptos/worlds,aptos/testnet}
sudo cp ~/.age/key.txt /var/keys/age/
sudo cp ~/.aptos/worlds/*.key /var/keys/aptos/worlds/
sudo chown -R root:wheel /var/keys
sudo chmod -R 600 /var/keys
sudo chmod 700 /var/keys /var/keys/age /var/keys/aptos /var/keys/aptos/worlds
```

### Verify

```bash
sudo cat /var/keys/age/key.txt > /tmp/k && fnox get TEST_SECRET --age-key-file /tmp/k && rm /tmp/k
```

## DuckDB Catalog

### Schema

```sql
CREATE TABLE identity (id INTEGER PRIMARY KEY, name VARCHAR, path VARCHAR, trit TINYINT);
CREATE TABLE keypair (id INTEGER PRIMARY KEY, identity_id INTEGER, pubkey VARCHAR, privkey_path VARCHAR, algorithm VARCHAR, trit TINYINT);
CREATE TABLE provider (id INTEGER PRIMARY KEY, name VARCHAR, trit TINYINT);
CREATE TABLE profile (id INTEGER PRIMARY KEY, name VARCHAR, trit TINYINT);
CREATE TABLE secret (id INTEGER PRIMARY KEY, name VARCHAR, keypair_id INTEGER, provider_id INTEGER, profile_id INTEGER, trit TINYINT);
```

### Query Examples

```bash
# List all secrets
duckdb ~/.config/keys/catalog.duckdb "SELECT name FROM secret"

# Check GF(3) conservation
duckdb ~/.config/keys/catalog.duckdb "SELECT * FROM gf3_total"

# Find Aptos keys
duckdb ~/.config/keys/catalog.duckdb "SELECT name FROM secret WHERE name LIKE 'APTOS%'"
```

## GF(3) Conservation

All entities are assigned trits (-1, 0, +1) such that:

```
Σ(trits) ≡ 0 (mod 3)
```

| Entity | Trit Assignment |
|--------|-----------------|
| age identity | -1 (validator) |
| ssh identity | 0 (coordinator) |
| gpg identity | +1 (generator) |
| default profile | 0 |
| prod profile | +1 |
| staging profile | -1 |
| secrets | cyclic: -1, 0, +1, -1, ... |

## ACSet Schema (Julia)

```julia
@present SchKeyStore(FreeSchema) begin
    Identity::Ob
    KeyPair::Ob
    Secret::Ob
    Provider::Ob
    Profile::Ob

    keypair_identity::Hom(KeyPair, Identity)
    secret_keypair::Hom(Secret, KeyPair)
    secret_provider::Hom(Secret, Provider)
    secret_profile::Hom(Secret, Profile)

    TritType::AttrType
    identity_trit::Attr(Identity, TritType)
    keypair_trit::Attr(KeyPair, TritType)
    secret_trit::Attr(Secret, TritType)
end
```

## Current Secrets Inventory

### Aptos Keys (38)

| Secret | Description |
|--------|-------------|
| `APTOS_ALICE_KEY` | Alice world key |
| `APTOS_BOB_KEY` | Bob world key |
| `APTOS_WORLD_[A-Z]_KEY` | 26 world keys |
| `APTOS_ALICE_MAINNET_KEY` | Alice mainnet profile |
| `APTOS_ALICE_TESTNET_KEY` | Alice testnet profile |
| `APTOS_BOB_MAINNET_KEY` | Bob mainnet profile |
| `APTOS_BOB_TESTNET_KEY` | Bob testnet profile |
| `APTOS_DEFAULT_KEY` | Default profile |
| `APTOS_TESTNET_ACCOUNT_KEY` | Testnet account |
| `APTOS_TESTNET_CONSENSUS_KEY` | Testnet consensus |
| `APTOS_TESTNET_FULLNODE_KEY` | Testnet fullnode |
| `APTOS_TESTNET_VALIDATOR_KEY` | Testnet validator |
| `APTOS_TESTNET_MINT_KEY` | Testnet mint |

### Other Secrets (4)

| Secret | Description |
|--------|-------------|
| `AMP_API_KEY` | AMP API key |
| `GOOGLE_CLIENT_SECRET_PATH` | Google OAuth path |
| `TEST_SECRET` | Test secret |

## Integration with Other Skills

### cognitive-surrogate (trit: 0)

```python
# Use fnox secrets in surrogate training
fnox exec --age-key-file ~/.age/key.txt -- python train_surrogate.py
```

### acsets (trit: -1)

```julia
# Query catalog via ACSet navigation
secrets_for_identity(ks, aptos_identity_id)
```

### gay-mcp (trit: +1)

```python
# Deterministic secret access coloring
seed = GaySeed.from_string("fnox-session")
color = derive_color(seed, secret_name)
```

## Triadic Bundle

```
fnox-secrets (-1) ⊗ cognitive-surrogate (0) ⊗ gay-mcp (+1) = 0 ✓
```

## Files

```
~/.cargo/bin/fnox              # fnox binary
~/fnox.toml                    # Encrypted secrets (git-safe)
/var/keys/age/key.txt          # Root-protected age key
/var/keys/aptos/               # Root-protected Aptos keys
~/.config/keys/catalog.duckdb  # DuckDB catalog
~/.config/keys/schema.jl       # ACSet schema
/usr/local/bin/fnox-secure     # Sudo wrapper (optional)
```

## Troubleshooting

### "No providers configured"

```bash
fnox provider add myage age
# Then edit fnox.toml to set recipients
```

### "Cannot decrypt"

```bash
# Check age key path
fnox get SECRET --age-key-file ~/.age/key.txt

# For root-protected
sudo cat /var/keys/age/key.txt > /tmp/k && fnox get SECRET --age-key-file /tmp/k; rm /tmp/k
```

### "Secret not found"

```bash
fnox list  # Check secret exists
fnox list -p prod  # Check correct profile
```

## References

- [fnox GitHub](https://github.com/jdx/fnox)
- [age encryption](https://age-encryption.org/)
- [ACSets.jl](https://github.com/AlgebraicJulia/ACSets.jl)

Related Skills

We are still matching the closest adjacent skills for this page. In the meantime, continue through the full directory.