What actually protects
Binary³ MCP.
This page is derived from the production codebase: its quantitative claims are drift-bound to source constants, its status and permission tables are content-pinned, and its logging claims are backed by implementation guards. Those guards verify the specific invariants named — they are not a proof of every sentence. Where a control does not exist, is not tested, or is not yet qualified, this page says so — in those words — rather than implying otherwise.
Status at a glance.
Statuses are deliberately conservative: a control is "implemented and tested" only where the automated suite exercises it, and "qualified" only where an independent qualification gate has passed. Component correctness is not end-to-end qualification.
| Control area | Status | Basis |
|---|---|---|
| Public JWKS surface | Qualified | The public verification-key document and its discovery chain are production-qualified |
| Authenticated MCP end-to-end | Qualified | Passed the post-roadmap production qualification gate (2026-09-14): both public tools invoked through the live machine endpoint; negative-authentication matrix and live revocation verified |
| TLS in transit (machine endpoint) | Verified | The public MCP endpoint is served over HTTPS at mcp.binarycubed.com — TLS terminates at the deployment edge; application code does not enforce the scheme |
| Bearer / JWT validation | Implemented + tested | Signature, issuer, audience, lifetime, algorithm, and key-id checks with a deny-all default; exercised by the automated suite |
| Per-tool entitlement | Implemented + tested | A credential must carry the exact tool name in its verified scopes; default is deny |
| Live credential–tenant binding | Implemented + tested | Every tool call re-authorizes the credential against the database before work begins; failures fail closed |
| Tool allowlisting / dispatch | Implemented + tested | Fixed registry of exactly two tools with a runtime exact-set assertion; allowlisted name dispatch only — no dynamic import or reflection |
| SSRF controls | Implemented + tested | DNS-first validation of every resolved address, connection pinning, per-hop redirect re-validation, proxy bypass disabled; classification below |
| Transport rate limiting | Implemented + tested | Per client IP at ingress, fail-closed; distinct from product quota |
| Credential logging | Never logged — tested | The bearer credential itself is excluded from logs, telemetry, and error responses — by construction and by test |
| KeySweep input persistence | Not persisted — tested | Submitted text is processed in memory; audit records keep counts and metadata, never the text |
| Role- or plan-based capability authorization | Not implemented | Authorization is scope-based per tool; plan tier influences quota policy, not capability |
| General data-retention policy | Not verified | Specific lifetimes are enforced where listed below; no general enforced retention policy exists in code or configuration |
| Compliance certifications | Not claimed | No certification or attestation is claimed anywhere on this page |
The request path.
Only controls that exist in the running service are shown. Each arrow is a boundary where a request can be rejected.
Client
agent / LLM host, over HTTPS
Ingress — rejects before protocol handling
mcp.binarycubed.com/mcp
Protocol
exactly two tools, exact-set asserted at boot
Per-call authorization
database re-authorization on every call
Tool services
in-process text analysis — no network
validated outbound fetch — public targets only
Axon is a separate Binary³ agent-security capability. It is not in this path and enforces none of it.
What each boundary answers.
| Hop | Representative threats | Controls in place |
|---|---|---|
| Client → endpoint | Credential theft, token replay, oversized payloads | Public endpoint served over HTTPS (TLS edge-terminated); token lifetime and issuance-time enforced with a 30-second clock-skew allowance; the bearer credential is never logged; request bodies bounded by the transport bridge (413) |
| Endpoint → authentication | Invalid or forged JWT, algorithm confusion, unknown key id, stale keys | Signature verification against the published JWKS; RS256/ES256 only; exact issuer and audience; an unknown key id is denied outright while the JWKS cache is fresh, and a stale cache single-flights one refresh per 300-second window; failed refreshes deny rather than fall back to stale keys |
| Request → tool dispatch | Tool-name spoofing, schema bypass, arbitrary function invocation | Fixed registry of two direct function references with a runtime exact-set assertion; the SDK dispatches by name against that fixed set only — no dynamic import or reflection; argument schemas enforced by the SDK from typed signatures |
| Dispatch → service | Broken authorization, cross-tenant laundering, disabled or expired credentials | Per-tool scope entitlement, then a live database binding check (active, non-deleted, unexpired, tenant-agreeing) on every call; failures are uniform and fail closed |
| Tool → outbound target | SSRF, DNS rebinding, redirect-based bypass, cloud metadata access, localhost and private-range access | Scheme and port allowlists; DNS-first validation of every resolved address; connection pinned to the validated addresses; every redirect hop re-validated from scratch; proxy environment disabled — detailed below |
| Response → client | Error-detail leakage, secret echo | Fixed ingress error envelopes with no internals; tool failures returned as code-and-message pairs; KeySweep results redact matched secret values |
| Logs / telemetry / storage | Credential or payload leakage, log injection | The bearer credential is never logged; telemetry drops credential, body, and payload keys and scrubs bearer-like values; audit rows carry identifiers and counts, plus the scan target as scheme://host — never raw inputs |
Authentication.
Three different claims are kept separate on this page: a control can be implemented, tested, or qualified — and each word means something different.
Bearer-only boundary
Every MCP protocol request — including discovery and tool listing — requires an issued bearer credential in the HTTP Authorization header. Browser sessions and cookies are never consulted. Authentication happens at the transport edge, before any protocol processing.
What is verified
Signature against the published JWKS; algorithm restricted to RS256 or ES256 (the none algorithm and symmetric algorithms are rejected); exact issuer and audience; expiration and issuance time with a 30-second clock-skew allowance; a well-formed key-id claim and tenant claim are required.
Key handling
Verification keys come from a static environment-provided JWKS document or an HTTPS JWKS URL. Unknown key ids trigger at most one refresh per cache window; a failed refresh denies rather than serving stale keys. The public JWKS document is served with Cache-Control: no-store.
Deny-all default
With no verifier configured, or with partial or malformed configuration, every token is rejected — including discovery requests. There is no implicit trust path.
Failure behavior
Missing, malformed, or rejected credentials receive HTTP 401 with a fixed unauthorized body and a WWW-Authenticate challenge. Rejection responses contain no token material and no internal detail.
Identity reduction
After verification, the request carries an internal key identifier as its subject, a scope set intersected with the registered tool vocabulary, a plan tier, and a tenant identifier. The raw token is discarded at the boundary.
Status: implemented and tested — the verification paths above are exercised by the automated suite (expired, wrong issuer, wrong audience, foreign signature, disallowed algorithm, missing or unknown key id, unconfigured and partially configured environments). Authenticated end-to-end MCP operation is independently qualified (2026-09-14 gate).
Authorization — what a credential may do.
Authentication answers "who is calling." Authorization answers "what may they do." These are separate questions and this service answers them in two layers.
Per-tool entitlement
A verified credential carries scopes, and invoking a tool requires that tool's exact name in the scope set — keysweep_scan_text or microdefend_scan_website. The check runs against the dispatch-selected tool name, so arguments cannot substitute a different entitlement. Missing entitlement is denied by default with forbidden.
Live binding check
On every call, before any scan work or quota consumption, the credential is re-authorized against the database: the key must be active, not deleted, unexpired, and agree with the claimed tenant. A check that cannot be completed fails closed (binding_check_unavailable) rather than proceeding.
What does not exist
There are no role-based permissions, no per-user permission objects, and no plan-based capability branching in the MCP path. Plan tier influences quota policy only. Authorization is exactly: verified scopes plus a live binding check.
Revocation behavior
Because entitlement and binding are re-evaluated per request, a credential that is deactivated, expired, or loses its tenant binding fails closed on its next call. There is no session caching of authorization decisions.
Tool permission matrix.
The public tool surface is closed at exactly two tools. Neither is "read-only" in the broadest sense — the matrix states what each actually does.
| Tool | Operation type | External network | Sensitive input | Side effects | Permission model |
|---|---|---|---|---|---|
keysweep_scan_text |
Analytical — in-process pattern analysis of supplied text | None | Submitted text may contain credential-like strings — that is the tool's purpose | None on account state; consumes one unit of quota per accepted scan; writes an audit record of metadata only | keysweep_scan_text scope + live binding check |
microdefend_scan_website |
Network-active — outbound requests to a user-supplied public URL | Yes — HTTP/HTTPS to validated public targets only | A public URL the caller is authorized to scan | Outbound requests to third-party sites; a redacted scan result is persisted; consumes quota and a concurrency slot | microdefend_scan_website scope + live binding check |
The MCP server as a whole is not read-only: MicroDefend performs outbound network activity by design. KeySweep is read-only with respect to account state and performs no network access. Any tool added to this registry in the future fails the registry assertion until this page's matrix is reviewed.
keysweep_scan_text.
What enters
A single text field, 1 to 256,000 characters. Input is validated before any quota is consumed; rejected input (invalid_text, text_too_large) costs nothing.
Where it goes
Nowhere. Analysis runs in-process; no network call is made, and no third party receives the text or derivatives of it.
What is stored
The submitted text is not persisted. The audit record stores the actor identifier, detection counts, risk level, and a correlation identifier — never the text and never matched secret values.
What comes back
Redacted findings: type, severity, confidence, a fingerprint, and the matched value's length — plus counts and an overall risk level. Matched secret values are not returned.
microdefend_scan_website — the outbound pipeline.
MicroDefend fetches a user-supplied URL, which makes server-side request forgery the controlling threat. Validation happens in this order, and no connection to the target is attempted before every step passes.
- Syntax and scheme. The URL must be a string of at most 2,048 characters, parse cleanly, and use exactly
httporhttps. Embedded credentials (user:pass@host) are rejected. - Port restriction. Only ports 80 and 443 are reachable; explicit ports outside that set are rejected.
- Blocked hostnames.
localhost, cloud metadata hostnames, and the.local,.internal,.localdomain, and.home.arpasuffixes are rejected by name. - DNS first. The hostname is resolved before any connection, and every resolved address is validated — a single private answer in a mixed response rejects the whole target.
- Address classification. Private, loopback, link-local, reserved, multicast, and unspecified addresses are rejected, including IPv4-mapped IPv6, 6to4, and Teredo forms. Cloud metadata endpoints are blocked by exact address: 169.254.169.254, fd00:ec2::254, 100.100.100.200, and 192.0.0.192.
- Connection pinning. The connection uses the exact addresses validated in step 4 — resolution is pinned for the request, so a hostname that starts answering differently after validation cannot redirect the connection (DNS-rebinding defense).
- No proxies. Proxy environment variables and session-level proxies are forcibly disabled for target requests; the caller cannot reintroduce one.
- Bounded redirects. Redirects (301/302/303/307/308) are followed manually, at most 3 hops, and every hop is re-validated from step 1 — including a fresh DNS resolution and full address classification.
- Size and time limits. Response bodies are capped at 2 MiB, checked via Content-Length and by counting streamed bytes. Every outbound request is capped at 15 seconds (the scanner default is 10). A scan makes several requests and sequential probes, so there is no single wall-clock deadline.
TLS posture
The page-metadata fetch deliberately does not verify the target's TLS certificate — the scanner's job includes assessing broken TLS, which a verifying fetch could not observe — while the other target fetches verify normally. The separate SSL probe evaluates the target's certificate using a verifying default context. The public MCP endpoint is served over HTTPS, terminated at the deployment edge.
Identification
Scanner requests identify themselves with a MicroDefend Security Scanner/1.0 user agent; the page-metadata fetch presents a browser user agent to observe what a visitor's browser would receive.
Scope notes
Internationalized hostnames are handed to the system resolver after lowercasing — every resolved address is still validated, so resolution quirks cannot bypass the address checks. Address classification uses the Python ipaddress library's semantics, pinned by the test suite. The scanner timeout is per-request connect/read, not a total wall-clock budget.
Scan authorization
MicroDefend is for public URLs you are authorized to scan. The controls above constrain where the tool can connect; they do not grant permission to scan a target.
SSRF classification: robustly mitigated.
Classification: robustly mitigated for the documented vector classes — with the scope notes above. This classification rests on the pipeline's structure, not on any single string check: every connection is pinned to addresses that passed full classification, and every redirect hop restarts validation from scratch.
| Vector | Result | Evidence |
|---|---|---|
| 127.0.0.1, localhost, ::1 | Rejected | Blocked hostnames plus loopback classification; automated tests |
| RFC1918 and other private ranges | Rejected | Address classification on literals and on every DNS answer; automated tests |
| Link-local (169.254.0.0/16) | Rejected | Link-local classification; automated tests |
| Cloud metadata (169.254.169.254 and IPv6/vendor equivalents) | Rejected | Exact-address blocklist plus classification; automated tests, including redirect-to-metadata |
| Hostname resolving to a private address | Rejected | Every DNS answer validated; mixed public/private answers reject the whole target; automated tests |
| Encoded IPv4 forms (decimal, hex, octal) | Rejected | Resolver-canonicalized, then classified; automated tests |
| IPv4-mapped IPv6, 6to4, Teredo | Rejected | Embedded IPv4 addresses recursively unwrapped and classified; automated tests |
| Public URL redirecting to a private target | Rejected | Each redirect hop re-validated from scratch; automated tests |
| DNS rebinding between validation and connection | Rejected | Connection pinned to the validated addresses; a hostname that flips after validation fails closed; automated tests |
| Proxy-based bypass | Rejected | Proxy environment forcibly disabled for target requests; automated tests |
| Non-HTTP schemes, credential-bearing URLs, non-80/443 ports | Rejected | Scheme, userinfo, and port allowlists; automated tests |
| Oversized responses | Rejected | 2 MiB cap via Content-Length and streamed-byte counting; automated tests |
Residual scope: the classification covers the URL-fetch path described above. It does not claim protection against vulnerabilities in target-side software, and it does not make the scanner safe to point at targets you are not authorized to scan.
Credential handling and secret management.
One entry point
Tokens enter only through the HTTP Authorization header at the MCP ingress. The header value is parsed strictly, verified, and then reduced to an internal identity — the token itself is not passed down the stack.
Never logged, never echoed
The bearer credential and the Authorization header value are never written to logs, telemetry, exceptions surfaced to clients, or error responses — that invariant is tested. Authentication failures log a reason, host, client IP, and correlation identifier. Headers a caller controls (such as Origin or forwarding headers) are recorded as received in rejection events — never place secrets in a header.
Credential lifecycle
Issued credentials have a maximum lifetime of 90 days. A newly minted credential is shown exactly once via a short-lived database record: held unhashed (it must be displayable), usable for up to 10 minutes, and deleted on first view. Expired records are not deleted at the moment of expiry — they are swept lazily the next time the same developer mints or views a credential, so an expired, never-viewed record can persist beyond its usability.
Secret storage
Application secrets — session signing, the issuer's private key, JWKS configuration, third-party API keys — are loaded from environment values — or, for the issuer signing key, from a file named by an environment variable — never from source. The repository contains no production credentials; test fixtures use non-production values, and the one hard-coded fallback in the codebase is a vendor-published public test key in a non-MCP path.
Examples are inert
All credential material in documentation and copy examples is placeholder text. No real token, key, or secret appears in public output.
Rotation
Credential rotation is exercised in the automated suite. Rotation of the public verification keys is an operational procedure: an environment update followed by a redeploy.
Logging, telemetry, and audit.
| Recorded | Never recorded |
|---|---|
| Rejection logs carry host, client IP, correlation identifier, and a reason string where the request was parsed far enough to have them; rejected-origin events also record the origin value. The earliest rejections (missing or untrusted Host) log less — there is nothing trustworthy to record yet | The bearer credential; Authorization header values |
| Security event class, tool name, actor identifier, and outcome for tool calls | Raw request bodies; KeySweep text (the MicroDefend target URL persists — see What persists) |
| Log lines and audit rows carry the scan target as scheme://host — never path, query, or userinfo | Raw URLs in log lines, matched secret values, scanner output bodies |
| Audit rows: actor, counts, risk level, scan identifiers, duration, correlation | Credentials, payloads, and stack details in telemetry events |
Telemetry scrubbing
The security-telemetry pipeline drops credential, body, payload, and exception keys outright, scrubs bearer-like and long opaque values, and truncates strings — before any event leaves the process.
Honest caveat
Infrastructure failures can place stack traces in ordinary server logs. Stack traces are never sent to clients, but this page does not claim log contents are free of internal detail under failure conditions.
What persists
A completed scan's result record — the submitted target URL (path and query string included) plus fields parsed from the target's pages (metadata, headers, exposure findings), all pattern-redacted for credential-like strings — is persisted with owner attribution. Raw response bodies are not persisted. Validation rejects credential-bearing userinfo, but the rest of the URL is stored as submitted: do not scan a URL whose path, query, or fragment you would not want stored. KeySweep text is never persisted.
Data retention.
Enforced lifetimes
Scan concurrency slots expire after 180 seconds and are purged on acquisition. The JWKS cache lives 300 seconds. Issued credentials live at most 90 days. The credential display record is usable for up to 10 minutes, deleted on first view, and swept lazily after expiry.
Everything else
Retention policy not verified. No general log-retention, analytics-retention, or scan-result-retention policy is enforced in code or configuration. This page does not state a retention period because the system does not enforce one.
Analytics.
Pages
MCP web pages (including this one) emit a page-view event with an anonymized IP and page context. Binary³'s own analytics events send only the page's origin and path — every string field in every event is cut at the first query-string or fragment marker before sending, whatever the field is named and however it is nested — and the same sanitized location and referrer values are set as configuration defaults for the stream, so the provider's automatic session and engagement signals inherit them. The provider's optional measurement features attach their own event fields outside this codebase's control, but links and forms on these pages never carry credentials, so no such field carries secrets. Events carry a pseudonymous client identifier and never tool names, inputs, errors, or credentials.
Service
The MCP protocol service emits no product-analytics events.
Encryption — precisely what is claimed.
In transit
The public machine endpoint is served over HTTPS at mcp.binarycubed.com/mcp — TLS terminates at the deployment edge and is not enforced by application code. The public JWKS document is served over HTTPS with no-store, and JWKS retrieval in URL mode requires HTTPS — that check is enforced in code.
What is not claimed
This page makes no encryption-at-rest claim and no application-layer encryption claim beyond TLS in transit. Those properties depend on infrastructure configuration outside this repository, and this page does not assert what it cannot verify.
Rate limiting, quotas, and concurrency.
Transport limiter
At ingress, before authentication and dispatch: 120 requests per 60 seconds per client IP (taken from the rightmost forwarded-for entry). The limiter is an in-process, bounded map that fails closed if it saturates, returning HTTP 429 with Retry-After: 60. This is transport-abuse limiting — not DDoS protection, and not per-credential.
Product quota
Separate from the transport limiter, each accepted tool call consumes quota keyed by credential and plan tier. Exhausted or unavailable quota fails closed (rate_limit_exceeded, quota_unavailable). KeySweep validates its input before consuming quota, so a rejected KeySweep input costs nothing. MicroDefend consumes the allowance before target validation, so a rejected website scan still decrements the allowance.
Scan concurrency
MicroDefend scans acquire database-backed slots serialized with advisory locks. While locking holds, acquisition is serialized and the ceilings are enforced over unexpired slot rows: at most 3 concurrent scans per credential, 1 for anonymous callers, 8 globally, with a 30-second duplicate-target window and 180-second slot expiry. A scan that outlives its slot no longer counts toward the ceilings — expiry bounds abandonment, not scan duration. If advisory locking is unavailable, the checks still apply but acquisition is no longer serialized — a deliberate availability trade-off. Saturation returns 429 or 503 rather than queueing unboundedly.
Tenant and account isolation.
Mandatory tenant binding
Every verified credential carries a tenant identifier, propagated only after authentication. The service layer independently rejects missing or invalid tenant claims — there is no default tenant.
Cross-tenant denial
The per-call database binding check rejects a credential presented against any tenant other than its own, uniformly and fail-closed. Cross-tenant laundering is covered by the automated suite.
No cross-tenant data path
The MCP surface exposes no endpoint that reads stored per-tenant data — no result history, logs, or billing lookups. A call creates and returns the caller's own scan output; there is nothing to address another tenant's data with.
MCP security is not Axon.
Two capabilities
Binary³ MCP is an access layer that exposes selected Binary³ tools to agents. Axon is a separate Binary³ agent-security capability. They are different products with different execution paths.
No hidden enforcement
Axon is not the MCP authentication system, not MCP middleware, not a policy-enforcement layer over MCP calls, and not a prerequisite for MCP access. Every control described on this page lives in the MCP transport and service code itself. Explore Axon separately.
Compliance posture.
This page is a behavior statement, not a compliance artifact.
No certifications claimed
Binary³ does not claim SOC 2, ISO 27001, NIST-framework, HIPAA, PCI DSS, or FedRAMP certification or attestation for the MCP surface on this page, and nothing here should be read as a compliance mapping.
Evidence over adjectives
This page avoids unverifiable qualifiers. Where a control exists, it is described by its mechanism and its tests. Where it does not, the page says so — that is the entire standard applied here.
What is — and isn't —
independently qualified.
Current qualification state
Public JWKS surface: qualified. The public verification-key document and its discovery chain are production-qualified.
Authenticated MCP end-to-end: qualified. Qualified 2026-09-14 under the post-roadmap production qualification gate: real bearer authentication; signature, issuer, and expiration validation; per-tool entitlement and tenant binding; one successful authenticated call per public tool through the live machine endpoint; a passing negative-authentication matrix; and live revocation through the customer path.
Separate gates: bearer-only REST API authentication and MCP billing are independent qualification tracks and are not covered by any statement on this page.