Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion docs/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Download the latest binary from [GitHub Releases](https://github.com/fullsend-ai
|--------------|-------------|
| [`fullsend agent`](agent.md) | Manage agent registrations — add, list, set, update, remove |
| [`fullsend github`](github.md) | Configure GitHub orgs and repos — setup, enrollment, day-2 operations |
| [`fullsend inference`](inference.md) | Manage GCP Workload Identity Federation for Agent Platform access |
| [`fullsend inference`](inference.md) | Manage inference credentials — GCP Workload Identity Federation for Agent Platform, and OpenAI WIF enrolment for GPT on pi |
| [`fullsend mint`](mint.md) | Deploy and manage the OIDC token mint service |
| [`fullsend repos`](repos.md) | Manage per-repo installations at scale via declarative manifest |

Expand Down
89 changes: 88 additions & 1 deletion docs/cli/inference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar_label: fullsend inference

# fullsend inference

Manage GCP Workload Identity Federation (WIF) infrastructure for Agent Platform access. These commands create, inspect, and remove the WIF pool, OIDC provider, and IAM bindings that allow GitHub Actions workflows to authenticate with GCP.
Manage the inference credentials agent runs use. `provision`, `deprovision` and `status` create, inspect, and remove the GCP Workload Identity Federation (WIF) pool, OIDC provider, and IAM bindings that let GitHub Actions workflows authenticate with GCP for Agent Platform (Vertex) access. [`openai`](#inference-openai) enrols repositories with OpenAI WIF for GPT models on the pi runtime.

## Commands

Expand All @@ -13,6 +13,9 @@ Manage GCP Workload Identity Federation (WIF) infrastructure for Agent Platform
| `fullsend inference provision <org\|owner/repo>` | Create WIF pool/provider and grant Agent Platform access |
| `fullsend inference deprovision <org\|owner/repo>` | Remove org or repo from WIF |
| `fullsend inference status <org\|owner/repo>` | Check WIF health and print config values |
| `fullsend inference openai request <owner/repo>[,…]` | Generate WIF provider/mapping request for OpenAI admin |
| `fullsend inference openai import [reply.json]` | Import OpenAI WIF identifiers into config |
| `fullsend inference openai status <owner/repo>` | Check OpenAI WIF configuration and exchange status |

## `inference provision`

Expand Down Expand Up @@ -80,8 +83,92 @@ fullsend inference status <org|owner/repo> \

Read-only — makes no changes.

## `inference openai`

Commands for enrolling repositories with OpenAI Workload Identity Federation (see the [operator guide](../guides/infrastructure/openai-workload-identity.md)). They need neither GCP access nor an OpenAI key.

What reaches the network, and what does not:

| Command | Network |
|---|---|
| `request` | None. The document is computed from the repository names. |
| `import` | None, unless `--variables` is passed: that calls the GitHub API through `gh` to set the three repository variables. |
| `status` | Reads configuration only, except inside a GitHub Actions job with `id-token: write`, where it performs one token exchange with OpenAI to prove the mapping accepts *that* job's repository — reporting the granted scope and expiry, never the token. |

No OpenAI API key is used or created by any of them.

### `inference openai request`

Generates the request document an administrator needs to enable OpenAI WIF for one or more repositories. Every value is computed from the repository names. Nothing is sent anywhere; the command needs no credentials.

```bash
fullsend inference openai request <owner/repo>[,<owner/repo>…] \
[--audience "<audience>"] \
[--project "<openai-project>"] \
[--service-account "<existing-sa-id>"] \
[--ref "refs/heads/<branch>"] \
[--format json|md] \
[--out <file>]
```

| Flag | Default | Description |
|------|---------|-------------|
| `--audience` | `fullsend://<owner>` | OpenAI Workload Identity audience |
| `--project` | *(empty)* | OpenAI project name or ID for the service accounts |
| `--service-account` | *(none)* | Map this existing service account instead of asking for `fullsend-<repo>-ci` to be created in the mapping |
| `--ref` | `refs/heads/main` | The `ref` assertion: the branch fullsend's agent workflows run from. Assertions are exact, so a repository whose default branch is not `main` needs this or every exchange fails |
| `--format` | `json` | Output format: `json` (versioned schema) or `md` (copy-paste ticket) |
| `--out` | *(stdout)* | Write output to a file |

### `inference openai import`

Takes the administrator's reply and writes `inference.openai` into `.fullsend/config.yaml` through the same setters as `fullsend github setup --openai-*`. All three identifiers must be present — a partial trio is refused, and the config is validated before it is written. The write is local: commit `.fullsend/config.yaml` afterwards, since fullsend reads the base branch for pull-request events.

The reply file may be either the bare reply object or the whole document `request --format json` produced with its `reply` section filled in — an administrator can edit and return the same file. When it names service accounts for several repositories, pass `--repo <owner/repo>` to choose one, or `--service-account-id` to give the value outright.

```bash
# From a reply JSON file:
fullsend inference openai import reply.json

# From flags:
fullsend inference openai import \
--audience "fullsend://<owner>" \
--identity-provider-id "<idp-id>" \
--service-account-id "<sa-id>"

# Set repository variables instead of config.yaml:
fullsend inference openai import \
--variables --repo <owner/repo> \
--audience "fullsend://<owner>" \
--identity-provider-id "<idp-id>" \
--service-account-id "<sa-id>"
```

| Flag | Default | Description |
|------|---------|-------------|
| `--audience` | | OpenAI Workload Identity audience |
| `--identity-provider-id` | | OpenAI identity provider ID |
| `--service-account-id` | | OpenAI service account ID |
| `--fullsend-dir` | `.fullsend` | Path to the .fullsend configuration directory |
| `--variables` | `false` | Set `FULLSEND_OPENAI_*` repository variables instead of config.yaml |
| `--repo` | | Two roles: the target repository for `--variables`, and the repository to select from a reply that names several (`service_account_ids`). Matched case-insensitively |

### `inference openai status`

Prints the resolved OpenAI WIF identifiers and their source (config layer or environment variables), and flags a partial trio. When run inside a GitHub Actions job with `id-token: write`, performs one exchange and reports the returned scope and expiry without ever printing the token.

```bash
fullsend inference openai status <owner/repo> \
[--fullsend-dir ".fullsend"]
```

| Flag | Default | Description |
|------|---------|-------------|
| `--fullsend-dir` | `.fullsend` | Path to the .fullsend configuration directory |

## See also

- [Getting inference for fullsend](../guides/getting-started/getting-inference.md) — getting started guide
- [OpenAI Workload Identity](../guides/infrastructure/openai-workload-identity.md) — end-to-end OpenAI WIF setup guide
- [Advanced setup](../guides/infrastructure/advanced-setup.md) — non-standard installation paths and WIF configuration
- [CLI internals](../guides/dev/cli-internals.md) — command tree and implementation details
20 changes: 17 additions & 3 deletions docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,23 @@ fullsend
│ ├── --repos <list> # Comma-separated repo names
│ ├── --mint-url <url> # Mint service URL ($FULLSEND_MINT_URL)
│ └── --audience <string> # OIDC audience (default: fullsend-mint)
├── inference # GCP: inference WIF management
├── inference # Inference credentials (GCP Vertex, OpenAI)
│ ├── provision <org|owner/repo> # Create WIF pool/provider for Agent Platform
│ ├── deprovision <org|owner/repo> # Remove WIF access for org or repo
│ └── status <org|owner/repo> # Check WIF health, print config
│ ├── status <org|owner/repo> # Check WIF health, print config
│ └── openai # OpenAI WIF enrolment (GPT on pi)
│ ├── request <owner/repo>[,...] # Generate the provider/mapping request for an admin
│ │ ├── --audience <string> # Provider audience (default: fullsend://<owner>)
│ │ ├── --project <name|id> # OpenAI project to bill the runs to
│ │ ├── --service-account <id> # Map an existing service account
│ │ ├── --ref <ref> # Ref assertion (default: refs/heads/main)
│ │ ├── --format <json|md> # Document format
│ │ └── --out <file> # Write to a file instead of stdout
│ ├── import [reply.json] # Record the admin's reply in config.yaml
│ │ ├── --audience/--identity-provider-id/--service-account-id
│ │ ├── --variables # Set FULLSEND_OPENAI_* repo variables instead
│ │ └── --repo <owner/repo> # Select from a multi-repo reply; target for --variables
│ └── status <owner/repo> # Resolved identifiers, and the exchange inside Actions
├── github # GitHub-only configuration
│ ├── setup <org|owner/repo> # Configure fullsend (no GCP needed)
│ ├── enroll <org> [repo...] # Enable repos for agent workflows
Expand Down Expand Up @@ -682,7 +695,8 @@ var executableFiles = map[string]struct{}{
| `internal/cli/root.go` | ~34 | CLI entry point, command registration |
| `internal/cli/admin.go` | ~2415 | Install/uninstall/analyze/enable/disable |
| `internal/cli/mint.go` | ~1022 | Mint deploy/enroll/unenroll/status |
| `internal/cli/inference.go` | ~408 | Inference WIF provision/status |
| `internal/cli/inference.go` | ~408 | Inference WIF provision/status (GCP) |
| `internal/cli/inference_openai.go` | ~900 | OpenAI WIF enrolment: request document, reply import, status/exchange |
| `internal/cli/github.go` | ~966 | GitHub setup/set/status/uninstall/sync-scaffold/enroll/unenroll |
| `internal/cli/issues.go` | ~430 | Issue read/write commands (`fullsend issues get`, `post-comment`) |
| `internal/cli/tracker_client.go` | ~122 | Tracker client factory (GitHub/GitLab/Jira) |
Expand Down
3 changes: 3 additions & 0 deletions docs/guides/getting-started/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ For organizations that separate GCP and GitHub responsibilities across teams, fu
| GCP Admin (Inference) | `fullsend inference provision <org\|owner/repo>` | Create WIF pool/provider and grant Agent Platform access (idempotent — safe to re-run for new orgs) |
| GCP Admin (Inference) | `fullsend inference deprovision <org\|owner/repo>` | Remove org or repo from WIF |
| GCP Admin (Inference) | `fullsend inference status <org\|owner/repo>` | Check WIF health, print config values |
| Repo Maintainer (OpenAI) | `fullsend inference openai request <owner/repo>[,...]` | Generate the provider/mapping request for an OpenAI organization admin (GPT on pi) |
| Repo Maintainer (OpenAI) | `fullsend inference openai import [reply.json]` | Record the admin's reply in `config.yaml`, or set the repository variables |
| Repo Maintainer (OpenAI) | `fullsend inference openai status <owner/repo>` | Check the OpenAI WIF identifiers, and the exchange when run inside Actions |
| GitHub Maintainer | `fullsend github setup <org\|owner/repo>` | Configure GitHub org or repo (no GCP needed) |
| GitHub Maintainer | `fullsend github enroll <org> [repo...]` | Add repositories to agent enrollment |
| GitHub Maintainer | `fullsend github unenroll <org> [repo...]` | Remove repositories from agent enrollment |
Expand Down
Loading
Loading