# RPKI & routing security

**A verified DNSSEC chain and a pinned TLSA key are worthless if someone can just steal the route.**

BGP has no built-in authentication - any network can announce "I originate `2a04:2a01::/32`," and if enough peers believe it, traffic to every Whisper agent is vacuumed into the hijacker's network before it reaches us. It has happened to real prefixes: YouTube's 2008 hijack by Pakistan Telecom, the 2018 Amazon Route 53 hijack that redirected `myetherwallet.com` traffic to a phishing site. DNSSEC and DANE prove the *answer* is authentic; RPKI proves the *path to the server* wasn't stolen. Skip it and you've locked the front door while leaving the delivery route unguarded.

Whisper's whole address block (`2a04:2a01::/32`, announced by **AS219419**) is RPKI-signed, and the resolver can enforce that every destination it hands an agent is running on a route nobody hijacked. This page covers the actual mechanism - ROAs, origin validation, the RFCs behind it - and how to check it yourself with nothing but stock tools.

## The mechanism: Route Origin Authorizations (RFC 6482)

RPKI (Resource Public Key Infrastructure, **RFC 6480**) is a PKI overlaid on the number resources themselves. A Regional Internet Registry (RIPE NCC, ARIN, APNIC…) holds the root certificate for the address space it allocated. It issues a certificate to the resource holder - Whisper Security / viaGraph B.V. holds the certificate for `2a04:2a01::/32` - and that holder signs a **Route Origin Authorization (ROA, RFC 6482)**, a small signed object asserting three fields:

| Field | Whisper's ROA |
|---|---|
| Prefix | `2a04:2a01::/32` |
| Origin ASN | `AS219419` |
| Max length | `32` |

The **max length** caps how specific a sub-announcement is allowed to be, and Whisper's ROA sets it to `32` - exactly the prefix length itself. That means **only the exact `/32` is authorized**: any more-specific announcement - a `/33`, a `/48`, a `/64` - from anywhere on earth, *including AS219419 itself*, is **RPKI-invalid**. It's the tightest ROA there is. There's no authorized more-specific for a hijacker to hide a bogus route behind and win longest-prefix-match, and no room for our own kit to leak one either. (A holder *can* permit more-specifics by setting `maxLength` longer than the prefix; Whisper deliberately doesn't - the per-agent `/128` identities all live *inside* that single `/32` announcement, so there's never a reason to announce anything narrower.)

ROAs are published in the RIR's **RPKI repository** as signed CMS objects and fetched by relying-party software (Routinator, rpki-client, OctoRPKI) that any network operator runs. That software builds a **VRP set** (Validated ROA Payload: prefix + max-length + ASN tuples) and hands it to the router.

## Route Origin Validation (RFC 6811)

**RFC 6811** defines how a BGP speaker uses that VRP set against every route it receives. For each announced `(prefix, origin-ASN)` pair, RPKI-to-router (RFC 8210) delivers the VRPs to the router in real time, and the outcome is one of three states:

- **Valid** - a VRP exists that covers this exact prefix (or a less-specific covering it, within max-length) with a matching origin ASN.
- **Invalid** - a covering VRP exists, but either the origin ASN doesn't match (hijack) or the announced prefix is more specific than the max-length allows (leak/overclaim).
- **NotFound (Unknown)** - no ROA covers this prefix at all - most of the internet's legacy space, still unsigned.

RFC 6811 recommends: prefer valid, never propagate invalid to customers, and deprioritize (or drop, per local policy) invalid routes in best-path selection. Whisper's edge routers apply **origin validation on every eBGP session** - invalid routes are marked and stripped from the RIB, so a hijacked more-specific of our own `/32`, or a bogus origin ASN claiming it, never wins a path even transiently.

### Dual-homed, not single-homed

AS219419 peers with more than one upstream and exchanges routes at public internet exchanges rather than depending on a single transit provider - the MANRS baseline for resilience. If one upstream flaps, has an outage, or itself propagates a bad route, the other path keeps `2a04:2a01::/32` reachable. Combined with RPKI-invalid dropping, this is what "an address on land we own" (see [Verifiable identity](/docs/verifiable-identity)) actually cashes out to operationally: a route that's both cryptographically authorized and not a single point of failure.

## MANRS: the operational commitment, not just the crypto

RPKI signs *what should be true*; **MANRS** (Mutually Agreed Norms for Routing Security, manrs.org) is the community's checklist that operators actually *do* something with it. AS219419 is MANRS-compliant against all four network-operator actions:

1. **Filtering** - reject announcements (from customers/peers) that fail origin validation or don't match agreed prefixes.
2. **Anti-spoofing** - enforce source-address validation so packets can't leave the network with a forged source.
3. **Coordination** - publish current contact info (peeringdb, IRR/RPKI metadata) so abuse and routing incidents get resolved fast.
4. **Global validation** - publish accurate route-object/ROA information so *other* networks can validate against AS219419's own routes.

That last one is the point where RPKI and MANRS meet: it's not enough for Whisper to validate what it receives - the ROA for `2a04:2a01::/32` has to be correct and current so the *rest of the internet's* routers validate Whisper's own announcements as valid, not invalid or unknown.

## Checking it yourself - stock tools

No Whisper software required - RPKI state is public data, published for exactly this purpose.

```bash
# 1. Ask a public RPKI validator (RIPEstat) for the ROA and origin-validation verdict
curl -s "https://stat.ripe.net/data/rpki-validation/data.json?resource=AS219419&prefix=2a04:2a01::/32" | jq '.data'
# → { "status": "valid", "validator": "routinator", "validating_roas": [
#       { "origin": "219419", "prefix": "2a04:2a01::/32", "max_length": 32, "validity": "valid" } ] }

# 2. Cross-check the ASN's name, peers and announced prefixes with bgpview.io (or bgp.tools)
curl -s "https://api.bgpview.io/asn/219419" | jq '.data | {name, description_short, rir_allocation}'
curl -s "https://api.bgpview.io/asn/219419/prefixes" | jq '.data.ipv6_prefixes[].prefix'
whois -h whois.radb.net '!6as219419'           # IPv6 IRR route objects for the origin AS

# 3. Grep the ROA out of a public, current VRP export (Cloudflare's rpki-client feed)
curl -s "https://rpki.cloudflare.com/rpki.json" \
  | jq '.roas[] | select(.asn=="AS219419")'
#   → { "prefix": "2a04:2a01::/32", "maxLength": 32, "asn": "AS219419", "ta": "ripe" }
```

`stat.ripe.net`'s `rpki-validation` endpoint runs the exact RFC 6811 algorithm against the live VRP set and gives you the same valid/invalid/unknown verdict a router would compute - no BGP session of your own required.

## Resolver enforcement: the direction, not yet the destination

Checking the *route to Whisper* is public and stock-tools-only, as above, and works today. The natural next step - making the **resolver itself** refuse to hand an agent a destination whose *own* route is currently RPKI-invalid, so a hijack of somebody else's prefix never becomes an answer your agent acts on - is the shape [graph-first policy](/docs/resolver) is built toward. It isn't there yet: `CALL whisper.agents({op:'policy', routing:'drop-hijacked'})` is accepted and answers `ok:true`, but a follow-up read of the stored policy shows no `routing` key at all, checked live against the control plane today. Sending it is a no-op, not an error, so don't build on it until this page says otherwise.

What *is* live on the resolver today is category policy - Tor exits, bulletproof hosting, newly-registered domains - the same mechanism [Graph-first resolution](/docs/resolver) documents:

```bash
whisper policy --block tor-exit
```

Combine that with checking a specific destination's own route validity yourself, on demand, using the stock-tools recipe above - the two compose into the same end-to-end trust story (a hijacked route ruled out, a malicious category ruled out) even before routing is a policy toggle in its own right.

> RPKI only signs the origin ASN, not the AS path - it stops "wrong network claims this prefix" hijacks (the overwhelming majority of real incidents) but not a path-manipulation attack from a transit AS already on a legitimate path. Full path security is what BGPsec (RFC 8205) targets; it isn't yet deployed at internet scale, and Whisper doesn't claim it does more than RFC 6811 origin validation.

---

**Next:** [Verifiable identity](/docs/verifiable-identity) - how the address itself, not just the route to it, is provable · [Trustless verification](/docs/verify) - chain-of-custody checks (DANE, DNSSEC, transparency) that compose with RPKI for an end-to-end trust story.
