Skip to content

docs: harden the OpenAPI sync policy against publishing private surfaces - #445

Open
hongyi-chen wants to merge 2 commits into
mainfrom
docs/harden-openapi-sync-policy
Open

docs: harden the OpenAPI sync policy against publishing private surfaces#445
hongyi-chen wants to merge 2 commits into
mainfrom
docs/harden-openapi-sync-policy

Conversation

@hongyi-chen

Copy link
Copy Markdown
Collaborator

Summary

Running sync-openapi-spec in --mode apply today would publish private surfaces into the public API reference at docs.warp.dev/api. This PR fixes the policy so the script can't do that. No spec content changesdevelopers/agent-api-openapi.yaml is untouched.

Found while triaging API findings during a missing_docs drift-watch run.

The problem

The docs repo and warp-server both generate the same published file, but they disagreed on what counts as public.

warp-server's script/generate-public-openapi filters on x-internal: true (public_api/public-openapi-filter.yaml) and publishes through the release-gated sync_public_openapi_to_docs workflow. The docs-side script instead kept a hand-maintained tag allowlist and, per its own docstring, kept x-internal: true operations verbatim.

That allowlist had gone stale. A --mode diff against current warp-server reported 31 paths to add and 20 unclassified ! warnings, including:

  • all 20 /factory/* paths (Oz Factory is unreleased; FactoryMcp is dogfood),
  • /memory_stores (Agent Memory is research preview) — the tag was renamed memory_storesmemory upstream, and only the old name was excluded, so the rename silently reopened the surface,
  • the /agent/messages/* and /agent/events/* orchestration-messaging operations, all explicitly marked x-internal: true upstream.

Changes

.agents/skills/sync-openapi-spec/scripts/sync_openapi.py

  • Honor x-internal: true: strip_internal_operations drops internal operations, and _has_public_operation drops a path whose operations are all internal. This mirrors warp-server's own filter, so a surface the server team marks private stays private here without a matching allowlist entry.
  • Added memory and factory to EXCLUDED_TAGS (keeping memory_stores for the pre-rename name).
  • Added EXCLUDED_PATH_PREFIXES = ("/factory",). A tags-only rule isn't sufficient: some Factory operations are tagged agent upstream (for example GET /factory/scorers/{scorer_id}/results), so they survived the tag filter.

.agents/skills/sync-openapi-spec/references/sync-policy.md

  • Documented the new rules and each new exclusion's rationale.
  • Added a section on the relationship to warp-server's release automation, naming it the authoritative publisher and this skill the manual fallback.
  • Replaced the "what we deliberately KEEP" section, which described the old keep-x-internal behavior.
  • Recommended asking the server team to mark an operation x-internal upstream as the preferred fix, since that hides it from both publishers at once.

Verification

Before, --mode diff reported 31 paths to add and 20 ! unclassified warnings. After:

Paths present in source but missing from target:
  + /agent/artifacts/{artifactUid}/download
  + /agent/run-by-external-reference

No ! warnings remain, and both remaining paths are genuinely public upstream (no x-internal marker).

  • --mode self-test passes.
  • npm run build passes.

Why --mode apply was not run

warp-server's release-gated workflow is the authoritative publisher for developers/agent-api-openapi.yaml; it opens its own PR on automation/sync-agent-api-spec. Hand-applying here would duplicate that pipeline and land a large schema regeneration outside the release gate. The two genuinely-public endpoints above will arrive through that automation. This PR only makes the fallback path safe to use when it is needed.

Conversation: https://staging.warp.dev/conversation/53c4f3f8-39bb-46c1-a5c0-66b467db0439
Run: https://oz.staging.warp.dev/runs/019fb91e-74a0-73f4-ac72-f2d88c32fab5

This PR was generated with Oz.

Co-Authored-By: Oz oz-agent@warp.dev

The docs-side sync script kept a stale tag allowlist and deliberately
retained x-internal operations, so --mode apply would have published
Factory, memory_stores, and the orchestration messaging endpoints.

Honor x-internal (matching warp-server's public-openapi-filter.yaml),
add the renamed memory tag and the factory tag, and exclude the
/factory path prefix since some of its operations are tagged agent.

No change to developers/agent-api-openapi.yaml.

Co-Authored-By: Oz <oz-agent@warp.dev>
@vercel

vercel Bot commented Jul 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 1, 2026 12:00am

Request Review

@cla-bot cla-bot Bot added the cla-signed label Jul 31, 2026
@hongyi-chen hongyi-chen added the documentation Improvements or additions to documentation label Jul 31, 2026 — with Warp Agent Staging
@hongyi-chen
hongyi-chen marked this pull request as ready for review July 31, 2026 23:58
@oz-for-oss

oz-for-oss Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@hongyi-chen

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@advait-m advait-m left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oz-for-oss oz-for-oss Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR updates the OpenAPI sync policy and script to strip x-internal operations and exclude newly private tags/path prefixes from the generated public API spec.

Concerns

  • The tag exclusion logic still only drops a path when all operation tags are excluded. A mixed path can retain an operation tagged with an excluded private surface if it is not also marked x-internal and does not match /factory, which conflicts with the stated belt-and-braces policy.

Security

  • The filtering gap can publish a private tagged operation in the public API reference when it shares a path item with a public operation.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

if path.startswith(EXCLUDED_PATH_PREFIXES):
return False
tags = _path_tags(path_item)
if tags and tags.issubset(EXCLUDED_TAGS):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] This only drops a path when all operation tags are excluded; if a path mixes a public operation with a memory/factory operation that is not x-internal, the excluded-tag operation is kept because strip_internal_operations() only removes x-internal. Strip excluded-tag operations too, or reject mixed paths before publishing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants