Repository navigation
Conversation
Adds tests/test_public_api_access_checker.py for skills/policyengine-api-access/scripts/check_public_api_access.py, which does not exist yet. Each test writes a small dashboard repository and scans it: - PA1 (error): browser code names api.policyengine.org or one of the Public API's Cloud Run addresses, including hosts built from string parts, in Vite apps, static sites, Pages Router pages and Next.js modules that a client component imports; - server code is not reported: Python backends, scripts, Vercel functions, Next.js route handlers, server components, server actions, server-only modules and middleware, plus tests, comments, build output and the household API and v2 hosts; - PA2 (error): a NEXT_PUBLIC_, VITE_ or REACT_APP_ variable holds a Public API address, the Public API's Auth0 tenant, a token or a client secret, or build config copies a server credential into the bundle; ordinary public variables and server secrets are not reported; - PA3 and PA4 (warnings): deploy config that proxies to the Public API, and browser code that builds a Public API path; - declared exceptions, the command line's exit status, standard-library imports only, the pinned workflow template, the skill's CI section, and the CI step in new dashboards' scaffolds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
skills/policyengine-api-access/scripts/check_public_api_access.py reads a dashboard's repository and fails when browser code calls the Public API: - PA1 (error): browser code names api.policyengine.org or one of the Public API's Cloud Run addresses, also when the host is joined from string parts; - PA2 (error): a NEXT_PUBLIC_, VITE_, REACT_APP_, GATSBY_ or EXPO_PUBLIC_ variable is named for, or set to, a Public API address, its Auth0 tenant, a token or a client secret, or next.config or Vite config reads a client secret; - PA3 and PA4 (warnings): deploy or build config that names the Public API, and browser code that builds a path only the Public API serves. Server code is not reported: top-level backend, server and scripts directories, Vercel functions, Next.js route handlers, middleware, server actions and server-only modules, and Next.js modules that only server components import (an import graph from "use client" modules and Pages Router pages decides). It uses only the standard library and runs in linear time; it follows the cost checker's command line, output and public-api-ok declarations. templates/public-api-checks.yml runs a pinned copy with read-only permissions. The skill's new "Check it in CI" section says how to add it, and the dashboard scaffold and /new-tool add the step to every new dashboard's CI. Existing dashboards adopt it in their own migrations. On 18 PolicyEngine dashboards it reports every browser caller listed in the Public API caller inventory, at the file that calls it, and nothing in the two dashboards whose backends call the Public API or in those that don't call it. Two regression tests cover what that run found: config files with URLs in strings, and a file that starts with many comments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s-check Brings in the rebuilt dashboard manifest, which the when-to-use guide test reads, and the skill's description of the firewall's 429. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #115
Stacked on #116 (
policyengine-api-access), whose skill gains the check's section. Its base is that PR's branch. It does not need #PR_2, and the two merge together without conflicts.Summary
skills/policyengine-api-access/scripts/check_public_api_access.pyfails a dashboard's pull request when browser code calls the Public API (api.policyengine.org) directly. It reads files only, uses only Python's standard library, and follows the cost checker: a pinned copy downloaded in CI, the same command line and output, and declared exceptions.api.policyengine.orgor one of the Public API's Cloud Run addresses (policyengine-api[-staging]-<hash>-<region>.a.run.app, tagged revisions,policyengine-api[-staging]-<number>.<region>.run.app), also when the host is joined from string parts, an array join, or a template with'policyengine.org'or'api'in the same fileNEXT_PUBLIC_*,VITE_*,REACT_APP_*,GATSBY_*orEXPO_PUBLIC_*variable named for a Public API address or credential, or set to the Public API's address, its server Auth0 tenant, a token or a server credential; ornext.configor Vite config that reads a client secretvercel.json,netlify.toml,_redirectsor build config that names the Public API/{country}/economy/{policy}/over/{baseline}or/{country}/calculate-fullBrowser code is every JavaScript, TypeScript, Vue, Svelte, Astro and HTML file except server code: top-level
backend/,server/,scripts/,functions/and similar;api/at the root of a project that is not Next.js; Next.js route handlers,pages/api/,pages/_document, middleware and instrumentation;*.server.*; modules starting with"use server"or importingserver-only. In a Next.js project an import graph decides: a module that a"use client"module or a Pages Router page reaches is browser code; one that only server components reach is server code; one nothing imports counts as browser code. Python, tests, stories, build output and comment-only lines are skipped.Where it lives, and how dashboards run it
In this repository, next to the skill, the same way as
policyengine-cloud-costs/scripts/check_deploy_config.py: the scaffold and/new-toolalready download that checker from a pinned commit (CHECKER_COMMIT) and run it with the runner'spython3. A composite action or a package would add a release process for one file.create-dashboard.ymlbuilds dashboards with the plugin's scaffold agents, so new dashboards get the step through the scaffold.templates/public-api-checks.yml: a workflow that runs the pinned script on pull requests, withcontents: read.targets/claude/agents/dashboard/dashboard-scaffold.mdandtargets/claude/commands/new-tool.md: every new dashboard's CI gets the step, and/new-tool's local checks run it. Adding it to existing dashboards is part of moving each one onto the dashboard API.Environment variables and secrets
The template and the scaffold steps add a workflow step to dashboards; this repository's own workflows are unchanged.
CHECKER_COMMITenvCHECKER_COMMIT_SHAplaceholder)env:→ thecurlURL in the same steptests/test_public_api_access_checker.py::test_workflow_template_runs_a_pinned_copy_with_read_only_permissionsGITHUB_TOKENraw.githubusercontent.comserves this public repository without oneNo secret is read. Not verified: a run of the template on GitHub Actions; the script ran locally only.
Tests
tests/test_public_api_access_checker.pywrites small repositories into a temporary directory and scans them: each PA1 form in a Vite app; Next.js modules reached from a client component, shared with a server component, or imported by nothing; Pages Router pages; HTML, Vue, Svelte and static sites; 22 server, test, comment, build-output and other-host cases that must not be reported; Next.js server code; anapi/directory in a Next.js project; 16 PA2 cases and 10 that must not be reported; PA3 and PA4; declarations with and without a reason; exit status 0, 1 (also with--stricton warnings) and 2; standard-library imports only; the workflow template; the skill's section; and the scaffold steps. Two regression tests came from running it on dashboards:tsconfig.jsonandpackage.jsonwith URLs in strings, and a file that starts with hundreds of comments (an earlier pattern took minutes on policyengine-model).e545f44: 87 failed on their assertions; exit code 1. The two regression tests failed against the first version of the script (one by timeout) before its fix in the green commit.fe46e86: 89 passed; exit code 0.On shallow clones of 18 dashboards' default branches it reported every browser caller among them that the Public API caller inventory lists, at the calling file (aspen-eitc-ctc, autumn-budget-2025-in-review, ccdf-calculator, cliff-watch, keep-your-pay-act, oregon-kicker-refund, policyengine-model, refundable-credit-conversion, state-legislative-tracker, us-state-eitcs-ctcs), and nothing in child-poverty-impact-dashboard and marriage (whose backends call the Public API) or in the six that don't call it. autumn-budget-2025-in-review also reports two lines of UI text that name the address. Each scan took under a second.
🤖 Generated with Claude Code