> ## Documentation Index
> Fetch the complete documentation index at: https://nono.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Profile Authoring

> Scaffolding, schema validation, and tooling for creating custom profiles

The `nono profile` command provides scaffolding and tooling for creating custom profiles. Instead of reverse-engineering the JSON structure from existing profiles, you can generate skeleton files, get editor autocomplete via JSON Schema, and access an LLM-oriented authoring guide.

<Tip>
  For an overview of what profiles are and how they compose with groups, see [Profiles & Groups](/cli/features/profiles-groups).
</Tip>

## Generating a Profile

Use `nono profile init` to scaffold a new profile:

```bash theme={null}
# Minimal skeleton
nono profile init my-agent

# With inheritance and groups
nono profile init my-agent --extends default --groups deny_credentials

# With a description
nono profile init my-agent --extends default --description "Profile for my agent"

# Full skeleton with all sections
nono profile init my-agent --full

# Output to a specific path instead of ~/.config/nono/profiles/
nono profile init my-agent --output ./my-agent.json
```

By default, the profile is written to `~/.config/nono/profiles/<name>.json`. Use `--force` to overwrite an existing file.

### Minimal Skeleton

A minimal skeleton includes the core sections most profiles need:

```json theme={null}
{
  "extends": "default",
  "meta": {
    "name": "my-agent",
    "description": "Profile for my agent"
  },
  "groups": {
    "include": [
      "deny_credentials"
    ]
  },
  "workdir": {
    "access": "readwrite"
  },
  "filesystem": {
    "allow": [],
    "read": []
  }
}
```

### Full Skeleton

With `--full`, additional sections are included as empty stubs for all additive fields:

```json theme={null}
{
  "meta": {
    "name": "my-agent"
  },
  "groups": {
    "include": [],
    "exclude": []
  },
  "commands": {
    "allow": [],
    "deny": []
  },
  "workdir": {
    "access": "readwrite"
  },
  "filesystem": {
    "allow": [],
    "read": [],
    "write": [],
    "allow_file": [],
    "read_file": [],
    "write_file": [],
    "deny": [],
    "bypass_protection": []
  },
  "security": {},
  "network": {
    "block": false,
    "allow_domain": [],
    "credentials": [],
    "open_port": [],
    "listen_port": [],
    "custom_credentials": {}
  },
  "env_credentials": {},
  "environment": {
    "allow_vars": []
  },
  "hooks": {},
  "rollback": {
    "exclude_patterns": [],
    "exclude_globs": []
  }
}
```

<Note>
  Fields that would override inherited behavior are intentionally omitted from the skeleton: `network_profile` (emitting `null` would clear an inherited proxy profile), `open_urls` (would replace inherited OAuth2 origins), `allow_launch_services` (would override inherited browser-opening permissions), and `allow_gpu` (would override inherited GPU access). Add these explicitly only when you intend to change the inherited behavior.
</Note>

### Validation

The `init` command validates inputs before writing:

* **Profile name** must be alphanumeric with hyphens (no leading/trailing hyphens)
* **`--extends`** target must exist as a preset, pack, or user profile
* **`--groups`** are checked against the embedded policy groups

After creating a profile, validate it:

```bash theme={null}
nono profile validate ~/.config/nono/profiles/my-agent.json
```

## JSON Schema

nono ships with a JSON Schema for profile files. Use it for editor autocomplete and validation.

### Exporting the Schema

```bash theme={null}
# Print to stdout
nono profile schema

# Write to a file
nono profile schema --output nono-profile.schema.json
```

### Editor Integration

Export the schema locally, then add a `$schema` field to your profile for automatic validation in editors that support JSON Schema (VS Code, IntelliJ, Neovim with LSP, etc.):

```json theme={null}
{
  "$schema": "./nono-profile.schema.json",
  "meta": {
    "name": "my-agent"
  }
}
```

In VS Code, you can also configure schema association in `.vscode/settings.json`:

```json theme={null}
{
  "json.schemas": [
    {
      "fileMatch": ["**/profiles/*.json"],
      "url": "./nono-profile.schema.json"
    }
  ]
}
```

## Authoring Guide

nono includes an embedded authoring guide designed for LLM agents assisting with profile creation:

```bash theme={null}
nono profile guide
```

This outputs a comprehensive reference covering every profile section, field descriptions, common patterns, variable expansion, and validation workflow. It is useful when asking an LLM to help you write a profile -- pipe or paste the guide into your conversation for context.

To make the guide automatically available to your coding agent, add a line to your project's instruction file (e.g., `CLAUDE.md`, `AGENT.md`, `.cursorrules`):

```md theme={null}
Should you need to work with nono profiles or policy, you can retrieve context using the `nono profile guide` command
```

## Workflow

A typical profile authoring workflow:

1. **Scaffold** the profile:
   ```bash theme={null}
   nono profile init my-agent --extends default --groups deny_credentials --full
   ```

2. **Edit** the generated file in your editor (with schema autocomplete):
   ```bash theme={null}
   $EDITOR ~/.config/nono/profiles/my-agent.json
   ```

3. **Validate** the profile:
   ```bash theme={null}
   nono profile validate ~/.config/nono/profiles/my-agent.json
   ```

4. **Inspect** the resolved profile (after inheritance and group expansion):
   ```bash theme={null}
   nono profile show my-agent
   ```

5. **Compare** against a baseline:
   ```bash theme={null}
   nono profile diff default my-agent
   ```

6. **Test** the profile:
   ```bash theme={null}
   nono run --profile my-agent --dry-run -- my-command
   ```

7. **Use** the profile:
   ```bash theme={null}
   nono run --profile my-agent -- my-command
   ```

## Available Groups

Use `nono profile groups` to list all available security groups. To see details for a specific group:

```bash theme={null}
nono profile groups deny_credentials
```

Groups are referenced by name in the `groups.include` field. See [Profiles & Groups](/cli/features/profiles-groups#groups) for the full group taxonomy and built-in group list.

<Note>
  The `groups.include` key was renamed from its former location under `security` in issue #594. The legacy key still deserializes with a deprecation warning; see `nono profile guide` for the full migration table. Legacy keys will be removed in v1.0.0.
</Note>

## Common Patterns

### Agent with API Credentials

```json theme={null}
{
  "extends": "default",
  "meta": {
    "name": "api-agent",
    "description": "Agent with API access via credential injection"
  },
  "workdir": { "access": "readwrite" },
  "env_credentials": {
    "openai_api_key": "OPENAI_API_KEY"
  },
  "network": {
    "network_profile": "standard"
  }
}
```

### CI Build Environment

```json theme={null}
{
  "meta": {
    "name": "ci-build",
    "description": "Locked-down CI environment"
  },
  "groups": {
    "include": ["deny_credentials"]
  },
  "workdir": { "access": "readwrite" },
  "network": { "block": true }
}
```

### Override a Deny Rule

```json theme={null}
{
  "extends": "default",
  "meta": {
    "name": "docker-agent",
    "description": "Agent that needs Docker access"
  },
  "workdir": { "access": "readwrite" },
  "filesystem": {
    "allow": ["$HOME/.docker"],
    "bypass_protection": ["$HOME/.docker"]
  }
}
```

<Note>
  `filesystem.bypass_protection` only removes the deny rule. You must also grant access via `filesystem.allow`, `filesystem.read`, or `filesystem.write` (or the matching `*_file` variant) for the path to be accessible.
</Note>

### Exclude Inherited Groups

```json theme={null}
{
  "extends": "default",
  "meta": {
    "name": "permissive-agent",
    "description": "Agent without deprecated startup-only command gating"
  },
  "workdir": { "access": "readwrite" },
  "groups": {
    "exclude": [
      "dangerous_commands",
      "dangerous_commands_macos",
      "dangerous_commands_linux"
    ]
  }
}
```

## CLI Reference

| Command                                         | Description                   |
| ----------------------------------------------- | ----------------------------- |
| `nono profile init <name>`                      | Generate a skeleton profile   |
| `nono profile init <name> --extends <base>`     | Inherit from a base profile   |
| `nono profile init <name> --groups <g1>,<g2>`   | Pre-populate security groups  |
| `nono profile init <name> --full`               | Include all optional sections |
| `nono profile init <name> --output <path>`      | Write to a specific file      |
| `nono profile init <name> --force`              | Overwrite existing file       |
| `nono profile init <name> --description <text>` | Set the profile description   |
| `nono profile schema`                           | Output JSON Schema to stdout  |
| `nono profile schema --output <path>`           | Write JSON Schema to a file   |
| `nono profile guide`                            | Print the authoring guide     |
