Skip to content
Closed
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include (no `.`/`..`); a lone `--require-hashes` directive is not trust evidence. See [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md).
Conflict-scope roots fail closed when the immediate parent directory is a symbolic link.
Cursor Cloud Agents cannot complete Figma MCP OAuth against `https://mcp.figma.com/mcp` (allowlisted-client catalog; Cloud unsupported). Desktop/CLI remain the MCP path. Cloud Agents that must read Figma files use the `FIGMA_ACCESS_TOKEN` secret with the REST API: `python3 scripts/ci/figma_rest_auth.py` then `--file FILE_KEY`. See [`docs/doctoring/figma-cloud-agent-mcp-auth.md`](docs/doctoring/figma-cloud-agent-mcp-auth.md).
28 changes: 27 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,30 @@ sequenceDiagram
- Rust remains the psychometric arithmetic owner. Repair never substitutes
Python for scoring math.

## Figma REST fallback

```mermaid
flowchart LR
Desktop["Desktop / CLI"]
Cloud["Cloud Agent / Automation"]
MCP["Figma MCP OAuth"]
REST["api.figma.com REST"]
Whoami["GET /v1/me"]
File["GET /v1/files/:key?depth=1"]

Desktop --> MCP
Cloud -->|"FIGMA_ACCESS_TOKEN"| REST
REST --> Whoami
Whoami -->|"secret valid"| File
File -->|"page names"| BuyerNext["Pick a page / node / image"]
```

Cloud Agents do not complete Figma MCP Connect. They send only
`X-Figma-Token` on a pinned `HTTPSConnection("api.figma.com")`, refuse
`file://` and `Host` overrides, and load one file at `depth=1` so the next
action is a named page rather than the entire document tree. See
[`docs/doctoring/figma-cloud-agent-mcp-auth.md`](docs/doctoring/figma-cloud-agent-mcp-auth.md).

## Quality gates

`scripts/ci/` ships with 100% statement/branch coverage and 100% docstrings.
Expand All @@ -107,4 +131,6 @@ tests pin workflow structure and governance prose so drift fails closed.
- [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md)
— current increment's repair-worker decision and APA 7th citations.
- [`docs/doctoring/fast-mlsirm-hourly-review-caller.md`](docs/doctoring/fast-mlsirm-hourly-review-caller.md)
— product-specific psychometric repair heartbeat and scientific gates.
— product-specific psychometric repair heartbeat and scientific gates.
- [`docs/doctoring/figma-cloud-agent-mcp-auth.md`](docs/doctoring/figma-cloud-agent-mcp-auth.md)
— Cloud Agent Figma MCP boundary and REST `--file` fallback.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Semantic Versioning where the repository publishes a release.

### Added

- Added a Cloud Agent Figma REST fallback that verifies `FIGMA_ACCESS_TOKEN` against `GET /v1/me` and loads one file at `GET /v1/files/:key?depth=1`, so agents can inventory pages after MCP Connect fails.
- Added a trusted pull-request comment router for `@cwl-noema-review` and review-only `@opencode-agent` dispatches, with an organization sweep, exact-head receipts, repository allowlisting, fixed runners, immutable checkout pins, and a permanent 100% statement/branch/docstring quality gate.
- Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence.
- Added a permanent exact-head contract workflow for the hourly review-repair scheduler, immutable reusable-workflow source, NVIDIA NIM model boundary, credential isolation, and fail-closed unattended-agent permissions.
Expand Down Expand Up @@ -39,6 +40,7 @@ Semantic Versioning where the repository publishes a release.

### Security

- Pin Figma REST calls to `http.client.HTTPSConnection("api.figma.com")`, allow only the `X-Figma-Token` header, accept alphanumeric file keys, and cap whoami/file bodies so `file://`, `Host` retargeting, and unbounded reads cannot leave the helper.
- Reject `.github/` and `scripts/ci/` from review-thread-derived autofix path authority so an untrusted inline reviewer cannot authorize the write-capable repair agent to modify workflows, CODEOWNERS, actions, scheduler code, or CI helpers that govern its own control plane.
- Require the model-write snapshot and exact-path allowlist to remain outside the pull-request worktree, checking both absolute and resolved locations so repository-local controls and outside-looking symlinks resolving into the repository fail closed before they can authorize or verify model changes.
- Snapshot the complete pre-model worktree for ordinary and conflict repair and reject every model-caused created, deleted, modified, mode-changed, retargeted, ignored, dangling, directory-backed, external-link, metadata-race, or out-of-scope path before staging or push.
Expand All @@ -55,6 +57,7 @@ Semantic Versioning where the repository publishes a release.

### Documentation

- Recorded the Cloud Agent Figma MCP boundary, plan-token preference, `--file` next action, and APA 7th citations for Figma REST authentication, file endpoints, OAuth 2.1, PKCE, RFC 9110, and CWE-22.
- Added an APA 7 doctoring record for conflict-control evidence isolation, including the Strix-reported trust-boundary failure, test-first remediation, canonical-path rule, operator contract, rollback, MITRE CWE-22, and current GitHub Actions secure-use guidance.
- Added operator and APA 7 doctoring records for the hourly cadence, immutable source identity, NVIDIA NIM provider and secret boundary, high-reasoning Mistral Small 4 writer, model-process credential isolation, modular MSA ownership, product-specific caller activation, verification contract, and rollback.
- Added DiskSage operational documentation for the hourly RCA loop, bounded retry cadence, permission model, standalone and MSA reuse, verification, rollback, and APA 7 references.
Expand Down
1 change: 1 addition & 0 deletions docs/CWL-MASTER-CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ GitHub **Project #1** is the shared source of truth. Structure: real **Issues**
- **BLOCKER B1**: org GitHub Actions effectively HALTED (~86 queued, ~0 in_progress org-wide) — likely the Actions monthly SPENDING CAP. Blocks ALL PR checks/merges + the Cloudflare DNS run (nameservers). Fix (org-admin): raise the Actions spending limit OR add a self-hosted runner. Nothing merges until then.
- **Decisions pending**: (D1) Code Security enablement vs the CodeQL-only code_scanning ruleset (osv/trivy/scorecard SARIF upload) — a private repo needs GHAS seats; reconcile or make those checks non-required. (D2) trivy `limit-severities-for-sarif: true` (gate only CRITICAL/HIGH) — held pending the user's strict-security preference.
- **Built this session, PR-open, awaiting merge (B1)**: see Project #1 PRs (contextual-orchestrator cost/routing #46 + naruon#973; pg-llm-batch; keyverse Keycloak; inkspan; SBOM #361; opencode auto-retry #360; Strix neutral #349 + emit #358; appguardrail collector #254; auto-rebase #357; noema #359/naruon#970; PDF-DOM naruon#965/newsdom#300; SDP #11; fast-mlsirm GPGPU #109; scopeweave #284/naruon#971; fuzzing 10 PRs (found+fixed 2 real naruon bugs); Cloudflare DNS/Pages #362; this protocol #363; planning #974). Human step: report the mapasevo21 malware file (github user-attachments) to GitHub Abuse; rotate the xtrmLLMBatchPython-leaked keys; the org-admin runner/decisions above.
- **Figma MCP on Cloud Agents (2026-08-16)**: `https://mcp.figma.com/mcp` is OAuth-only and not supported in Cursor Cloud Agents / Automations. Desktop IDE and CLI remain the MCP path. Cloud Agents that must read Figma files store a personal or plan access token as `FIGMA_ACCESS_TOKEN`, run `python3 scripts/ci/figma_rest_auth.py`, then `python3 scripts/ci/figma_rest_auth.py --file FILE_KEY` for page-level REST metadata. See `docs/doctoring/figma-cloud-agent-mcp-auth.md`.

---
*Keep this current. Update Project #1 as the live tracker; this file is the narrative brief a fresh agent reads to reconstruct the whole picture.*
Expand Down
138 changes: 138 additions & 0 deletions docs/doctoring/figma-cloud-agent-mcp-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Figma MCP auth on Cursor Cloud Agents

## Incident

A Cursor Cloud Agent tasked with Figma work discovers the official Figma MCP
server (`https://mcp.figma.com/mcp`) in an `error` state: live tool discovery
fails and no Figma tools are available. Re-running Connect / OAuth from the
Cloud Agent cannot repair it. Desktop Cursor and the Cursor CLI remain able to
complete the same OAuth flow.

## Live evidence (2026-08-16)

Unauthenticated `initialize` against the remote MCP endpoint:

```http
POST https://mcp.figma.com/mcp
HTTP/2 401
WWW-Authenticate: Bearer resource_metadata="https://mcp.figma.com/.well-known/oauth-protected-resource",scope="mcp:connect",authorization_uri="https://api.figma.com/.well-known/oauth-authorization-server"
```

Body: `Unauthorized`.

The same environment can reach Figma (`HEAD`/`POST` complete; no egress block).
`GET https://api.figma.com/v1/me` without a token returns
`{"status":403,"err":"Invalid token"}`. No `FIGMA_*` environment variables are
present on the Cloud Agent VM.

Figma's remote MCP is OAuth 2.1 with PKCE and an allowlisted MCP client
catalog. Cursor Cloud Agents are not a supported client for that catalog.

## Decision

Do not treat Figma MCP as available inside Cloud Agents or Cloud Automations.
Cursor staff stated this explicitly: Figma MCP is not supported in Cloud agents;
it is fully supported in the IDE and the CLI (Neilson, 2026). There is no
estimated timeline; support is a joint Cursor/Figma change.

Use two disjoint auth paths:

| Surface | Auth | Capability |
|---|---|---|
| Cursor Desktop / CLI | Figma MCP OAuth (`Settings → Tools & MCP → Figma → Connect`) | Full MCP toolset (`get_design_context`, `use_figma`, write-to-canvas, …) |
| Cursor Cloud Agent | Figma personal or plan access token in `FIGMA_ACCESS_TOKEN` | REST only (`X-Figma-Token` on `https://api.figma.com/v1/...`) |

A personal or plan access token does **not** unlock Figma MCP on Cloud Agents.
It only authorizes the REST API. Do not commit the token. Do not put it in
`environment.json`, workflow YAML, or chat output.

Prefer a **plan access token** for organization CI and Cloud Agent fleets
(admin-managed, not tied to one person, expiry up to one year; Figma, n.d.-a).
Use a personal access token only when the operator is acting on their own
account (maximum 90 days). Both kinds are stored in the same secret name.

Whoami is not enough for design-to-code. After the secret is present, load one
file at `GET /v1/files/:key?depth=1` so the next action is a named page, node,
or image request rather than downloading the entire document tree (Figma,
n.d.-c). File keys are the `:file_key` segment from
`https://www.figma.com/:file_type/:file_key/:file_name` and must be 8–128
alphanumeric characters (CWE-22 path-restriction; MITRE, 2026). The helper
sends only `X-Figma-Token`, pins `http.client.HTTPSConnection("api.figma.com")`,
and caps whoami bodies at 64 KiB and file bodies at 8 MiB (RFC 9110 message
framing; Fielding et al., 2022).

## Operator procedure

1. **Desktop / CLI MCP (preferred for design-to-code).** In Cursor Desktop,
Settings → Tools & MCP → Figma → Connect, then Allow access in the Figma
browser window. Confirm with a Figma MCP `whoami` from a desktop agent.
2. **Cloud Agent REST secret.** In Figma: account menu → Settings → Security
→ Personal access tokens → Generate new token, or ask a plan admin for a
plan access token. Grant `file_content:read` (add comment scopes only if
needed). Store the value as the Cursor environment secret
`FIGMA_ACCESS_TOKEN`.
3. **Verify the secret without printing it:**

```bash
python3 scripts/ci/figma_rest_auth.py
```

Success prints a handle/id/email line. Missing or rejected tokens exit
non-zero and never echo the secret.
4. **Load the file the buyer asked for** (copy the key from the Figma URL):

```bash
python3 scripts/ci/figma_rest_auth.py --file FILE_KEY
```

Success prints page names plus component and style counts. Next: request
that page's node JSON or images over REST. The helper opens a pinned
`http.client.HTTPSConnection("api.figma.com")` and refuses any other URL,
so Semgrep `dynamic-urllib-use-detected` does not apply
(`urllib.request.urlopen` is not used).

## Why MCP Connect cannot be finished here

Figma only accepts MCP clients listed in its catalog (Figma, n.d.-d). The
Cloud Agent MCP client is not on that list, so the OAuth authorize endpoint
answers `Forbidden` / `401` before a browser grant can be created. Asking the
user to "click Connect" inside a Cloud Agent or Automation therefore cannot
succeed. The same Connect button works in the desktop IDE because that client
is allowlisted.

## References (APA 7th edition)

Fielding, R., Nottingham, M., & Reschke, J. (Eds.). (2022). *HTTP semantics*
(RFC 9110). RFC Editor. https://doi.org/10.17487/RFC9110

Figma. (n.d.-a). *Authentication*. Figma Developer Docs. Retrieved August 16,
2026, from https://developers.figma.com/docs/rest-api/authentication/

Figma. (n.d.-b). *Personal access tokens*. Figma Developer Docs. Retrieved
August 16, 2026, from
https://developers.figma.com/docs/rest-api/personal-access-tokens/

Figma. (n.d.-c). *Files*. Figma Developer Docs. Retrieved August 16, 2026,
from https://developers.figma.com/docs/rest-api/file-endpoints/

Figma. (n.d.-d). *Set up the remote server (recommended)*. Figma Developer
Docs. Retrieved August 16, 2026, from
https://developers.figma.com/docs/figma-mcp-server/remote-server-installation/

Figma. (n.d.-e). *Changelog*. Figma Developer Docs. Retrieved August 16, 2026,
from https://developers.figma.com/docs/rest-api/changelog/

MITRE. (2026). *CWE-22: Improper limitation of a pathname to a restricted
directory ('Path Traversal')*. https://cwe.mitre.org/data/definitions/22.html

Neilson, K. (2026, June 10). Reply in *Figma MCP shows "Forbidden" in
Automations / Cloud Agents*. Cursor Forum.
https://forum.cursor.com/t/figma-mcp-shows-forbidden-in-automations-cloud-agents/162969

Parecki, A., Hardt, D., & Lodderstedt, T. (2025). *The OAuth 2.1 authorization
framework* (Internet-Draft). Internet Engineering Task Force.
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1

Sakimura, N., Bradley, J., & Agarwal, N. (2015). *Proof Key for Code Exchange
by OAuth public clients* (RFC 7636). RFC Editor.
https://doi.org/10.17487/RFC7636
Loading
Loading