Runcastle

Security model

Honest framing first: a workflow is arbitrary code and prompts that a stranger will run against their repository with their API keys, with agents running with permissions skipped inside a container. Our job is not to make that safe — it can't be, fully — but to make everything inspectable, tamper-evident, and free of surprises.

No execution on install

runcastle add writes files and prints text. It never runs package code, never installs dependencies, and never touches your .env. Any future feature that executes anything will be a separate, explicit command — installation itself stays inert.

Immutability & tamper evidence

Every version pins a git commit SHA, and the registry stores SHA-256 checksums for every file, computed at publish time. The CLI verifies checksums on every download, regardless of whether files come from the author's repository or the registry's cache. A force-pushed or edited repository cannot silently change what installers receive: either the pinned SHA still resolves and checksums match, or the install falls back to the registry's cached copy — which still must match the publish-time checksums.

Static analyzability

The rendering on this site is only trustworthy if what you read is what runs. To keep that true, the entrypoint is constrained:

  • Imports are restricted to an allowlist — no arbitrary modules.
  • Lifecycle hooks must be object literals with string-literal commands — a hook that builds its command dynamically cannot be reviewed, so it cannot be published.

Violations block publish; they are never warnings.

Disclosure parity

Anything with side-effect potential must appear twice: declared in the manifest's disclosures, and detected in the code. Host hooks, sandbox hooks, network access, and !`command` shell expansion in prompt files are all rendered prominently on the site and in the CLI preview — never hidden behind a click. A mismatch between declared and detected behavior blocks publish.

Secret hygiene

  • Publish-time secret scanning: anything resembling a real credential in package files blocks publish.
  • The registry never stores or receives user API keys — env vars are declared by name only, and the CLI never touches your .env.
  • Authentication is GitHub OAuth with minimal scopes — enough to identify you and verify repository ownership, nothing more.

Inert rendering

All package content is treated as hostile input everywhere it is rendered. Prompt files and READMEs are displayed as inert text: markdown is sanitized with a strict schema, HTML is never injected raw, and javascript: URLs are not auto-linked. Topology labels are escaped and truncated in the diagram, cards, and OG images.

Moderation

Every workflow page has a report link. A report creates a moderation case for the maintainers, who can:

  • Unlist — hide the workflow from browse and search. Existing pinned installs keep working via cached files.
  • Block — add the pinned SHA to a denylist. File endpoints return 410 Gone for new installs; this is the kill switch for malicious content.

Rate limits & web hygiene

All API mutations are CSRF-safe and rate-limited (60 requests/minute anonymous, 300 authenticated, per IP). Dependencies are audited in CI.

Responsible disclosure

Found a vulnerability in Runcastle itself? Please report it privately via the contact on the policy page rather than opening a public issue.