spotlight_harness_profile

The spotlight_harness_profile resource, and the API's harness-profile kind: a team's set of permission rules, MCP servers and native harness settings. A station names one in its profile.

KindEndpointTerraformAddress
harness-profile/api/resources/teams/{teamId}/harness-profilesspotlight_harness_profile<team key>/<key>

See Resource API for the operations, headers and errors every kind shares.

Example

resource "spotlight_harness_profile" "core_careful" {
  team_id = spotlight_team.core.id
  key     = "careful"

  permissions = {
    allow = ["read", "edit", "execute(npm test *)"]
    ask   = ["execute(git push *)"]
    deny  = ["read(.env)"]
  }

  mcp_servers = [
    {
      name    = "acme"
      command = "npx"
      args    = ["-y", "acme-mcp"]
      env     = { ACME_API_KEY = "secret.ACME_API_KEY" }
    },
  ]

  native = {
    claude-code = { includeCoAuthoredBy = false }
    codex       = "model_verbosity = \"low\"\n"
  }
}

Fields

FieldTypeDefaultDescription
keystringrequiredWhat stations name the profile by, as in careful. Lowercase words joined by dashes, at most 64 characters. Fixed: an update that changes it is refused; Terraform replaces the resource.
permissions.allowarray of strings[]Rules for what the agent may do.
permissions.askarray of strings[]Rules for what the agent asks a person about first.
permissions.denyarray of strings[]Rules for what the agent may never do.
mcpServersarray of objects[]Stdio MCP servers, started in the sandbox. A remote server is named on an integration instead; see MCP servers.
nativeobject{}Each harness's own settings, by harness id. See native settings.

permissions accepts no other keys.

Permission rules

A rule is a kind, alone or with a pattern in parentheses.

KindCovers
readreading and searching files
editediting, deleting and moving files
executerunning commands
RuleMeaning
executeevery command
execute(npm test *)commands matching the pattern
read(.env)reading the paths matching the pattern
  • A pattern may not be empty.
  • A rule may appear once, under one of allow, ask and deny.
  • For each kind, a bare rule sets what happens to anything no patterned rule matches. A kind has at most one bare rule.
  • A kind with no bare rule is allowed.
  • A rule with a pattern is an exception to the kind's bare rule.

An ask rule becomes a Spotlight approval. A permission request is put to a person only when its kind has an ask rule, bare or patterned; a request of any other kind, such as a web fetch, is allowed. See Approvals.

MCP servers

FieldTypeDefaultDescription
namestringrequiredLowercase words joined by dashes, at most 64 characters. Each name once per profile.
commandstringrequiredThe command that starts the server, as in npx.
argsarray of strings[]Its arguments.
envmap of name to string{}Its environment. Names match ^[A-Za-z_][A-Za-z0-9_]*$.

An env value is plain text, stored and shown as written, or a reference to a workspace secret written secret.<NAME>, as in secret.ACME_API_KEY.

  • A reference must name a secret the workspace holds, or the write is refused with 422.
  • The server receives a stand-in, and egress puts the value in place of it, in the server's requests to the host the secret is bound to.
  • A secret a profile references cannot be deleted.

Every harness gets the servers when its session starts. Cursor also gets them in cursor/mcp.json.

Native settings

KeyValueRead by the harness as
claude-codean objectClaude Code settings JSON
codexa string of TOMLCodex config.toml
cursoran objectCursor CLI config JSON

A key that names no harness, a claude-code or cursor value that is not an object, and a codex value that does not parse as TOML are refused with 422.

How each harness receives it

A run's harness gets the profile's settings as files in the run's state directory, .spotlight/state within the run's workspace. See Inside a sandbox. Spotlight does not remove a repository's own settings files, such as .claude/settings.json or AGENTS.md.

HarnessFilesDirectory variableAlso
claude-codeclaude/settings.jsonCLAUDE_CONFIG_DIRask and deny rules go into the session as managed settings, with bypass-permissions mode disabled.
codexcodex/config.toml, codex/rules/spotlight.rulesCODEX_HOMEThe harness runs in codex-acp's read-only mode, with a workspace-write sandbox on every turn.
cursorcursor/cli-config.json, cursor/mcp.jsonCURSOR_CONFIG_DIR
HarnessWhat the files hold
claude-codepermissions.allow and permissions.defaultMode from the rules, then native.claude-code layered over them. defaultMode is acceptEdits unless edit is not allowed. Each MCP server is allowed as mcp__<name>.
codexconfig.toml is native.codex as written. spotlight.rules holds a prefix_rule for each execute rule with a pattern.
cursorcli-config.json holds permissions.allow and permissions.deny from the rules, then native.cursor layered over them. mcp.json holds the MCP servers.

Warnings

Where a harness cannot hold a rule as written, the profile's warnings name the approximation. The write succeeds. Warnings include:

HarnessCaseEffect
claude-codeA looser patterned rule under a bare deny, or under a bare ask for readThe bare rule holds for the whole kind.
claude-code, cursornative sets a key the rules also writeThe native value replaces it.
codexAny read rule other than allowNot held; Codex reads what its sandbox can see.
codexA bare edit rule other than allow, or any edit rule with a patternNot held; edits are decided by the sandbox.
codexA bare execute rule other than allowNot held; only patterned execute rules are.
codexAn execute pattern with a wildcard other than a final * wordWritten as every command starting with the words before the wildcard.
codexAn execute pattern starting with a wildcardLeft out.
codexnative.codex sets approval_policy, approvals_reviewer or sandbox_modeReplaced on every turn.
cursorA bare ask for readRead is allowed.
cursorA patterned rule under a bare denyThe kind is denied.
cursorAn ask rule under an allowed kindDenied instead.
cursorAn execute pattern of more than one wordWritten for the command's first word only.
cursorAny MCP serverMay not load: Cursor asks a person to approve each server, and ACP carries no such request.

Delete

A delete is refused with 409 in-use while any station names the profile.

A station that names a profile its team does not hold is not refused when the line is written; its runs are refused.

See Limit what agents may do and Give an MCP server a secret.

On this page