Platform Roadmap: RBA Fleet
This page is the standing plan for evolving RBA Skills from a Claude Code plugin catalog into a governed internal AI agent platform — RBA Fleet — that can scale to a 500+ person organization.
It exists so the whole company can see where the platform is going, why it’s shaped the way it is, and what is being built next. It is grounded in fact-checked research into how Stripe, Uber, Microsoft, and the open-source ecosystem actually build and distribute internal AI tooling (sources at the bottom).
The naming
Section titled “The naming”We use plain infrastructure vocabulary so the platform is easy to adopt across the org — one brand name, standard terms for every component.
| Term | What it means |
|---|---|
| RBA Fleet | The overall agent platform (all three layers below) |
| Runner | A single autonomous agent that does one job |
| the Fleet | The Runners collectively |
| Gateway | The one server every Runner goes through to reach internal systems |
| Registry | The source-of-truth list of every Runner (declared as code in this repo) |
| Sandbox | The isolated environment a Runner executes in |
RBA Skills stays the name of the catalog itself. RBA Fleet is the runtime built on
top of it.
What we’re actually building
Section titled “What we’re actually building”A real agent platform is three layers stacked. Most internal “AI catalog” efforts only build the first. To reach a true agent fleet we build all three, with a single governance spine running through them.
| Layer | What it is | Who exemplifies it | RBA today |
|---|---|---|---|
| 1 — Catalog (distribution & discovery) | Where people find and install tooling | Claude Code marketplaces; SkillHub registry | ✅ Strong — this repo |
| 2 — Gateway | One central MCP server connecting agents to internal systems; tools authored once, auto-discoverable | Stripe Toolshed; Uber MCP Gateway | ⚠️ Seed only (rba-hub-mcp) |
| 3 — Fleet (execution) | Sandboxed Runners that actually do the work | Stripe Minions; Uber Agent Mesh | ❌ Not yet |
THIS REPO (control plane — declarative, git, CI-gated) ┌──────────────────────────────────────────────────────────────────────┐ │ plugins/ skills · agents · mcp · hooks · commands · resources │ │ runners/ ← Runner declarations (the Registry) │ │ rba-meta.json governance: owners · maturity · securityReview │ │ validator runtime-least-privilege · ownership · review gate │ │ generates → marketplace.json (clients) · api/_catalog.json · _runners │ └──────────────┬──────────────────────────────────┬──────────────────────┘ │ installs (Claude Code) │ reads Registry ▼ ▼ Layer 1: CATALOG Layer 2: GATEWAY Layer 3: FLEET Claude Code clients one MCP server Claude Agent SDK extraKnownMarketplaces seed = rba-hub-mcp sandboxed Runners enabledPlugins (force-on) scoped tokens + tiering no prod / no egress strictKnownMarketplaces UNIFIED AUDIT LOG ◄──────────┤ exec logs (managed-settings lockdown) policy enforcement point small default toolset ▲ │ └──── all tool calls ───────┘ (single chokepoint)The organizing principle
Section titled “The organizing principle”This repo stays the declarative control plane; the Gateway and the Fleet are runtime services that live outside it. RBA Skills is already what every case study calls the “source-of-truth registry” — git-backed, PR-reviewed, validator-gated, with audit-via-git-history. We lean into that: the repo declares and governs tools and Runners; separate services run them.
This matches the evidence. No large org runs marketplace.json as its production
backbone — Stripe and Uber treat the Claude/coding-agent client as one surface and
build a bespoke gateway underneath. Our design does the same: marketplace.json is
the client distribution surface; the Gateway is the integration backbone; the
runners/ directory is the Registry.
Layer 1 — Catalog hardening (in this repo)
Section titled “Layer 1 — Catalog hardening (in this repo)”These are additive changes to the existing six-layer pipeline (bundle → loader → schema → pages → validator → submission bot). None break the existing catalog.
Governance metadata — live now
Section titled “Governance metadata — live now”Three fields were added to rba-meta.json (and standalone artifact frontmatter),
defined in src/content.config.ts and enforced by scripts/validate-bundles.mjs:
{ "owners": [{ "team": "platform", "github": "rba-platform" }], "maturity": "experimental", // experimental | stable | deprecated "securityReview": { "status": "none" } // none | requested | passed | failed}owners— who is accountable. Drives a generatedCODEOWNERSand the two-tier review model. Currently a validator warning on every plugin; flips to an error after a one-quarter migration window.maturity— release lifecycle, replacing the “no deprecation path” gap.securityReview— the catalog-level security gate.maturity: stablerequiressecurityReview.status: "passed"— a hard validator error. This is the first line of defense against the uncurated-skill problem (see Governance below).
The validator also now enforces valid semver on plugin.json versions, so
installs stay resolvable as the catalog grows.
Still to do in Layer 1
Section titled “Still to do in Layer 1”- Turn on push distribution. Configure
extraKnownMarketplaces(auto-prompt install when an employee trusts the repo folder) and a curatedenabledPluginsbaseline (force-on the primitives:research,rba-crew,onboarding,rba-hub-mcp). Lock allowed sources withstrictKnownMarketplacesin managed settings (deployed via MDM — un-overridable by users, by design). - Generate
CODEOWNERSfrom theownersfield. externalSourceescape hatch. Add an optionalrba-meta.json.externalSource(a git URL) so a heavy plugin can graduate to its own repo without changing the catalog contract. Solves “single repo / clone-everything” before it hurts — ship the hook now, use it later.- Run the loader in CI. Today a malformed bundle is silently skipped rather than failing the build. Once Runner declarations are safety-critical, that silence is a governance hole — the validator must hard-fail instead.
Layer 2 — The Gateway
Section titled “Layer 2 — The Gateway”A single internal MCP server that is the only path from any Runner to any internal
system. rba-hub-mcp is the seed — today it exposes the catalog read-only; it
gets generalized into the tool-proxy and policy plane. Lives in a new service repo
(e.g. rba-gateway), not here.
| Responsibility | Approach | Pattern source |
|---|---|---|
| Tool registry | Tools authored once, self-describing, auto-discoverable to all Runners | Stripe Toolshed (~500 tools) |
| Auto-generation | If RBA services expose OpenAPI specs, generate MCP tools from them | Uber IDL crawl (10,000+ services) |
| Identity & tokens | Integrate RBA’s IdP (Entra) → mint short-lived, audience-scoped, single-hop tokens per call | Uber STS (via OIDC, not SPIFFE) |
| Tiered gating | First-party tools auto-approved; third-party gated harder | Uber tiering |
| Write protection | Block mutable endpoints by default; rate-limit writes; explicit scope to mutate | Uber guardrails |
| Unified audit log | Every tool call → one append-only sink | The thing a gateway-free design can’t give |
The catalog and Gateway connect via a published tools-catalog.json (committed or
cached) that this repo’s site renders read-only. The Gateway owns tool source; the
repo never duplicates it.
Layer 3 — The Fleet
Section titled “Layer 3 — The Fleet”The Runners themselves, built on the Claude Agent SDK — not a fork of an existing
agent (Stripe forked goose in 2024 because the SDK didn’t exist yet; today the SDK
is the substrate). Runs in a new service repo (e.g. rba-runner).
The Registry lives in THIS repo as a new runners/ artifact type — declarative,
PR-reviewed, validator-gated. This is the “mandatory registry that kills shadow
agents.” It’s live now — see the Runners reference for the
declaration shape and the governance rules the validator enforces (owners and
sandboxProfile required; write-scoped Runners gated on a passed security review).
// runners/<slug>/runner.json{ "name": "release-notes-drafter", "description": "...", "owners": [{ "team": "platform" }], // required "trigger": "manual | schedule | webhook", "model": "claude-opus-4-8", "skills": ["research", "document-templates"], // refs to catalog artifacts "allowedTools": ["gateway:jira.read", "gateway:git.*"], // SCOPED Gateway tools "sandboxProfile": "qa-no-egress", "maturity": "experimental", "securityReview": { "status": "none" }}Runtime model: each Runner executes in a Sandbox — no production credentials, no network egress except through the Gateway. That isolation is what lets a Runner run without per-action permission prompts (Stripe’s key insight). The Runner gets a scoped token from the Gateway, a small default toolset, and orchestration that interleaves LLM loops with deterministic steps (git, lint, test).
Governance — closing the security gap
Section titled “Governance — closing the security gap”A Snyk audit of ~3,984 publicly published agent skills found ~37% had a security flaw and 36% contained prompt injection, because the open marketplace had no signing, no review, and no sandbox — and skills run with the agent’s full permissions. RBA Fleet closes that gap with defense in depth, four layers:
- Authoring-time (live) — the validator rejects bare
Bash, wildcardWebFetch, and credential-path access. - Declaration-time (live for catalog; planned for
runners/) — scopedallowedToolsand thesecurityReviewpromotion gate. - Runtime scope (Gateway) — tokens grant only declared scopes; writes are gated and rate-limited.
- Isolation (Sandbox) — no production access, no egress except via the Gateway.
RBAC and two-tier review (the SkillHub model, implemented with GitHub primitives):
owners[] generates CODEOWNERS so a team approves changes within its namespace;
promotion to org-wide (enabledPlugins, maturity: stable, or any write-scoped
Runner) requires a platform-admins review enforced by branch protection.
Audit & telemetry: git history (declarations) + Gateway log (tool calls) + Runner log (executions), unified at the Gateway sink — and surfaced back as catalog dashboards (the “how many Runners ran this week?” answer).
Sequencing — all three in scope, one hard dependency
Section titled “Sequencing — all three in scope, one hard dependency”All three layers are in scope from the start. The only real constraint is that the Fleet can’t run safely before the Gateway exists (it needs scoped tokens and the audit sink).
| Workstream | Can start | Hard dependency | Delivers |
|---|---|---|---|
| A — Control plane (this repo) | ✅ Started | none | Governance fields, versioning, ownership, review gate, runners/ Registry, push-distribution config |
B — Gateway (rba-gateway) | Now, parallel | IdP integration | Tool proxy, scoped tokens, tiering, audit sink |
C — Fleet (rba-runner) | Scaffold now | Gateway (B) for live use | Sandboxed Agent-SDK execution of runners/ declarations |
Critical path: B’s token + audit milestone gates C’s production use. A ships continuously and independently.
- Runners are the top risk — autonomous and tooled. Mitigation: mandatory
security review before any write-scoped Runner reaches
stable; Sandbox is required. - Static-site coupling to a live Gateway. Mitigation: the Gateway publishes a
committed/cached
tools-catalog.json; the build never blocks on a live service. - Silent loader skip becomes a governance hole once Runner declarations matter. Mitigation: run the loader in CI and hard-fail.
- Identity over-engineering. SPIFFE/SPIRE is for service-mesh scale RBA likely doesn’t have. Mitigation: OIDC scoped tokens via the existing IdP.
- Single-repo clone-everything at 500+. Mitigation: the
externalSourcehook lets heavy plugins graduate to their own repos with no contract change.
Deliberately not doing
Section titled “Deliberately not doing”- Not forking an agent framework — the Agent SDK, not
goose. - Not putting Gateway tools in
plugins/— the Gateway owns its registry; the repo mirrors it read-only. - Not building SPIFFE/SPIRE — OIDC scoped tokens suffice at this scale.
- Not auto-generating tools from service specs on day one — hand-author first.
- Not sharding the repo now — ship the
externalSourcehook, defer the split until clone time is a measured problem. - Not reusing the existing
agents/artifact for Runners — Claude Code subagent definitions and autonomous Runners are semantically different. - Not adopting hosted Managed Agents wholesale for governed Runners — the ZDR/BAA gate and the customer-owned identity/audit requirement keep execution self-hosted for sensitive tiers. See Execution & hosting.
Sources
Section titled “Sources”Fact-checked research underpinning this plan:
- Stripe — Minions, Part 1 · Part 2
- Uber — Solving the Agent Identity Crisis
- Anthropic — Claude Code plugin marketplaces · Managed Agents overview · Self-hosted sandboxes · Agent SDK hosting
- Microsoft — Cloud Adoption Framework: AI agent governance
- AWS — Bedrock AgentCore
- SkillHub — open-source enterprise skill registry
- Snyk — ToxicSkills / ClawHub audit