{"id":"CVE-2026-103090","kind":"vulnerability","aliases":["CVE-2026-103090"],"related":[],"title":"Google SAM: unauthenticated enrollment endpoint leaks peer identity tokens","description":"Missing Authentication for Critical Function (CWE-306) and Insufficiently Protected Credentials (CWE-522) in the control plane enrollment status handler (HandleEnrollStatus at GET /enroll/status in internal/controlplane/server.go) in Google OSS Agent Mesh (SAM) versions 0.1.0-alpha.1 through 0.1.0-alpha.8 allow an unauthenticated remote attacker to retrieve an approved bootstrap-enrolled peer's signed Biscuit identity token by supplying a peer_id obtainable from the unauthenticated GET /info endpoint. A related flaw in POST /enroll allowed any bootstrap-token holder to re-fetch another peer's credential. An attacker can replay the disclosed Biscuit token as a bearer credential on /policies to read mesh authorization policies and on /routers/lease to overwrite advertised router multiaddrs. Users should upgrade to version 0.1.0-alpha.9 or later, which requires cryptographic proof of possession of the enrollment private key on credential-releasing endpoints, enforces rate limiting, and validates router lease addresses.","summary":"Google SAM (Sovereign/OSS Agent Mesh, github.com/google/sam) control plane: GET /enroll/status needs no credential and returns an approved bootstrap-enrolled peer's signed Biscuit token. The peer_id it needs is published by the unauthenticated GET /info. The token works as a bearer credential on /policies (read mesh roles and bindings, including member emails) and /routers/lease (overwrite advertised router addresses, so mesh-join disruption). Limits: only bootstrap-token-enrolled peers, mostly routers (the chart default router path is affected); OIDC-enrolled peers are not; the stolen token is valid for 24h from approval. Public exposure depends on the Gateway/HTTPRoute exposing the enrollment paths (chart gateway.enabled is false by default).","severity":"high","cvss":8.8,"epss":0.00335,"exploited":false,"exploited_at":null,"products":[{"name":"google/sam","fixed":["0.1.0-alpha.9"],"affected":">= 0.1.0-alpha.1, < 0.1.0-alpha.9","ecosystem":"go"}],"ecosystems":["go"],"tags":["agent-mesh","kubernetes","mcp","package","sam","self-hosted"],"not_affected_if":["control-plane-not-internet-exposed","default-config","managed-hosting","oidc-enrolled-peers"],"how_to_check":"Run the control plane and check the version: affected if it is github.com/google/sam < v0.1.0-alpha.9 (0.1.0-alpha.1 to alpha.8). Check whether the control plane is internet-reachable: curl https://<control-plane>/info lists router addresses (and the peer IDs), and curl 'https://<control-plane>/enroll/status?peer_id=<id>' returning ENROLLMENT_STATUS_APPROVED with a biscuit_token means you are exposed. Check whether routers were enrolled with bootstrap tokens (router.useOidcToken: false, the chart default).","fix":"Upgrade to v0.1.0-alpha.9 or later. After upgrading, restart or re-enroll routers so their enrollment-time Biscuits are replaced, and review /policies and router lease addresses for tampering. If you cannot upgrade, do not route /enroll/status and /info to the public internet (restrict the Gateway HTTPRoute to trusted networks).","status":"resolved","published_at":"2026-10-21T23:17:24+00:00","first_seen_at":"2026-10-23T21:57:29+00:00","triaged_at":"2026-10-23T22:32:44+00:00","updated_at":"2026-10-24T13:15:54+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-10-23T22:32:44Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade to SAM 0.1.0-alpha.9 or later, which adds proof of possession of the enrollment key and rate limiting.\nRotate any peer Biscuit tokens that may have been exposed.","reach":"network","title":"Google SAM: unauthenticated enrollment endpoint leaks peer identity tokens","impact":"medium","summary":"Google OSS Agent Mesh (SAM) versions 0.1.0-alpha.1 through 0.1.0-alpha.8 let anyone who knows a peer_id, which the public /info endpoint exposes, fetch that approved peer's signed Biscuit identity token from /enroll/status. The stolen token can then be replayed as a bearer credential to read mesh policies and overwrite advertised router addresses.","category":"package","who_cares":["sam","agent-mesh","self-hosted"],"confidence":0.8,"needs_auth":"no","worst_case":"Attacker reads mesh policies and overwrites router addresses using a stolen token","analyst_note":"","how_to_check":"Check the installed SAM version; alpha.1 through alpha.8 are affected.\nunknown","needs_analyst":false,"not_affected_if":["default-config"],"user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"high"},"cost_usd":0.000549,"input_tokens":3219,"output_tokens":455,"severity_before":"high"},"analyst_status":"done","analyst_note":"Confirm the affected deployment exposure and the exact check for alpha.1 to alpha.8 at the NVD entry and the project's release notes.","search":"'-103090':12A,15A '-2026':11A,14A '-306':147C '-522':153C '/enroll':214C '/enroll/status':38B,164C '/google/sam)':34B '/info':65B,207C '/policies':74B,242C '/routers/lease':84B,250C '0.1.0':174C,177C,261C '24h':122B 'address':88B,288C 'advertis':86B,253C 'affect':109B 'agent':18B,30B,170C 'agent-mesh':17B 'allow':179C,215C 'alpha.1':175C 'alpha.8':178C 'alpha.9':262C 'anoth':225C 'approv':45B,124B,187C 'attack':183C,230C 'authent':142C 'author':246C 'bearer':71B,239C 'bind':79B 'biscuit':52B,194C,235C 'bootstrap':47B,97B,189C,218C 'bootstrap-enrol':46B,188C 'bootstrap-token':217C 'bootstrap-token-enrol':96B 'chart':104B,135B 'control':35B,156C 'credenti':41B,72B,151C,228C,240C,278C 'credential-releas':277C 'critic':144C 'cryptograph':267C 'cve':10A,13A 'cwe':146C,152C 'default':105B,140B 'depend':127B 'disclos':234C 'disrupt':93B 'email':82B 'endpoint':5A,208C,280C 'enforc':281C 'enrol':4A,48B,99B,112B,133B,158C,190C,273C 'expos':131B 'exposur':126B 'fals':138B 'fetch':224C 'flaw':211C 'function':145C 'gateway.enabled':136B 'gateway/httproute':130B 'get':37B,64B,163C,206C 'github.com':33B 'github.com/google/sam)':32B 'googl':1A,27B,168C 'google/sam':16A 'handleenrollstatus':161C 'handler':160C 'holder':220C 'host':26B 'id':56B,201C 'ident':8A,195C 'includ':80B 'insuffici':149C 'internal/controlplane/server.go':166C 'join':92B 'key':275C 'kubernet':20B 'later':264C 'leak':6A 'leas':287C 'limit':94B,283C 'mcp':21B 'member':81B 'mesh':19B,31B,76B,91B,171C,245C 'mesh-join':90B 'miss':141C 'most':101B 'multiaddr':255C 'need':39B,58B 'obtain':202C 'oidc':111B 'oidc-enrol':110B 'oss':169C 'overwrit':85B,252C 'packag':22B 'path':107B,134B 'peer':7A,49B,55B,100B,113B,191C,200C,226C 'plane':36B,157C 'polici':247C 'possess':270C 'post':213C 'privat':274C 'proof':268C 'protect':150C 'public':125B 'publish':60B 'rate':282C 're':223C 're-fetch':222C 'read':75B,244C 'relat':210C 'releas':279C 'remot':182C 'replay':232C 'requir':266C 'retriev':185C 'return':43B 'role':77B 'router':87B,102B,106B,254C,286C 'sam':2A,23B,28B,172C 'self':25B 'self-host':24B 'sign':51B,193C 'sovereign/oss':29B 'status':159C 'stolen':117B 'suppli':198C 'token':9A,53B,67B,98B,118B,196C,219C,236C 'unauthent':3A,63B,181C,205C 'upgrad':258C 'user':256C 'valid':120B,285C 'version':173C,260C 'work':68B","nicknames":[],"mitigations":[],"who_affected":null,"tier":"B","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-21T23:17:24+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"cve-coordination@google.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-103090","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-103090","severity":null,"published_at":"2026-10-21T23:17:24+00:00","modified_at":"2026-10-22T16:18:19+00:00","first_seen_at":"2026-10-23T21:57:29+00:00","fetched_at":"2026-10-23T22:29:02+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-103090:515","url":null,"severity":null,"published_at":"2026-10-23T23:46:25+00:00","modified_at":"2026-10-23T23:46:25+00:00","first_seen_at":"2026-10-23T23:46:25+00:00","fetched_at":"2026-10-23T23:46:25+00:00","note":"Read maintainer advisory GHSA-hp3x-79wr-rx66 (google/agentmesh): affected < v0.1.0-alpha.9, fixed alpha.9. Advisory has a private PoC (not public, not attached); no exploitation reported; no X chatter. Scope narrower than summary: only bootstrap-token-enrolled peers (mainly routers), OIDC-enrolled not affected, token valid 24h from approval. Did not read release notes for alpha.9 directly; fix details (PoP, rate limit) come from MindPattern/vendor summaries."},{"source":"epss","external_id":"CVE-2026-103090","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-103090","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-24T13:15:54+00:00","fetched_at":"2026-10-24T13:15:54+00:00","note":null}],"documents":[{"id":2161,"url":"https://github.com/google/agentmesh/security/advisories/GHSA-hp3x-79wr-rx66","title":"GHSA-hp3x-79wr-rx66: Unauthenticated GET /enroll/status returns an approved peer's Biscuit","kind":"advisory","source":"analyst","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null},{"id":2162,"url":"https://www.ionix.io/threat-center/cve-2026-103090/","title":"CVE-2026-103090 analysis (Ionix)","kind":"blog","source":"analyst","text":null,"published_at":null,"relation":"describes","confidence":null,"note":null}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}