Skip to content

add: SRO (Security Research Orchestrator) to plugins - #793

Open
DakshGajjar wants to merge 1 commit into
awesome-opencode:mainfrom
DakshGajjar:add-opencode-sro
Open

DakshGajjar wants to merge 1 commit into
awesome-opencode:mainfrom
DakshGajjar:add-opencode-sro

Conversation

@DakshGajjar

@DakshGajjar DakshGajjar commented Oct 1, 2026 •

Copy link
Copy Markdown

Submission Type

  • Plugin
  • Project
  • Theme
  • Agent
  • Resource

Details

Name: SRO (Security Research Orchestrator)
Repository: https://github.com/dakshgajjar/opencode-sro
Tagline: Security research harness that reads bounty engagements and enforces scope in code, not in a prompt

Checklist

  • Relevant to OpenCode
  • Repository is public and accessible
  • Actively maintained
  • Not a duplicate
  • YAML file in correct folder (data/plugins/)
  • Filename is kebab-case

Why

An LLM is good at reasoning about security and bad at deciding what it is allowed to touch, so SRO takes the second job. It reads Bugcrowd/HackerOne/Intigriti engagements with no credentials, stages the extracted scope for explicit human confirmation, and then refuses any action the engagement does not authorize.

What ships:

  • Deterministic scope engine — IN_SCOPE / OUT_OF_SCOPE / UNKNOWN. UNKNOWN is blocked and cannot be configured to allow. Exclusions always beat inclusions.
  • Policy engine — a fixed ladder returning ALLOW / DENY / ASK, with per-host rate limits.
  • Tool broker — a closed catalog of 14 declared tools, 6 implemented. No shell access. The one network tool is dns_resolve, and it cannot connect to anything; everything that would reach a third party's system is declared, refused, and says why.
  • Read-only connectors — the transport has no method that accepts an HTTP verb, and a test walks the package and fails if a write-shaped name or a vendor SDK appears.
  • Evidence store — OBSERVED / HYPOTHESIS / VERIFIED enforced structurally. A hypothesis can never become a finding without cited observed evidence.
  • Untrusted-content handling — program briefs are data; an injection test suite asserts they cannot change scope, policy or model routing.
  • Local-first routing — sensitive material routes local, external inference off by default.
  • Egress transport — one reviewed component holds every network control, so a handler cannot become a second implementation of it.

10 agents, 16 commands, 6 instruction files, 726 tests. Standard library only at runtime — no Python dependencies.

Note on the Python dependency

The plugin is a thin bridge; the authorization boundary is a Python package that ships with it (requires Python 3.11+). That is deliberate — a scope or policy decision needs to be a language with real tests, not a prompt a model can be talked out of. The same reason platform readers import no vendor SDK: an SDK would import its write surface with it.

Try it without a real program

npx opencode-sro example > brief.json
opencode

<!-- sro:release -->
## 1.0.0

The first release where the control plane, the documentation and the code agree
with each other.

**What works now:** 6 of 14 catalog tools, five local and read-only plus
`dns_resolve`. The other eight are declared with `implemented: false` and return a
refusal naming the tools that do work. `sro_capabilities` reports which is which,
so the catalog is not a promise list.

`dns_resolve` is the only tool that touches a network. It resolves names and
classifies every address they return — `public`, `private`, `loopback`,
`link-local`, `metadata` — so a hostname that resolves inward shows up as a
result rather than a silent nothing. It cannot connect to anything.

**The egress layer** (`sro/core/egress.py`) is the only component allowed to open
a socket. A handler receives a session already bound to an approved target and
cannot name a different one. It resolves once, refuses private and metadata
ranges, and connects to the pinned address — so the window between "we decided
this was allowed" and "we connected" does not exist. Limits are frozen and
`send()` takes no overrides. Response bodies pass through the same untrusted fence
as program text, with the target named as provenance, because a response body is
attacker-controlled text arriving in a context trusted to follow instructions.

**Documentation that cannot drift.** `METHOD.md` and `docs/EGRESS.md` ship with
the package and are checked against the implementation by the test suite: every
tool named in the method must be implemented rather than merely declared, every
network tool must have a verdict in the review, and "nothing is approved" is
asserted so the suite fails the day a second network tool ships.

**A scope bypass was found and fixed on the way.** `target=api.acme.test` with
`url=https://admin.acme.test/secret` returned `ALLOW`: the policy ladder resolved
the supplied target and ignored the URL, which is what would actually have been
fetched. It was invisible while every network tool was unimplemented and would
have gone live with the first one.

**Shipped surface:** 10 agents, 16 commands, 6 instruction files, 726 tests.
Standard library only at runtime — no Python dependencies, and one npm dependency
that is the plugin SDK.

@DakshGajjar
DakshGajjar marked this pull request as draft October 1, 2026 02:36
@DakshGajjar
DakshGajjar marked this pull request as ready for review October 1, 2026 02:41
@DakshGajjar
DakshGajjar marked this pull request as draft October 1, 2026 04:52
@DakshGajjar
DakshGajjar marked this pull request as ready for review October 1, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant