Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 91 additions & 38 deletions docs/dir/directory-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ The following example demonstrates how to store, publish, search, and retrieve a

The CLI supports Docker-style name references in addition to CIDs. Records can be pulled using formats like `name`, `name:version`, or `name:version@cid` for hash-verified lookups. See [Name Verification](#name-verification) for details.

!!! note "Authentication for federation"
!!! note "Authentication for remote Directory servers"

When accessing Directory federation nodes, authenticate first with `dirctl auth login`. See [Authentication](#authentication) for details.
When accessing a remote Directory server, authenticate first with `dirctl auth login`. See [Authentication](#authentication) for details.

## Common Workflows

Expand Down Expand Up @@ -309,67 +309,93 @@ dirctl routing list -o json | jq -r '.[].cid' | xargs -I {} dirctl pull {}

## Authentication

Authentication is required when accessing Directory federation nodes. The CLI supports multiple authentication modes, with GitHub OAuth recommended for interactive use.
Authentication is required when accessing remote Directory servers. The CLI supports OIDC-based authentication for humans and CI workflows, with pre-issued tokens for service users and automation.

| Command | Description |
|---------|-------------|
| `dirctl auth login` | Authenticate with GitHub |
| `dirctl auth login` | Authenticate via OIDC (browser PKCE, headless, or device flow) |
| `dirctl auth logout` | Clear cached authentication credentials |
| `dirctl auth status` | Show current authentication status |

### GitHub OAuth Authentication
### OIDC Authentication

GitHub OAuth (Device Flow) enables secure, interactive authentication for accessing federation nodes.
OIDC is the default authentication model for remote Directory access. Supported patterns:

#### `dirctl auth login`
- **Interactive login** (PKCE) via `dirctl auth login`
- **Headless login** via `dirctl auth login --no-browser`
- **Device flow** via `dirctl auth login --device` (no browser needed on this machine)
- **Pre-issued token** via `--auth-token` / `DIRECTORY_CLIENT_AUTH_TOKEN` (CI, scripts, service users)

Authenticate with GitHub using the OAuth 2.0 Device Flow. No prerequisites.
#### Interactive login (`dirctl auth login`)

Authenticate as a human user using OIDC Authorization Code + PKCE.

```bash
# Start login (shows a code and link)
# Using flags
dirctl auth login \
--oidc-issuer "https://prod.idp.ads.outshift.io" \
--oidc-client-id "dirctl"

# Or using environment variables
export DIRECTORY_CLIENT_OIDC_ISSUER="https://prod.idp.ads.outshift.io"
export DIRECTORY_CLIENT_OIDC_CLIENT_ID="dirctl"
dirctl auth login
```

What happens:

1. The CLI displays a short-lived **code** (e.g. `9190-173C`) and the URL **https://github.com/login/device**
2. You open that URL (on this machine or any device), enter the code, and authorize the application
3. After you authorize, the CLI receives a token and caches it at `~/.config/dirctl/auth-token.json`
4. Subsequent commands automatically use the cached token (no `--auth-mode` flag needed)
1. The CLI opens browser-based login against your OIDC issuer
2. You authenticate with your credentials
3. The CLI caches the token at `~/.config/dirctl/auth-token.json`
4. Subsequent commands can reuse the cached token (auto-detect or `--auth-mode=oidc`)

```bash
# Force re-login even if already authenticated
dirctl auth login --force

# Show code and URL only (do not open browser automatically)
# Headless: show URL only, do not open browser automatically
dirctl auth login --no-browser
```

!!! note "Custom OAuth App (optional)"
To use your own GitHub OAuth App instead of the default, create an OAuth App in [GitHub Developer Settings](https://github.com/settings/developers) with Device Flow support and set `DIRECTORY_CLIENT_GITHUB_CLIENT_ID` (and optionally `DIRECTORY_CLIENT_GITHUB_CLIENT_SECRET`). For normal use, leave these unset.
#### Device flow login (`dirctl auth login --device`)

Authenticate without a browser on the current machine. Useful for SSH sessions, containers, or remote servers.

```bash
dirctl auth login --device \
--oidc-issuer "https://prod.idp.ads.outshift.io" \
--oidc-client-id "dirctl"
```

The same environment variables from interactive login apply (`DIRECTORY_CLIENT_OIDC_ISSUER`, `DIRECTORY_CLIENT_OIDC_CLIENT_ID`).

What happens:

1. The CLI displays a code and a URL
2. You open the URL on any device (phone, another computer) and enter the code
3. You authenticate with your credentials
4. The CLI polls until authorization completes, then caches the token

#### `dirctl auth status`

Check your current authentication status.

```bash
# Show authentication status
dirctl auth status

# Validate token with GitHub API
dirctl auth status --validate
```

Example output:

```
Status: Authenticated
User: your-username
Organizations: agntcy, your-org
Cached at: 2025-12-22T10:30:00Z
Provider: oidc
Subject: johndoe
Issuer: https://prod.idp.ads.outshift.io
Email: johndoe@example.com
Cached at: 2026-01-15T10:30:00+00:00
Token: Valid ✓
Estimated expiry: 2025-12-22T18:30:00Z
Cache file: /Users/you/.config/dirctl/auth-token.json
Expires: 2026-01-15T11:30:00+00:00
Cache file: /home/johndoe/.config/dirctl/auth-token.json
```

#### `dirctl auth logout`
Expand All @@ -382,41 +408,59 @@ dirctl auth logout

#### Using Authenticated Commands

Once authenticated via `dirctl auth login`, your cached credentials are automatically detected and used:
Once authenticated, cached credentials are automatically detected and used:

```bash
# Push to federation (auto-detects and uses cached GitHub credentials)
# Push to remote Directory server (auto-detects and uses cached OIDC credentials)
dirctl push my-agent.json

# Search federation nodes (auto-detects authentication)
dirctl --server-addr=federation.agntcy.org:443 search --skill "natural_language_processing"
# Search remote Directory server (auto-detects authentication)
dirctl --server-addr=prod.gateway.ads.outshift.io:443 search --skill "natural_language_processing"

# Pull from federation (auto-detects authentication)
# Pull from remote Directory server (auto-detects authentication)
dirctl pull baeareihdr6t7s6sr2q4zo456sza66eewqc7huzatyfgvoupaqyjw23ilvi
```

**Authentication mode behavior:**

- **No `--auth-mode` flag (default)**: Auto-detects authentication in this order: SPIFFE (if available in Kubernetes/SPIRE environment), cached GitHub credentials (if `dirctl auth login` was run), then insecure (for local development).
- **Explicit `--auth-mode=github`**: Forces GitHub authentication (e.g. to bypass SPIFFE in a SPIRE environment).
- **No `--auth-mode` flag (default)**: Auto-detects authentication in this order: SPIFFE (if available in Kubernetes/SPIRE environment), OIDC (explicit token or cached token), then insecure (for local development).
- **Explicit `--auth-mode=oidc`**: Forces OIDC authentication.
- **Other modes**: Use `--auth-mode=x509`, `--auth-mode=jwt`, or `--auth-mode=tls` for specific authentication methods.

```bash
# Force GitHub auth even if SPIFFE is available
dirctl --auth-mode=github push my-agent.json
# Force OIDC auth even if SPIFFE is available
dirctl --auth-mode=oidc push my-agent.json
```

#### Pre-issued Tokens (CI and Service Users)

For CI/CD pipelines and automation, pass a pre-issued JWT token directly:

```bash
# GitHub Actions OIDC
dirctl search --name "*" \
--server-addr "prod.gateway.ads.outshift.io:443" \
--auth-mode=oidc \
--auth-token "<github-oidc-jwt>" \
--output json

# Service user with pre-generated token
export DIRECTORY_CLIENT_AUTH_TOKEN="<service-user-jwt>"
export DIRECTORY_CLIENT_SERVER_ADDRESS="prod.gateway.ads.outshift.io:443"
dirctl search --auth-mode=oidc
```

### Other Authentication Modes

| Mode | Description | Use Case |
|------|-------------|----------|
| `github` | GitHub OAuth (explicit) | Force GitHub auth, bypass SPIFFE auto-detect |
| `oidc` | OIDC bearer/JWT auth | Human login, pre-issued tokens, and CI workload identity |
| `x509` | SPIFFE X.509 certificates | Kubernetes workloads with SPIRE |
| `jwt` | SPIFFE JWT tokens | Service-to-service authentication |
| `token` | SPIFFE token file | Pre-provisioned credentials |
| `tls` | mTLS with certificates | Custom PKI environments |
| `insecure` / `none` | No auth, skip auto-detect | Testing, local development |
| (empty) | Auto-detect: SPIFFE → cached GitHub → insecure | Default behavior (recommended) |
| (empty) | Auto-detect: SPIFFE → OIDC → insecure | Default behavior (recommended) |

## Configuration

Expand All @@ -434,15 +478,24 @@ dirctl routing list
### Authentication

```bash
# Use SPIFFE Workload API
# OIDC authentication (most common)
export DIRECTORY_CLIENT_OIDC_ISSUER="https://prod.idp.ads.outshift.io"
export DIRECTORY_CLIENT_OIDC_CLIENT_ID="dirctl"
dirctl auth login

# Pre-issued token (CI/service users)
export DIRECTORY_CLIENT_AUTH_TOKEN="<jwt>"
dirctl --auth-mode=oidc routing list

# SPIFFE Workload API (Kubernetes)
dirctl --spiffe-socket-path /run/spire/sockets/agent.sock routing list
```

## Command Organization

The CLI follows a clear service-based organization:

- **Auth**: GitHub OAuth authentication (`auth login`, `auth logout`, `auth status`).
- **Auth**: OIDC authentication (`auth login`, `auth logout`, `auth status`).
- **Storage**: Direct record management (`push`, `pull`, `delete`, `info`).
- **Import**: Batch imports from external registries (`import`).
- **Routing**: Network announcement and discovery (`routing publish`, `routing list`, `routing search`).
Expand Down
Loading