Skip to content

📖 Add Hive (Hive Commons) security self-assessment - #2286

Open
clubanderson wants to merge 2 commits into
cncf:mainfrom
clubanderson:docs/hive-security-self-assessment
Open

clubanderson wants to merge 2 commits into
cncf:mainfrom
clubanderson:docs/hive-security-self-assessment

Conversation

@clubanderson

@clubanderson clubanderson commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the CNCF TAG-Security self-assessment for Hive under projects/hive-commons/security-assessment/.

Updated 2026-09-09 — new home. This PR originally filed the assessment under projects/kubestellar/sub-projects/hive/. Hive has since been transferred out of the KubeStellar org into its own vendor-neutral org, hivecommons (2026-09-03, full history preserved; old URLs redirect), and is applying to Sandbox as an independent project rather than as a KubeStellar subproject. The file has been moved to projects/hive-commons/security-assessment/self-assessment.md and all kubestellar/hive references rewritten accordingly. KubeStellar consensus for the separation was recorded and closed in kubestellar/kubestellar#3986.

KubeStellar is still named in the document where it remains factually correct — as Hive's origin and as its first production adopter — but it is no longer described as Hive's host org.

Updated 2026-10-01 — ioscan defaults resynced. The mirrored self-assessment now matches hivecommons/hive#7095: ioscan.canaries defaults on unless opted out, and ioscan.fail_mode defaults to closed at ACMM L5/L6 while staying open at L1–L4.

Updated 2026-10-02 — v5 links and heartbeat verification. Evidence links now point at maintained v5, and the hub→spoke heartbeat rows reflect #7082 as closed with signed responses verified log-only by default and enforced only with HIVE_HEARTBEAT_VERIFY=enforce.

What Hive is, and why the threat model is unusual

Hive orchestrates fleets of AI coding agents that autonomously maintain software projects — filing issues, opening pull requests, reviewing, and at high autonomy levels merging. Agents run as CLI subprocesses under tmux, in containers or pods, holding GitHub App or PAT credentials.

That means the system runs model output with credentials that can write to source repositories, so the assessment focuses on the boundaries that contain that rather than on a conventional network/data perimeter.

Covered:

  • ACMM autonomy levels (L1–L6) and the agent mode ladder — the primary risk gate. Write and merge capability is earned by level; low-level agents can only advise.
  • ioscan — prompt-injection scanning of untrusted input on the kick path, with canary support
  • MITM proxy — network egress enforcement (ADR-0002)
  • GitHub App credential handling — JWT→installation token, per-cluster private keys at 0600, distinct from the OAuth/OIDC login path
  • Append-only audit log — the attribution substrate, with rotation and a gzip-bomb read cap
  • Private vulnerability reporting via GitHub Security Advisories

Weaknesses are stated, not omitted

A self-assessment that claims everything is fine is not useful to a reviewer, so the document names its own gaps. The three most significant:

  1. ioscan.fail_mode is level-aware. It defaults to open at ACMM L1–L4, where Critical findings are redacted and the kick continues, and to closed at ACMM L5/L6 via the shipped level packs, where Critical findings block the kick unless an operator explicitly overrides the mode.
  2. Agents share a container rather than being sandboxed per run, separated by UID rather than process/kernel containment, and can hold live write credentials in-session. Tracked upstream as hivecommons/hive#2804.
  3. Single-maintainer security response capacity, with CODEOWNERS present but not enforced by branch protection — a consequence of the project's own automation merging green PRs. This is the largest institutional risk identified.

It also records plainly that no third-party security audit or penetration test has been performed, and that SBOM/provenance attestations are currently disabled on image builds (with the reason, which is a real container-runtime exec failure rather than an oversight).

Notes for reviewers

  • Relative links in the source document have been rewritten to absolute Hive URLs so they resolve from this repository. All 11 were verified to return 200 against hivecommons/hive@v5 after the org move; one pre-existing broken path (docs/landscape.md → src/docs/landscape.md) is fixed here.
  • The canonical copy lives in the Hive repo; the document says so, so corrections land in one place.
  • Scope is Hive only — not KubeStellar Core, and not Console.
  • If the TOC would prefer a different directory name than hive-commons (for example hive, or holding the file until the Sandbox application is decided), say the word and I will move it.

References

@clubanderson
clubanderson requested a review from a team as a code owner August 27, 2026 16:12

@JustinCappos JustinCappos 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.

This needs some work to deal with parts the LLM didn't have the data for. There is also some low-hanging fruit the project could do to improve security.

@clubanderson
clubanderson requested a review from a team as a code owner September 9, 2026 15:56
@clubanderson clubanderson changed the title 📖 Add KubeStellar Hive security self-assessment 📖 Add Hive (Hive Commons) security self-assessment Sep 9, 2026
@JustinCappos

Copy link
Copy Markdown
Contributor

@clubanderson and others from the team. please let me know when you've addressed the prior comments and we can provide another review.

clubanderson pushed a commit to clubanderson/toc that referenced this pull request Sep 11, 2026
Revision 2 in response to the seven review comments on cncf#2286.

- Add a deployer-facing threat section: the attack path from a stranger's
  issue to a repository write, what stands in the way of each concern and
  what does not, the three settings that determine exposure, and the worst
  realistic outcome at L6.
- State plainly that ioscan has never been red-teamed and has no measured
  detection rate; recharacterize it as a partial mitigation and credit
  containment to the network deny rules instead.
- Re-scope log scrubbing as log hygiene rather than an exfiltration control,
  and answer the base64 question directly. Running that question against the
  canary path surfaced a real defect: the egress check is substring-only, so
  an encoded canary is not detected, while the input path does decode base64.
- Replace the false "Case studies: not applicable" claim with the seven
  adopters in ADOPTERS.md, three in production, one at ACMM L5/L6 across 43
  repositories.
- Record that the maintainer roster grew from one to three across three
  affiliations and that a security response process now exists; restate the
  remaining risk as unenforced code ownership rather than bus factor.
- Correct the SBOM explanation: #3760 is a container-runtime exec defect
  caused by attestations forcing an OCI index, not an SBOM deprioritization.
- Delete the open-questions section and answer every item against the
  repository, including two answers that are "no".
- Commit to the OpenSSF Best Practices badge.

Tracking issues filed: hivecommons/hive#6684, #6685, #6686, #6687, #6688.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <clubanderson@gmail.com>
@clubanderson

Copy link
Copy Markdown
Contributor Author

@JustinCappos — all seven comments are addressed and replied to individually. Ready for another review.

Short version of what changed, and one thing you should see first.

Your base64 question found a real bug. You asked, about secret redaction, "what if I prompt inject something in which has you emit these in a base 64 encoded format or similar?" Running that against the control that's actually supposed to catch exfiltration — ioscan canaries — exposed an asymmetry nobody had noticed. The input path decodes base64 and normalizes Unicode before scanning. The egress path is a bare strings.Contains. So an agent induced to emit its canary base64-encoded passes the proxy check unflagged, which is precisely the attack canaries exist to detect. Filed as hivecommons/hive#6686. That's a defect located from a one-sentence hypothetical against a codebase you don't know, and it's the most useful comment in the review.

The rest:

Your comment What changed
"If I deploy this, what should I worry about?" New section stating the attack path plainly — including that no step necessarily has a human read the attacker's text first — with a concern → what-stops-it → what-does-not table, the three settings that determine exposure, and the worst realistic outcome at L6.
"Have you red teamed?" No. Nothing in the repo establishes a detection rate. ioscan is now described as an unmeasured partial mitigation, with containment credited to the proxy hard-deny of POST /pulls and PUT /pulls/{n}/merge — which holds whether or not injection succeeds. Evaluation tracked in #6685.
"Is this to prevent a model leaking them?" Log scrubbing re-scoped as hygiene for Hive's own logs and explicitly not an exfiltration control. Plus the bug above.
"At least get a passing badge." Agreed — #6684. Most passing criteria already met; outstanding work is registration, not engineering.
"This is a huge risk. Why not mitigate it?" Half of it was mitigated three days before your review and our document was stale: OWNERS went from one maintainer to three across three affiliations on 2026-08-28, with security-response.md landing the same day. The other half is real and unmitigated — live v4 branch protection requires no PR reviews at all, so a change to the proxy deny-rule table can merge on green CI with no human security reviewer. Scoped enforcement tracked in #6687.
"Looks like AI generated this." It had, and the claim was false: "Case studies: not applicable" is contradicted by ADOPTERS.md — seven adopters, three in production, one running ACMM L5/L6 across 43 repositories. Replaced with the real table.
"Go through the open questions." Section deleted; every item answered against the repository. Two answers are "no" — no external comms channel (by design), and no adversarial testing has ever been performed.

Five issues filed: #6684 badge · #6685 red team · #6686 canary bug · #6687 code-owner enforcement · #6688 out-of-band SBOM.

The canonical copy is updated in lockstep at hivecommons/hive#6692. All 37 external links verified 200, all internal anchors resolve.

The document is meaningfully less confident than it was, which I think is the correct direction. Thanks for the review — it was substantive, and it improved the software and not just the document.

clubanderson added a commit to hivecommons/hive that referenced this pull request Sep 11, 2026
* Revise security self-assessment after TAG-Security review

Mirrors the revision made for cncf/toc#2286 into the canonical copy.

Seven review comments asked for the parts the first draft hedged on:

- New deployer-facing section: the path from a stranger's issue to a
  repository write, what stands in the way of each concern and what does
  not, the three settings that determine exposure, and the worst realistic
  outcome at L6.
- ioscan efficacy is now stated as unmeasured. No red-team exercise exists,
  so it is described as a partial mitigation, with containment credited to
  the proxy deny rules rather than to the scanner.
- Log scrubbing re-scoped as hygiene for Hive's own logs, explicitly not an
  exfiltration control. Answering the reviewer's base64 question against the
  canary path surfaced a real defect, filed as #6686: the egress check is a
  substring test while the input path decodes base64.
- "Case studies: not applicable" was wrong. ADOPTERS.md lists seven
  adopters, three in production, one at ACMM L5/L6 across 43 repositories.
- Records the roster growth from one maintainer to three across three
  affiliations, and security-response.md; restates the remaining risk as
  unenforced code ownership rather than bus factor.
- Corrects the SBOM explanation: #3760 is a container-runtime exec defect
  caused by attestations forcing an OCI index, not an SBOM decision.
- Open-questions section replaced with answers, including two that are "no".

Tracking issues: #6684, #6685, #6686, #6687, #6688.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <clubanderson@gmail.com>

* Fix changelog fragment: must start with a '- ' entry bullet

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <clubanderson@gmail.com>

---------

Signed-off-by: Andy Anderson <clubanderson@gmail.com>
Co-authored-by: Andy Anderson <clubanderson@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@clubanderson

Copy link
Copy Markdown
Contributor Author

Pushed a correction to this self-assessment: the OpenSSF Best Practices badge status was wrong in this document, in the direction of understating the project.

The document said the badge was "not yet held, and now being pursued." It has in fact been held at the passing level since 2026-08-27 — project 14261, 100% of the passing criteria, never lapsed — which is four days before the review that asked for it. README.md in the project repository had been displaying the badge the whole time.

@JustinCappos — this is the correction to my reply on your badge comment; you asked for a passing badge and we already had one, so answering "we'll get it" was wrong. Separately corrected there.

What was actually outstanding turned out to be the badge entry, not the badge. Hive moved out of the kubestellar org to the vendor-neutral hivecommons org on 2026-09-03, and 67 of the entry's criteria justifications — 70 URLs — still pointed at github.com/kubestellar/hive and hive.kubestellar.io. For a self-certified badge the per-criterion justifications are the entire evidentiary value, so every link a reviewer might follow to check a claim landed on the old home. All 70 now resolve to the current repository and site; the entry re-verifies at passing / 100% with zero fields referencing the old org.

Root cause, since it is the same defect you flagged elsewhere in this review. This document was being written from itself rather than re-derived from observable state. That is what produced the stale maintainer count, and it produced this too — the CNCF Sandbox application (cncf/sandbox#516) has stated "OpenSSF Best Practices passing badge at 100%" correctly since filing, so the accurate fact was already written down in a sibling document. The badge status in this file is now taken from the programme's public API, and the section records both prior errors rather than quietly overwriting them.

Consistency pass. Correcting the one section left three other passages contradicting it, including the response table at the top of this document. Those are fixed in hivecommons/hive#6715, and this file has been regenerated from the canonical copy so the two agree exactly.

Affiliation is consistent across all three places: Hive is an independent project in the hivecommons org, transferred out of the KubeStellar org on 2026-09-03, with KubeStellar recorded as its incubating parent and first production adopter.

clubanderson pushed a commit to hivecommons/hive that referenced this pull request Sep 11, 2026
CNCF TAG-Security asked, on the ioscan section of the self-assessment
(cncf/toc#2286): "have you red teamed to know how well this works? Is
this perfect defense, works decently well, a partial mitigation, etc.?"

The honest answer was no. pkg/ioscan has 56 unit tests, but they assert
that KNOWN shapes are caught — by construction every one passes, and they
cannot produce a detection rate. The self-assessment recorded efficacy as
"unmeasured" and committed to measuring it.

Measured now, against 43 adversarial payloads through the production
entry point (ioscan.ScanInput, shipped defaults):

  blocked (withheld from the agent)     16   37%
  detected but injected anyway           8   19%
  missed entirely                       19   44%
  ------------------------------------------------
  reached the agent verbatim            27   63%

Per family, detection is very uneven: unicode 6/8 blocked, smuggling 4/7,
direct-override 2/10, split-payload 0/4. Plus 2 of 6 benign controls were
redacted — including an issue *reporting* a prompt-injection bug.

Three findings worth more than the headline number:

  - The middle bucket is not obvious. blockedInput requires Critical, or
    Injection at High+, so every Medium finding is recorded for audit and
    the raw text is still injected. "ioscan findings" is not "attacks
    stopped", and nothing said so before.
  - Split payloads score 0% structurally, not for want of a rule. Each
    untrusted segment is scanned separately, so a phrase split across two
    comments is never a single string to match.
  - Two single characters (U+FF29 fullwidth I, U+00AD soft hyphen) defeat
    the STRONGEST family outright. Filed as #6708; the U08 fix is verified
    to be a one-character addition to isInvisibleControl.

Item 3 of the issue — does the network layer still contain what gets
through — is measured rather than claimed:
TestRedTeamContainmentHoldsForEveryMode checks POST /pulls and
PUT /pulls/{n}/merge against all four ACMM modes on every run. That is
the real finding: the injection defense of record is the proxy deny rule,
not the text scanner.

The corpus is a RATCHET, not a snapshot. TestRedTeamCorpusOutcomesAreStable
pins each observed outcome and fails in BOTH directions — a regression,
and equally an improvement, because an improvement makes the published
miss rate wrong. Both branches were verified by deliberately breaking and
deliberately improving a rule; the improvement path prints "re-run the
report and republish". So the document's numbers cannot silently drift
from the code.

Not measured, and said so in the document rather than estimated: the
optional LLM classifier (default-off, and fails open, so the
deterministic floor here is the worst case either way), the output path,
and the canary egress path (#6686).

Fixes #6685

Signed-off-by: Danathar <Danathar@users.noreply.github.com>
@clubanderson

Copy link
Copy Markdown
Contributor Author

Follow-up correction to my earlier note in this thread — two numbers I cited there have since been superseded, and the mirror is now re-synced from canonical (7ea636a).

1. The red-team figures moved, because the gaps they measured were closed.

My earlier comment quoted the evaluation's original result. Since then hivecommons/hive#6714 closed the two Unicode gaps that evaluation found — U+FF29 FULLWIDTH LATIN CAPITAL I was missing from the confusable fold table, and U+00AD SOFT HYPHEN was not treated as an invisible control. Each defeated the entire Unicode family with a single character.

metric as first published now
attack payloads withheld from the agent 16 (37%) 18 (42%)
reached the agent verbatim 27 (63%) 25 (58%)
missed (no rule fired) 19 (44%) 17 (40%)
detected but not blocked 8 (19%) 8 (19%)
Unicode steganography family 6/8 blocked 8/8

The overall characterisation is unchanged and deliberately so: this is still a partial mitigation, and a narrow one. 58% of attack payloads still reach the agent verbatim, paraphrased instruction override is still 2/10, and split payloads are still 0/4 — structurally, because each untrusted segment is scanned separately. What bounds the consequence of a successful injection is not ioscan; it is the proxy's hard deny of POST /pulls and PUT /pulls/{n}/merge.

2. The canary egress weakness recorded here has been fixed.

Revision 2 recorded, as a known weakness, that the canary egress check matched literal substrings only — so a base64-encoded canary passed unflagged (#6686). That is now closed: CanaryRegistry.Scan decodes and normalizes before matching. The residual limitation is stated rather than dropped — the transform list is finite and enumerated, so an encoding it does not model still passes, and git-receive-pack bodies remain opaque.

3. Why there were stale numbers to correct at all.

Worth stating plainly, since this is the same class of problem @JustinCappos flagged originally with the stale maintainer count. The regression test that publishes these outcomes fails when a result changes in either direction, including improvements, precisely so an improvement cannot silently invalidate a published figure. It worked — but the republish updated the results table and the machine-readable outcomes while leaving the prose that summarised them untouched, so the document contradicted itself within three lines of the corrected table, and the stale figures had already been copied into this mirror.

Fixed in hivecommons/hive#6741 as a repository-wide sweep for the figures rather than an edit to the one file that happened to be noticed, and verified with grep across every .md and .go file rather than by re-reading the document. That is now three instances of the same failure mode in this document set (maintainer count, OpenSSF badge status, red-team figures), which I think is the more useful thing to report than any individual number.

This mirror is generated from the canonical copy at src/docs/security-self-assessment.md and verified byte-identical; corrections continue to flow repo → here, never the reverse. This push also fixes two relative releases.md links that resolved nowhere in this repository.

@sherine-k sherine-k 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.

hi @clubanderson
Thank you for this PR and for the recent updates you have made.
I have added a few questions, especially to make sure that all angles of the threat model were equally addressed.
A comment on the style rather than the content: Some sections looked somewhat dense and harder to read for me. Do you think you could do something?

@clubanderson

Copy link
Copy Markdown
Contributor Author

@sherine-k — thank you for the second pass. All six inline questions are answered individually; two of them surfaced things worth tracking rather than just describing, so they now have issues:

On readability: agreed. The next push to this PR will (a) fold the answers above into the document — a credential-storage/blast-radius table, a hub↔spoke threat table, the relay authentication paragraph, the image tradeoff — (b) collapse the red-team section to a summary that links to ioscan-red-team.md, and (c) break the dense sections (Actions, Critical components, Weaknesses) into short paragraphs and tables, moving detail to the appendix. I will ping when it is up.

@clubanderson

Copy link
Copy Markdown
Contributor Author

@sherine-k — the revision is up (6eaa9cb), mirrored from the canonical copy (hivecommons/hive#7088). What changed, mapped to your comments:

Your comment Where it landed
L102 — token/key storage, blast radius, install/update New Credentials: where they live and what falls with them — storage table (spoke / hub / self-hosted), blast-radius table per compromised actor, install/upgrade facts and the attestation gap
L110 — relay authentication New Contributor relay authentication
L113 — hub↔spoke threats New Hub ↔ spoke interface — both directions + hub-minted tokens, and a threat table. Unsigned config push filed as hivecommons/hive#7082
L196 — fail_mode / canaries Framing corrected in three places (open redacts and continues); plan in hivecommons/hive#7083 — canaries on everywhere, closed at ACMM ≥ L5
L291 — red-team duplication Cut to a five-row summary table linking to ioscan-red-team.md
L497 — one image, every backend Stated as a tradeoff with cost, mitigations and roadmap under Security relevant components
Style Densest paragraphs replaced with tables; a stale appendix answer ("no adversarial testing has occurred") corrected to say what was done and what still has not been (external review)

A Revision 3 table at the top maps each point to its change, same as Revision 2 did for Justin's round. Ready for another look.

clubanderson added a commit to hivecommons/hive that referenced this pull request Sep 15, 2026
cncf/toc#2286 second review (sherine-k) asked six questions the document
had answered by control rather than by consequence. Changes:

- New "Credentials: where they live and what falls with them": storage
  table per credential per deployment shape, blast-radius table per
  compromised actor (spoke / relay / hub), install and upgrade facts.
- New "Hub <-> spoke interface": both directions and the hub-minted
  tokens, plus a threat table. Finding: hub->spoke heartbeat responses
  carrying config and App credentials rely on TLS alone and are not
  signed or hive-bound. Filed as #7082.
- New "Contributor relay authentication": hashed registration token,
  constant-time compare, trust tiers, 55-minute per-task token, and the
  stated weaknesses.
- Corrected the document's own framing of fail_mode: open in three
  places -- it REDACTS a Critical finding and continues, it does not pass
  the injection through. Defaults plan (canaries on everywhere, closed at
  L5+) tracked in #7083.
- Red-team paragraph in critical component 2 replaced with a summary
  table linking to ioscan-red-team.md.
- "One image, every backend" stated as a tradeoff with cost, mitigations
  and roadmap.
- Appendix answer "no adversarial testing has occurred" was stale since
  #6685 closed; now says what was done and what still has not been
  (external review).
- Revision 3 table at the top mapping each review point to its change.

Link checker: all relative links and anchors resolve.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andy Anderson <andy@clubanderson.com>
clubanderson added a commit to clubanderson/toc that referenced this pull request Sep 15, 2026
Revision 2 in response to the seven review comments on cncf#2286.

- Add a deployer-facing threat section: the attack path from a stranger's
  issue to a repository write, what stands in the way of each concern and
  what does not, the three settings that determine exposure, and the worst
  realistic outcome at L6.
- State plainly that ioscan has never been red-teamed and has no measured
  detection rate; recharacterize it as a partial mitigation and credit
  containment to the network deny rules instead.
- Re-scope log scrubbing as log hygiene rather than an exfiltration control,
  and answer the base64 question directly. Running that question against the
  canary path surfaced a real defect: the egress check is substring-only, so
  an encoded canary is not detected, while the input path does decode base64.
- Replace the false "Case studies: not applicable" claim with the seven
  adopters in ADOPTERS.md, three in production, one at ACMM L5/L6 across 43
  repositories.
- Record that the maintainer roster grew from one to three across three
  affiliations and that a security response process now exists; restate the
  remaining risk as unenforced code ownership rather than bus factor.
- Correct the SBOM explanation: #3760 is a container-runtime exec defect
  caused by attestations forcing an OCI index, not an SBOM deprioritization.
- Delete the open-questions section and answer every item against the
  repository, including two answers that are "no".
- Commit to the OpenSSF Best Practices badge.

Tracking issues filed: hivecommons/hive#6684, #6685, #6686, #6687, #6688.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@Santoshkumarpuppala

Copy link
Copy Markdown

@clubanderson the defaults sherine-k asked about on L304 changed after this mirror was synced, so the document under review still gives the old answer. 9c772add was pushed about half an hour before hivecommons/hive#7095 merged (2026-09-15 19:08Z). That PR turned canaries on by default and made fail_mode default to closed at ACMM L5–L6 (src/docs/ioscan.md:10-11, src/pkg/config/packs/level-5.yaml:18 and level-6.yaml:18, at 616fd46 on v5).

The mirror still says otherwise at L304 ("Canaries are default-off"), L318-319 ("Both default off"), L427 ("ioscan.canaries, default off") and L729 ("default ioscan.fail_mode is open"). Weakness 1 in the PR description still says fail_mode "defaults to open".

A resync alone would carry this back in. The canonical copy at 616fd46 (same lines on v4) has the same four statements at L308, L322-323, L437 and L739. Item 3 says "Both default off" at L322-323 and then, at L332-338, that #7095 shipped. Suggest fixing those four lines to match ioscan.md:10-11, then resyncing and updating the description. Read at those SHAs, not run. This is only about the text matching the shipped config, not about which default is right.

@clubanderson

clubanderson commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks @Santoshkumarpuppala — you were right. I resynced this from the corrected canonical Hive self-assessment and fixed the stale ioscan defaults in the four cited spots, the item 3 contradiction, and the PR description Weakness 1.

Canonical Hive PRs:

Mirror update on this PR: clubanderson/toc@76076d0

The corrected wording now says ioscan.canaries defaults on everywhere unless canaries: false opts out, and ioscan.fail_mode is level-aware: open at ACMM L1-L4, closed at ACMM L5/L6 via the L5/L6 packs, with explicit per-hive fail_mode overriding either default.

Second pass: fixed 10 more stale statements (bin path/count, forge support, Sandbox stage, ACMM code-write levels, budget window, maintained branch, Scorecard branches, 60-day public-vulnerability commitment, #2804 status, and v5 CODEOWNERS enforcement wording).

@github-actions

github-actions Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign abebars after the PR has been reviewed.
You can assign the PR to them by writing /assign @abebars in a comment when ready.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Santoshkumarpuppala

Copy link
Copy Markdown

@clubanderson confirmed at 6617e1f: L304, L318-331, L430, L732-736 and Weakness 1 now match hivecommons/hive@325ce9a (src/pkg/config/config.go:415-432, src/pkg/config/packs/level-5.yaml:18, level-6.yaml:18). A grep for the old wording finds it at 9c772add and nowhere at head. Read, not run.

Since hivecommons/hive#9923 was closed with v4 unmaintained, as L597-598 now say, L10, the description's "Source document" and the other 26 blob/v4 links could point at v5; the v4 copy at 5c287a3 still has all four old statements. L58 also pins citations to 327969b0 on v4, where the ioscan.md:10-11 cited at L732 still reads "open (default)" and canaries: false. Canonical has the same L58, so that fix starts there.

@sherine-k on your hub/spoke question: L37, L209 and L218 are still the pre-#7082 text (responses unsigned, issue open). hivecommons/hive#7082 closed as completed on 2026-09-15 and canonical at 325ce9a says mitigated, but verification is log-only unless a spoke sets HIVE_HEARTBEAT_VERIFY=enforce: a failed signature is logged and the response still applied (src/pkg/spoke/verifier.go:42-54, :335-344). Canonical L222 says enforcement is opt-in; worth keeping that in the resynced rows.

@clubanderson

Copy link
Copy Markdown
Contributor Author

@Santoshkumarpuppala @sherine-k thanks for the follow-up. I made a small canonical Hive PR and resynced this mirror:

  1. Switched the self-assessment evidence links from blob/v4 to blob/v5, including the mirror's canonical-source link and this PR description's Source document link.
  2. Updated the citation pin from the old v4 SHA to current v5 head baa7dacc7; ioscan.md:10-11 still matches the level-aware fail_mode and default-on canary wording at that SHA.
  3. Corrected the hub→spoke rows for #7082: heartbeat responses are now signed and verified by the spoke, but enforcement is opt-in with HIVE_HEARTBEAT_VERIFY=enforce; by default failed verification is logged and the response is still applied.

Canonical Hive PR: hivecommons/hive#9985
Mirror commit: 9e7ce93b82a162cc7e56ac67956e5ebce34f53eb

@Santoshkumarpuppala

Copy link
Copy Markdown

@clubanderson checked at 9e7ce93: no blob/v4 links are left (27 now point at v5), the L58 pin is baa7dacc7 on v5, and the hub/spoke text says signature enforcement is opt-in with HIVE_HEARTBEAT_VERIFY=enforce (L206-207). Read, not run. Nothing further from me on these.

@clubanderson

Copy link
Copy Markdown
Contributor Author

/kind docs

Ready for another look. Every review thread now has an in-thread pointer to where the document answers it and is resolved — reopen any that don't.

What changed since the first review (2026-08-31), at head 9710605:

@JustinCappos

@sherine-k

Housekeeping: Hive moved to its own org on 2026-09-03, so the file now lives at projects/hive-commons/security-assessment/ and the canonical copy is hivecommons/hive src/docs/security-self-assessment.md on v5 (mirror resynced today, pin e6fb024e9).

/cc @JustinCappos @sherine-k — requesting re-review.

@github-actions github-actions Bot added the kind/docs Docs related changes or updates label Oct 19, 2026
@github-actions
github-actions Bot requested a review from JustinCappos October 19, 2026 15:59
@github-actions github-actions Bot removed the needs-kind Indicates an issue or PR that is missing an issue type or kind (a kind/foo label) label Oct 19, 2026
Comment on lines +873 to +881
Two earlier revisions of this section were wrong about this, in opposite
directions, and both errors are worth recording. The first said the badge was
"not yet assessed whether this is planned," which was an evasion rather than
an answer; TAG-Security review called it out. The correction then overshot by
describing the badge as not yet held and merely "being pursued" — but it had
in fact been awarded on 2026-08-27, four days before that review. In both
cases this document was written from itself rather than re-derived from
observable state, which is the same defect that left the maintainer count
stale. The badge status above is taken from the programme's public API.

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.

You still have cases like this where the LLM is chatting information into the document. Please have a human go through and remove all of this type of content,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for catching it. I will get it cleaned up now. I hate when it does this.

Security self-assessment for hivecommons/hive, following the TAG-Security
self-assessment template, submitted in support of the CNCF Sandbox
application (cncf/sandbox#516). The canonical copy lives in the Hive
repository at src/docs/security-self-assessment.md and is mirrored here.

Signed-off-by: Andy Anderson <andy@clubanderson.com>
@clubanderson
clubanderson force-pushed the docs/hive-security-self-assessment branch from 9710605 to 9769838 Compare October 22, 2026 12:46
@clubanderson

Copy link
Copy Markdown
Contributor Author

Removed drafting commentary from the document text: the Revision 2/3 response tables, the "Questions resolved since first review" section, the revision-history paragraph under Open SSF best practices, and review-process asides throughout. Facts previously only stated in the removed sections (v5 branch protection requires no PR reviews; red-team corpus is maintainer-authored with no external review) are now in §Known weaknesses and §Critical security components. Commit history squashed to a single commit (9769838).

@JustinCappos

Copy link
Copy Markdown
Contributor

Removed drafting commentary from the document text: the Revision 2/3 response tables, the "Questions resolved since first review" section, the revision-history paragraph under Open SSF best practices, and review-process asides throughout. Facts previously only stated in the removed sections (v5 branch protection requires no PR reviews; red-team corpus is maintainer-authored with no external review) are now in §Known weaknesses and §Critical security components. Commit history squashed to a single commit (9769838).

This is an AI generated commit message. Based upon the fact that the prior edits have been from AI, I'm not convinced that a human has reviewed any of this as was requested repeatedly.

@mnm678 @jkjell @evankanderson

I don't know a good way to handle this, but I will not be continuing to look at this unless this issue is resolved. Perhaps the best way would be for a human from the project show up to a TAG Security and Compliance meeting in person to discuss your self assessment. The human should understand and be able to defend all parts of the self assessment as though they wrote it themself.

@clubanderson

Copy link
Copy Markdown
Contributor Author

@JustinCappos there is no expectation for our members, or me, to show up for a meeting at the TAG Security without the knowledge (and ability to explain it). The use of AI is to compile legible and comprehensive documentation quickly. It is not to portray our project as an unknown that nobody is capable of explaining. We have designed the project to use AI throughout. That does not mean the maintainers are incapable of explaining how it works, its design, or the security aspects of it. Please don't conflate the use of AI with an inability for maintainers to explain core concepts and architecture.

@JustinCappos

JustinCappos commented Oct 22, 2026 via email

Copy link
Copy Markdown
Contributor

@clubanderson

Copy link
Copy Markdown
Contributor Author

I see - so this is about style and terse-ness of the document. I get it. Yes, sometimes claude gives you riddles only it can interpret. Completely fair. Let me noodle on this and come back with something that resembles a human readable format. Thank you for the feedback.

Shorter, template-aligned rewrite of the Hive Commons self-assessment:
every section explains what a control does before any numbers, open
gaps are stated plainly, and the linked security docs were rewritten to
the same reading level. Canonical copy lives in hivecommons/hive.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@clubanderson

clubanderson commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor Author

@JustinCappos we took the review feedback to heart and rewrote this from scratch rather than patch it. The original was difficult to follow and too lengthy and conversational to be useful.

What changed:

  • Shorter (about 3,200 words, in line with the median of accepted assessments) and written so a non-specialist can follow it; every control is explained before any numbers appear.
  • Follows the template sections exactly.
  • Open gaps are stated plainly up front (shared container by default, registration token rotation, no external red team yet).
  • The seven linked security docs in the Hive repo were rewritten to the same reading level and are now kept from going stale by a CI check.

We would appreciate another look when you have time, and are happy to walk through any part of it. Thank you for your patience with the earlier version.

@JustinCappos JustinCappos 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.

Okay, thanks for the work on this. This is a lot better now. I've left some detailed comments below, but it's in much better shape.

| -- | -- |
| Assessment Stage | Complete |
| Software | <https://github.com/hivecommons/hive> |
| Security Provider | No. Hive runs AI coding agents; its security controls exist to limit what those agents can do. |

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.

If it exists to limit what agents can do, is it a provider? Maybe I don't know the definition...


Each actor below runs separately from the others; the isolation between them is what stops a problem in one from spreading.

* **Agent processes.** Each agent runs under its own Unix user ID inside the spoke container, in its own `tmux` session, with its own GitHub token file that other agents cannot read. Agents share one container and one kernel; there is no per-agent container or virtual machine.

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.

How do you stop other agents from reading it? Can you be more specific? (Also you mention isolation above and I have the same question)

* **Egress proxy.** All HTTPS traffic from agent processes is forced through an in-container proxy (using `iptables`, which requires the `CAP_NET_ADMIN` capability). The proxy identifies the calling agent by the socket's user ID, not by anything the agent claims, and applies a rule table for that agent's level. If the proxy cannot be set up, the spoke refuses to start.
* **Hive core.** A Go process that schedules agents, runs the pre-kick pipeline (see Actions), serves the dashboard and performs the GitHub writes that agents are not allowed to make themselves. It holds the GitHub App key and mints the short-lived, per-agent tokens.
* **Dashboard and API.** Browser access with four roles: read, read-write, merger, owner. Sessions and hub single sign-on are verified with Ed25519 signatures (a public-key scheme); a spoke with no verification key returns HTTP 503 rather than falling back to a weaker check.
* **Hub.** Holds a master secret that never leaves it. Each spoke receives only keys derived from that secret for its own hive ID, plus the hub's public key. Hosted spokes receive their own GitHub App key and nothing belonging to other tenants.

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.

What about confused deputy style attacks? How do you protect against them? SPIFFE had a nasty issue with this a few years back that was very non-trivial to fix.

### Actions

1. **Select work.** Shell scripts enumerate open issues and pull requests, classify them and compute merge eligibility before any model is involved.
2. **Scan input.** `ioscan` normalizes the text (removing invisible Unicode characters and look-alike letters), undoes common encodings and checks the whole thread for known prompt-injection phrasing, dangerous instructions and secret-shaped strings. Text from strangers is withheld when any rule fires. At L1–L4 a critical finding is redacted and the task proceeds; at L5–L6 the task is blocked. A distinct canary string is planted in each prompt.

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.

I think ioscan hasn't really be evaluated to show it is very effective at protecting against prompt injection. (At least to my knowledge, at this time.) Is this a major area of concern?

note, I see you've addressed this somewhat below. Maybe make this text less definitive so that at this point in my reading I know that you don't think this is a perfect defense.

4. **Mediate GitHub calls.** Every request passes the proxy. The rule table allows or denies each REST method and path, and each GraphQL mutation, for the agent's level; anything unmatched is denied. Creating a pull request (`POST /pulls`) and merging one (`PUT /pulls/{n}/merge`) are denied for every level.
5. **Perform privileged writes.** To open or merge a pull request, the agent drops a request file. Hive core reads the file's owner (not its contents) to identify the agent, re-checks eligibility, and performs the write as the GitHub App. Every such write carries a visible trailer naming the agent, backend and model, and is appended to an audit log.
6. **Scan output.** The proxy scans outbound GitHub request bodies for the canary, after decoding base64, hex, percent-encoding, reversed and split spellings. A hit is logged and, at L5–L6, blocked.
7. **Talk to the hub.** A spoke sends operational status (never credentials) using a per-hive bearer token. The hub replies with configuration, signed with Ed25519 and bound to the hive ID and a sequence number. By default a spoke logs a bad signature and still applies the response; rejection requires `HIVE_HEARTBEAT_VERIFY=enforce`.

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.

what is the purpose of the signature? Is it non-repudiation / authenticity?


### Development pipeline

* `v5` is the maintained branch. Branch protection requires eleven status checks before merge: `gate`, `DCO` (Developer Certificate of Origin sign-off), `build-and-test`, `test`, `coverage`, `golangci-lint`, `gosec`, `govulncheck`, a changelog-fragment guard, a PR-contents check and a sign-off-survives-squash check. Administrators are not exempt.

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.

Having v5 as the main branch may trip up folks and scanners. (Just mentioning, not trying to put a fine point on this.)


Still open:

* Agents share one container by default. An opt-in sandbox mode runs each task in its own rootless container with no credentials, but it is not the default. We are evaluating stronger isolation options, including OpenShell.

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.

You might also consider nono

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

Labels

kind/docs Docs related changes or updates needs-triage Indicates an issue or PR that has not been triaged yet (has a 'triage/foo' label applied) tag/security-and-compliance TAG Security and Compliance

Projects

Status: New
Status: No status
Status: No status
Status: No status

Development

Successfully merging this pull request may close these issues.

5 participants