Skip to content

Commit 40eb1f7

Browse files
dvdksnclaude
andauthored
docs(sandboxes): document file.parser and deniedDomains in kits spec (#25030)
## Summary - Adds a `#### file.parser` subsection under the Credentials spec reference, covering supported forms (`json:<dot.path>` and plain text), JSON path rules and limitations, priority/fallback behaviour for missing files, worked examples, and common error messages. Behaviour verified against `sandboxd/pkg/secrets/store.go`. - Adds `deniedDomains` to the Network spec reference table, which was missing despite being a supported field. Deny rules take precedence over allow rules including those from composed kits. ## Test plan - [ ] `docker buildx bake lint vale` — passes clean for this file - [ ] Spot-check rendered output on staging 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1c519b2 commit 40eb1f7

1 file changed

Lines changed: 78 additions & 9 deletions

File tree

  • content/manuals/ai/sandboxes/customize

content/manuals/ai/sandboxes/customize/kits.md

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -505,12 +505,81 @@ credentials:
505505
| -------------------------- | ------------------------------------------------------------- |
506506
| `sources` | Map of service identifier to credential source. |
507507
| `sources.<id>.env` | Environment variables to read on the host, in priority order. |
508-
| `sources.<id>.file.path` | Path on host. `~` expands to home. |
509-
| `sources.<id>.file.parser` | How to extract the value (for example, `"json:apiKey"`). |
508+
| `sources.<id>.file.path` | Path on host. `~` expands to home directory. |
509+
| `sources.<id>.file.parser` | How to extract the credential value from the file. |
510510
| `sources.<id>.priority` | `env-first` (default) or `file-first`. |
511511

512512
Service identifiers link credentials to [network rules](#network).
513513

514+
#### file.parser
515+
516+
`file.parser` tells the proxy how to extract a credential from the file at `file.path`.
517+
Omit it for plain-text files; set it to `json:<dot.path>` to extract a field from a JSON file.
518+
519+
| Value | Behavior |
520+
| ----------------- | ------------------------------------------------------------------------------------ |
521+
| omitted or empty | Reads the entire file as the credential. Leading and trailing whitespace is trimmed. |
522+
| `json:<dot.path>` | Parses the file as JSON and returns the value at the dot-separated path. |
523+
| any other value | Rejected — `unsupported parser: <value>`. |
524+
525+
For `json:` paths, segments are separated by `.` (for example, `json:credentials.github.token`).
526+
Only object keys can be navigated — arrays are not supported and there is no `[0]`-style indexing.
527+
Keys that contain a literal `.` cannot be referenced. The resolved value must be a string, number,
528+
or boolean; numbers and booleans are converted to strings. Objects, arrays, and null are rejected.
529+
530+
When a source has both `env` and `file` defined, `priority` controls which is tried first. The
531+
preferred source is used when it exists — the environment variable is set, or the file is
532+
present on disk. If it doesn't, the other source is used instead. The choice is made once at
533+
discovery time, so parser errors (missing JSON field, wrong value type, invalid JSON) surface
534+
as errors rather than triggering a fallback.
535+
536+
Plain-text token file:
537+
538+
```yaml
539+
credentials:
540+
sources:
541+
openai:
542+
file:
543+
path: "~/.openai/token"
544+
```
545+
546+
Nested JSON field, with an environment variable as fallback:
547+
548+
```yaml
549+
credentials:
550+
sources:
551+
github:
552+
env:
553+
- GH_TOKEN
554+
file:
555+
path: "~/.config/myapp/creds.json"
556+
parser: "json:credentials.github.token"
557+
priority: file-first
558+
```
559+
560+
Given `~/.config/myapp/creds.json`:
561+
562+
```json
563+
{
564+
"credentials": {
565+
"github": { "token": "ghp_xyz", "expires": "2026-12-31" }
566+
}
567+
}
568+
```
569+
570+
The proxy resolves the credential to `ghp_xyz`, falling back to `GH_TOKEN` if the file is
571+
missing. If the file exists but the JSON path doesn't resolve, the request fails with the
572+
parser error below instead of falling back.
573+
574+
Common errors when using `json:` parsers:
575+
576+
| Error message | Cause |
577+
| --------------------------------------------- | ------------------------------------------------------------------- |
578+
| `field 'X' not found in JSON` | The path doesn't exist in the file. |
579+
| `cannot navigate to field 'X': not an object` | A path segment hit a string, array, or scalar instead of an object. |
580+
| `field 'X' is not a string value` | The resolved value is an object, array, or null. |
581+
| `failed to parse JSON: ...` | The file is not valid JSON. |
582+
514583
### Network
515584

516585
```yaml
@@ -525,13 +594,13 @@ network:
525594
valueFormat: <format>
526595
```
527596

528-
| Field | Description |
529-
| ------------------------- | ---------------------------------------------------------------- |
530-
| `allowedDomains` | Domains the sandbox can reach. Wildcards supported. |
531-
| `deniedDomains` | Domains the sandbox can't reach. Deny rules take precedence. |
532-
| `serviceDomains` | Map of domain to service identifier from `credentials.sources`. |
533-
| `serviceAuth.headerName` | HTTP header the proxy sets (for example, `Authorization`). |
534-
| `serviceAuth.valueFormat` | Format string for the header value (for example, `"Bearer %s"`). |
597+
| Field | Description |
598+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
599+
| `allowedDomains` | Domains the sandbox can reach. Wildcards supported. |
600+
| `deniedDomains` | Domains the sandbox is blocked from reaching. Deny rules take precedence over allow rules, including those from other composed kits. |
601+
| `serviceDomains` | Map of domain to service identifier from `credentials.sources`. |
602+
| `serviceAuth.headerName` | HTTP header the proxy sets (for example, `Authorization`). |
603+
| `serviceAuth.valueFormat` | Format string for the header value (for example, `"Bearer %s"`). |
535604

536605
### Environment
537606

0 commit comments

Comments
 (0)