Safeguard
Supply Chain Security•

ASPA Explained: RPKI Route Leak Detection and How to Deploy It

ASPA lets a network sign the list of its transit providers in the RPKI so routers can reject leaked AS paths. How it works, its limits and how to deploy it.

Safeguard Security Team
39 min read

ASPA (Autonomous System Provider Authorization) is an RPKI signed object in which a network lists the autonomous systems it buys transit from, so that routers elsewhere can check whether a BGP AS path climbs up and down the customer and provider hierarchy in a way that makes sense. It catches many route leaks and some forged paths that route origin validation cannot see. As of 25 October 2026 both IETF ASPA documents are still Internet-Drafts, not RFCs, but two RIRs already let you publish ASPAs and several open source validators and routing daemons can use them.

Route origin validation (ROV) asks whether an AS may originate a prefix. ASPA asks whether the path the route took could come from real business relationships. This post goes one level deeper than our explainers on BGP, on what ROV does not stop and on route leaks versus hijacks: the object format, the algorithm with worked numbers, how ASPA fits with BGP roles, which open source software supports it, and a deployment plan that does not drop valid traffic.

Key takeaways

  • An ASPA is signed by a customer AS and lists its provider ASes. Peers and customers must not be listed. A network with no transit providers publishes an ASPA containing only AS 0.
  • Routers verify a received AS_PATH against all published ASPAs. A valid path rises from the origin through customer to provider hops, crosses at most one peering link at the top, then only descends. A path with a "valley" in it is a leak.
  • There are two algorithms. Upstream verification applies to routes from customers and lateral peers and allows only a climbing path. Downstream verification applies to routes from providers and allows one climb and one descent.
  • Results are Valid, Invalid or Unknown. The draft recommends treating Invalid as ineligible and treating Unknown the same as Valid. Unknown is common while deployment is partial.
  • ASPA protects others from your neighbors' mistakes. The BGP role and Only to Customer (OTC) mechanism from RFC 9234 stops your own AS from leaking. Use both.
  • Both IETF documents, and the RTR version 2 protocol that carries ASPA data to routers, are drafts at "WG Consensus: Waiting for Write-Up" as of 25 October 2026.
  • ARIN and the RIPE NCC document ASPA signing; rpki-client, Routinator, Krill, OpenBGPD, BIRD and FRRouting document ASPA support.
  • The most damaging mistake is a missing provider, especially a backup or DDoS scrubbing provider. It turns valid routes through that provider into Invalid as other networks enforce.

What problem does ASPA solve that route origin validation does not?

BGP has no built in idea of who pays whom, so the rules that keep routing sane live in each operator's export policy. Most networks follow one rule set, often called the Gao and Rexford model: routes from a customer may go to everyone; routes from a provider or a lateral peer may go only to customers. Break that rule and you have a route leak. RFC 7908 (June 2016) defines a leak as the propagation of routing announcements beyond their intended scope and sorts leaks into six types:

RFC 7908 typeWhat happensExample cited in RFC 7908
Type 1, hairpin turn with full prefixA multihomed customer learns a route from one provider and passes it to another providerThe June 2015 leak of about 179,000 prefixes by a large Malaysian operator, which a transit network accepted and propagated
Type 2, lateral ISP to ISP to ISPA network passes a route from one lateral peer to another lateral peerDescribed as common in peering disputes and misconfigured peering
Type 3, provider routes leaked to a peerA network sends routes it learned from its transit provider to a lateral peer
Type 4, peer routes leaked to a providerA network sends routes it learned from a lateral peer up to its transit providerSeveral incidents in Europe and Asia cited in the RFC
Type 5, re-originationA network re-announces a learned prefix as if it originated it, while traffic still reaches the real origin
Type 6, internal prefixes and more specificsA network leaks internal routes or more specific prefixes it should have kept inside

Route origin validation sees none of the first four types. In a Type 1 leak the origin AS is correct and its Route Origin Authorization (ROA) matches, so the ROV check passes. The damage is in the middle of the path: traffic now flows through a customer network that was never meant to carry transit.

ROV also misses forged origins. If an attacker announces a prefix with a fake path ending in the victim's own AS number, the origin check passes. The verification draft says ROV can prevent accidental hijacks, but malicious forged-origin hijacks can still occur; RFC 9319 narrows that surface with tight maxLength settings but cannot verify the path.

ASPA fills that gap. Each network publishes who its providers are, so any router can test whether every hop in a path is plausible. A leak shows up as a "valley": a route that goes down to a customer and back up to another provider, or crosses more than one peering link. The draft describes the result as route leak detection and mitigation plus, to some degree, protection against forged-origin and forged-path-segment hijacks. It also notes this works without support from the source of the anomaly: the leaker does not have to deploy anything.

What is an ASPA object?

An ASPA is a Cryptographic Message Syntax (CMS) signed object that follows the RFC 6488 template for RPKI signed objects, the same family as ROAs and manifests. It is issued under the RPKI certificate hierarchy that RFC 6480 describes: the RIRs act as trust anchors, resource holders receive certificates for their address space and AS numbers, and signed objects are validated back to a trust anchor by relying party software.

The current profile, draft-ietf-sidrops-aspa-profile revision 29 (July 2026), defines the content in a few lines of ASN.1. In plain terms:

FieldMeaningRules from the profile draft
versionFormat versionMust be 1 and must be explicitly encoded
customerASIDThe AS that signs the object, called the Customer AS (CAS)A positive integer; must match the single AS number in the end entity certificate
providersThe set of Provider ASes (SPAS) the customer authorizesAt least one entry, in ascending numerical order, no duplicates, must not contain the customer's own AS number
AS 0Means "I have no providers"May appear only as the single entry in the list

The content type has the object identifier 1.2.840.113549.1.9.16.1.49 (id-ct-ASPA). Repository files commonly use the .asa extension; the Routinator documentation's example shows a source URI ending in AS64496.asa.

A few profile details matter in practice:

  • What counts as a provider. A network that may send its customer routes from any direction and send the customer's routes in any direction. That is transit. Peers and customers are not providers.
  • Route servers. Transparent exchange route servers (RFC 7947) do not add their AS to the path and need not be listed. A non-transparent route server must be listed.
  • One object per customer AS. Multiple objects are merged into a union set, but splitting invites race conditions during updates. When merging, AS 0 is dropped if any real provider appears.
  • Certificate constraints. The end entity certificate must carry exactly one AS identifier and no IP address extension; a fresh key pair per object is recommended.
  • Size limits. RTR version 2 can carry at most 16,380 providers in one ASPA message. The profile recommends relying parties cap the union between 4,000 and 10,000 providers and, above the cap, treat all of that customer's ASPAs as invalid rather than emit a partial list.

What is the standards status?

On 25 October 2026 the IETF datatracker shows:

DocumentRevisionLast updatedState
draft-ietf-sidrops-aspa-profile, "A Profile for Autonomous System Provider Authorization"293 August 2026 (draft dated July 2026, expires 30 January 2027)Active Internet-Draft; IETF stream state "WG Consensus: Waiting for Write-Up"; intended status Proposed Standard
draft-ietf-sidrops-aspa-verification, "BGP AS_PATH Verification Based on Autonomous System Provider Authorization (ASPA) Objects"2916 October 2026 (expires 19 April 2027)Active Internet-Draft; "WG Consensus: Waiting for Write-Up"; intended status Proposed Standard
draft-ietf-sidrops-8210bis, "The RPKI to Router Protocol, Version 2"2713 August 2026Active Internet-Draft; "WG Consensus: Waiting for Write-Up"

"WG Consensus: Waiting for Write-Up" means the SIDROPS working group has reached consensus and the document is waiting for the shepherd write-up before it goes to the IESG. It is not an RFC yet. The Krill documentation says major changes are not expected but router and validator support may still be lacking; the RIPE NCC calls ASPA an emerging standard that is ready for use in signing.

How does upstream and downstream path verification work?

The verification draft builds everything from one simple function and two ramps.

The provider authorization function

For any pair of ASes x and y, the router asks: is y an attested provider of x? It looks up the union of provider sets for customer x and returns one of three answers:

  • Provider+ if x has a valid ASPA and y is in it. The plus sign means y is either a provider or a non-transparent route server.
  • Not Provider+ if x has a valid ASPA and y is not in it.
  • No Attestation if x has no valid ASPA at all.

That third answer is why partial deployment produces Unknown rather than Invalid. A router cannot call a hop a leak if the customer in that hop never said who its providers are.

Up-ramps, down-ramps and the apex

Take the AS path after removing consecutive duplicates (prepends). Number it from the origin: AS(1) is the origin, AS(N) is the neighbor that sent the route. The receiving router is AS(N+1).

A legitimate path has this shape:

  1. An up-ramp from the origin: each hop goes from a customer to its provider.
  2. At most one lateral step at the top, a peering link or a route server.
  3. A down-ramp toward the receiver: each hop goes from a provider to its customer.

The draft's rule is short. If the apex of the up-ramp and the apex of the down-ramp are more than one hop apart, the path is invalid. Equivalently, if the combined length of the up-ramp and the down-ramp is at least N, the path is leak free.

Because some ASes have no ASPA, the router cannot always know the exact ramp lengths. So it computes two bounds for each ramp:

  • max_up_ramp: the first position from the origin where the next hop is "Not Provider+". If none, N.
  • min_up_ramp: the first position where the next hop is "No Attestation" or "Not Provider+". If none, N.
  • max_down_ramp and min_down_ramp: the same idea counted from the neighbor end, computed as N minus J plus 1, where J is the highest position whose hop toward the origin is "Not Provider+" (for the max) or "No Attestation" or "Not Provider+" (for the min).

Then:

  • If max_up_ramp plus max_down_ramp is less than N, the path is Invalid. Even the most generous reading cannot make it leak free.
  • Otherwise, if min_up_ramp plus min_down_ramp is less than N, the result is Unknown. Missing ASPAs leave a gap.
  • Otherwise the path is Valid.

Which algorithm applies to which session

Route received fromAlgorithm in the draftWhat the path may look like
A customerUpstream (section 5.5)Only an up-ramp. Down-ramp lengths are set to 0
A lateral peer, or a route server or RS-client in either directionUpstreamOnly an up-ramp
A providerDownstream (section 5.6)An up-ramp, an optional lateral step, then a down-ramp

Both algorithms first run three sanity checks: an empty AS_PATH is Invalid; a path whose most recent AS does not match the neighbor's AS is Invalid (with an exception for an RS-client receiving from a transparent route server in the upstream case); a path containing an AS_SET is Invalid. RFC 9774 already requires routes with AS_SET to be treated as withdrawn, and the draft says these checks must run before ASPA verification if the router implements them.

The draft applies the procedures only to IPv4 and IPv6 unicast (AFI 1 and 2, SAFI 1) by default, only on eBGP sessions at the edge, and only on four-octet AS capable speakers.

Worked example 1: a hairpin leak caught by upstream verification

All AS numbers here come from the documentation range so they cannot collide with real networks.

  • AS64496 originates 203.0.113.0/24. Its ASPA lists one provider: AS64501.
  • AS64501 is a regional transit network. Its ASPA lists one provider: AS64505.
  • AS64510 is a small enterprise that buys transit from both AS64501 and AS64502. Its ASPA lists AS64501 and AS64502.
  • AS64502 is the second transit provider and it enforces ASPA on customer sessions.

AS64510 misconfigures its export policy and sends everything it learns from AS64501 to AS64502. This is a Type 1 leak. AS64502 receives 203.0.113.0/24 from its customer AS64510 with the path 64510 64501 64496.

AS64502 runs the upstream algorithm because the route came from a customer. N is 3. AS(1) is 64496, AS(2) is 64501, AS(3) is 64510.

StepPair checkedLookupResult
1Is 64501 a provider of 64496?ASPA of 64496 lists 64501Provider+
2Is 64510 a provider of 64501?ASPA of 64501 lists only 64505Not Provider+

The first "Not Provider+" sits at position 2, so max_up_ramp is 2. The upstream algorithm sets both down-ramp values to 0. The check "max_up_ramp is less than N" is 2 compared with 3, so the outcome is Invalid. Following the draft's recommended policy, AS64502 marks the route ineligible, keeps it in the Adj-RIB-In for later re-evaluation, and the leak stops at the first hop.

Notice whose ASPA did the work. It was the ASPA of AS64501, the network the route was leaked from, not the ASPA of the leaker. That matters for the next case.

Worked example 2: the same leak returning Unknown

Change one fact: AS64501 has not published an ASPA.

StepPair checkedLookupResult
1Is 64501 a provider of 64496?ASPA of 64496 lists 64501Provider+
2Is 64510 a provider of 64501?No ASPA for 64501No Attestation

There is no "Not Provider+" anywhere, so max_up_ramp is N, which is 3. The first "No Attestation" sits at position 2, so min_up_ramp is 2. The invalid test (3 less than 3) fails. The unknown test (2 less than 3) succeeds. The outcome is Unknown, and under the recommended policy Unknown gets the same preference as Valid. The leak is not caught.

The lesson for transit networks is direct. Your own ASPA protects your customers' routes and other people's routes that pass through you. The RIPE NCC page makes the same point from the other side: the more AS holders sign their ASPA objects, the harder it becomes to spoof a path that includes your AS.

Worked example 3: a downstream path, valid and then leaked

Now look from a customer's side, which uses the more permissive downstream algorithm.

  • AS64496 (origin) lists provider AS64501.
  • AS64501 lists provider AS64505.
  • AS64505 and AS64506 are large transit free networks that peer with each other. Each publishes an AS 0 ASPA: "we have no providers".
  • AS64502 lists provider AS64506.
  • AS64520, the verifier, buys transit from AS64502 and receives the route from it.

The legitimate path at AS64520 is 64502 64506 64505 64501 64496. N is 5.

Up-ramp from the origin:

PairLookupResult
(64496, 64501)64496 lists 64501Provider+
(64501, 64505)64501 lists 64505Provider+
(64505, 64506)64505 has AS 0Not Provider+

So max_up_ramp and min_up_ramp are both 3.

Down-ramp from the neighbor end:

PairLookupResult
(64502, 64506), is 64506 a provider of 64502?64502 lists 64506Provider+
(64506, 64505), is 64505 a provider of 64506?64506 has AS 0Not Provider+

The highest position with "Not Provider+" is J equal to 4, so max_down_ramp is 5 minus 4 plus 1, which is 2. The minimum is also 2. The sums are 3 plus 2, which is 5, for both bounds. Five is not less than N, so the path is Valid. It climbs two hops, crosses one peering link at the top (64505 to 64506), and descends two hops.

Now a leak. AS64507 is a customer of both AS64506 and AS64508. It leaks the route it learned from AS64506 up to AS64508, and AS64508 passes it down to its customer AS64520. The path at AS64520 is 64508 64507 64506 64505 64501 64496, so N is 6. AS64507 lists providers AS64506 and AS64508. AS64508 lists its own provider, AS64509.

The up-ramp is unchanged: max and min are 3. On the down-ramp, the pair (64508, 64507) asks whether 64507 is a provider of 64508. AS64508's ASPA lists only 64509, so the answer is "Not Provider+" at position 6. That gives max_down_ramp of 6 minus 6 plus 1, which is 1. The sum 3 plus 1 is 4, less than 6, so the path is Invalid. The valley at AS64507 is visible because AS64508 published an honest ASPA.

If AS64508 had published nothing, max_down_ramp would be 3 (from the AS 0 hop at position 4) and min_down_ramp 1, so the result would be Unknown and the leak would pass.

Cases ASPA does not catch by design

  • Your own leaks. The verification draft says ASPA detects leaks created by ASes earlier in the path but cannot stop the local AS from originating a leak toward its neighbor. That is the job of RFC 9234 roles and OTC.
  • A malicious provider. The draft's security section admits a provider can forge paths for its direct or indirect customers or manipulate paths it sends to them, and ASPA may not detect it. The draft considers this unrealistic given contracts, and suggests the customer can drop the provider and remove it from the ASPA.
  • Prepend games. ASPA cannot detect added or removed repeats of an AS number. This does not affect leak detection but can matter for traffic engineering disputes.
  • Complex relationships. Mixed provider and peer roles in one session can hide leaks; the draft suggests splitting sessions, per prefix verification, or falling back to the downstream algorithm.
  • Forged paths through networks with no ASPA. Any hop whose customer has not published returns No Attestation, so a forger who builds a path through such hops gets Unknown, not Invalid.

How does ASPA relate to RFC 7908 and RFC 9234?

RFC 7908 defines the problem. RFC 9234, published as a Standards Track RFC in May 2022, and ASPA are two of the answers, and they cover different ends of the same problem.

RFC 9234 adds two things to BGP:

  1. The BGP Role capability (capability code 9) sent in the OPEN message. Each side declares its role on this session: Provider (0), RS (1), RS-Client (2), Customer (3) or Peer (4). Roles must pair up correctly (Provider with Customer, RS with RS-Client, Peer with Peer). A mismatch tears the session down with the Role Mismatch notification (code 2, subcode 11). In "strict mode" a missing capability from the neighbor also rejects the session.
  2. The Only to Customer (OTC) attribute, an optional transitive path attribute with type code 35 and a four octet value holding an AS number. When a route is sent to a customer, a peer or an RS-client, OTC is added with the sender's AS number. A route that carries OTC must never be sent to a provider, a peer or a route server. On receipt, a route with OTC arriving from a customer or RS-client is a leak and is ineligible, and a route from a peer with an OTC value other than the peer's AS number is also a leak.

OTC travels in the update and needs neighbors that both run it. ASPA lives in the RPKI and can judge a path even when the leaker runs nothing new.

The verification draft links them twice. Section 6.3 recommends BGP roles because the role tells the router whether to run the upstream or downstream algorithm. Section 8.4 says ASPA "lacks the ability to prevent the local AS from initiating a route leak" and recommends OTC alongside it. FRRouting instead lets you state the ASPA direction in a route map, because setting a role there also enables OTC handling, which some operators may not want during an ASPA rollout.

Comparison: ROV, ASPA, BGP roles and OTC, and BGPsec

MechanismWhat it checksWhere the data livesWhat you need to deployStatus on 25 October 2026
ROV with ROAsThat the origin AS may announce the prefix and the prefix length is within maxLengthRPKI signed ROAs, delivered to routers over RTRROAs for your prefixes; a relying party; routers that drop InvalidStandards Track RFCs (6811, 9582 and others); widely deployed
ASPAThat each hop in the AS path is a plausible customer to provider or peering step; catches valleysRPKI signed ASPAs, delivered over RTR version 2An ASPA for each of your ASes; a validator with ASPA support; routers with ASPA verification and RTR version 2IETF drafts at WG consensus; RIR signing available at ARIN and the RIPE NCC; implementations in open source validators and daemons
BGP roles and OTC (RFC 9234)That roles on a session agree, and that a route once sent "down" or sideways never goes back up or sidewaysConfiguration on each session plus an attribute carried in BGP updatesRole configuration on every eBGP session; daemon supportStandards Track RFC since May 2022
BGPsec (RFC 8205)That the update really traversed the ASes in the signed path, hop by hopRouter keys in the RPKI plus signatures in every updateRouter key certificates; every AS on the path must sign; more CPU and memoryStandards Track RFC; very limited deployment, according to the Routinator documentation

Two lines in the verification draft are worth quoting to settle a common confusion. On BGPsec, the draft says it "does not detect route leaks (valley-free violations)" and that BGPsec and ASPA are complementary. BGPsec proves the path was not altered. ASPA asks whether an unaltered path should ever have existed.

Which open source software supports ASPA?

Version claims below come from each project's documentation or the verification draft's implementation status section, which the draft says is self reported. Confirm on release notes before you plan.

SoftwareRole in the chainASPA support as documented
rpki-client (OpenBSD project, portable releases)Relying party: fetches and validates the RPKIThe manual says it produces Validated ROA Payloads, BGPsec router keys and Validated ASPA Payloads (VAPs). Its BIRD output is for BIRD 2.16 and up, with tables ROAS4, ROAS6 and ASPAS. The project site lists rpki-client 9.9, released 22 August 2026
Routinator (NLnet Labs)Relying party and RTR serverASPA processing is enabled with --enable-aspa or enable-aspa = true in the config; ASPA appears in RTR output and in the json and jsonext formats. The docs mark the feature as new in version 0.13.0
Krill (NLnet Labs)Certification authority software for delegated RPKIManages ASPA configurations; the docs say ASPA objects can currently be managed only through the command line client
OpenBGPDBGP daemonThe draft lists ASPA verification in version 7.8 and higher. bgpd.conf documents aspa-set, the role per neighbor (required for ASPA verification), avs valid, unknown, invalid filter matching, and an RTR min-version that must be 2 for ASPA
BIRDBGP daemonThe BIRD 2 documentation says its RPKI protocol, since RTR version 2, receives ASPAs into an ASPA table; filters call aspa_check_upstream, aspa_check_downstream or aspa_check(table, bgp_path, is_upstream), which return ASPA_VALID, ASPA_INVALID or ASPA_UNKNOWN
FRRoutingBGP daemonThe current FRR documentation describes match aspa upstream and match aspa downstream in route maps, show rpki aspa, and notes ASPA is a build time feature that needs an RTR library with ASPA support and RTR version 2. Its docs put route server sessions under downstream, while the verification draft uses upstream for route server sessions

We have not tested these versions for this post; treat the table as a map, not a compatibility matrix.

Step by step: publish, validate and test ASPA before you enforce

The plan below has five stages. The first three are safe on a production network because they change nothing about which routes your routers accept. The last two are where mistakes cost traffic.

Stage 1: inventory your real providers

Before you sign anything, write down every network that sells you transit, per AS you hold.

  1. List every eBGP session on every edge router with the neighbor AS and the relationship: provider, customer, peer, route server or complex. Cover IPv4 and IPv6; the draft requires listing a provider even if it carries only one address family.
  2. Add standby providers: backup transit, a DDoS mitigation service, an emergency provider. The draft recommends adding them in advance, because adding them during an incident races global ASPA distribution.
  3. Add non-transparent route servers (their AS appears in paths you receive from them). Exclude lateral peers and customers, as the RIPE NCC page states.
  4. If a provider is migrating AS numbers, include both the new and legacy AS, per the draft.

Then check what the world sees: in a public route collector or looking glass, list the AS directly to the left of yours in every path. Any AS there that is not on your list is a forgotten provider or a leak already happening.

Stage 2: create the ASPA at your RIR or in your own CA

What your RIR offers decides how you publish:

  • ARIN. ARIN's documentation describes creating an ASPA in ARIN Online under Routing Security, Manage RPKI, ASPAs, Create ASPA, and also through its RPKI RESTful API with an API key. ARIN says one ASPA may contain only one customer AS, so organizations with several AS numbers need one per AS. Modifications take effect in its database immediately and appear in the public repository within 24 hours.
  • RIPE NCC. The RIPE NCC's ASPA page says ASPA is considered ready for use in signing and points members to its documentation and a RIPE 91 presentation. It warns that its RPKI dashboard gives no hints about which providers are seen for your AS in BGP, so the inventory is your job.
  • APNIC. APNIC's resource certification page describes ASPA validation with the upstream and downstream algorithms and advises that ROAs and ASPAs match your real BGP announcements. Check MyAPNIC for the current create workflow.
  • LACNIC and AFRINIC. We did not confirm ASPA support for these RIRs for this post. Ask them directly.
  • Delegated CA. If you run your own certification authority with Krill, the Krill documentation describes ASPA configurations managed through its command line client. Krill creates the object under each parent that delegated the customer AS to you.

Whichever route you choose, put every provider for one customer AS in a single object, as both drafts recommend. If you have no transit at all, for example because you only peer, publish an AS 0 ASPA. The verification draft defines that as a statement that you have no providers and are not a client of any non-transparent route server.

Stage 3: confirm the object with a relying party

ARIN's documentation says that to verify an ASPA is active you need an RPKI validator. Run one, and check that your object appears with the right providers.

With rpki-client, run a normal validation pass and inspect the JSON output in the output directory. The manual describes the Validated ASPA Payloads it produces.

# rpki-client: run a validation pass and write outputs, including JSON
doas rpki-client -j /var/db/rpki-client
# then look for your customer AS among the ASPA entries in the json output

With Routinator, enable ASPA and print the validated dataset in json format.

# Routinator: include ASPA objects in the validated output
routinator --enable-aspa vrps --format json > vrps.json
# confirm your customer AS and its providers appear in the "aspas" array
python3 -c "import json;d=json.load(open('vrps.json'));print([a for a in d.get('aspas',[]) if a.get('customer')=='AS64510'])"

Replace AS64510 with your own AS number. Exact output field names can differ between releases and output formats; check them against your version's documentation. If the object is missing, check that your CA publication point is reachable and wait for the next repository refresh. If the providers are wrong, fix the object at the CA, not in the validator.

Stage 4: run verification in monitor only mode

Feed ASPA data to routers over RTR version 2 and tag or log results without rejecting anything. Leave this running for weeks, not hours. You are looking for Invalid results on routes you know are legitimate, which almost always mean someone forgot a provider.

OpenBGPD. Set the role per neighbor, require RTR version 2 on the RTR session, and match on the ASPA validation state. The bgpd.conf manual documents these keywords; the sketch below logs and tags rather than drops.

# /etc/bgpd.conf (sketch, adapt to your setup)
rtr 192.0.2.10 {
        port 3323
        min-version 2
}

neighbor 198.51.100.1 {
        remote-as 64510
        descr "customer-64510"
        role provider          # our local role on this session
}

neighbor 203.0.113.1 {
        remote-as 64505
        descr "transit-64505"
        role customer
}

# monitor phase: mark ASPA invalid routes with a large community, do not drop
match from ebgp avs invalid set large-community 64502:1:1

Check the manual for your release before using any keyword. The role keyword in OpenBGPD describes your local role on that session, so on a session to a customer your role is provider.

FRRouting. The FRR documentation gives a complete example. In monitor mode, set a community or lower local preference instead of denying:

rpki
 rpki cache tcp 192.0.2.10 3323 preference 1
exit
!
router bgp 64502
 neighbor 198.51.100.1 remote-as 64510
 neighbor 203.0.113.1 remote-as 64505
 address-family ipv4 unicast
  neighbor 198.51.100.1 soft-reconfiguration inbound
  neighbor 198.51.100.1 route-map FROM-CUSTOMER in
  neighbor 203.0.113.1 soft-reconfiguration inbound
  neighbor 203.0.113.1 route-map FROM-TRANSIT in
 exit-address-family
!
route-map FROM-CUSTOMER permit 10
 match aspa upstream invalid
 set community 64502:666 additive
route-map FROM-CUSTOMER permit 20
!
route-map FROM-TRANSIT permit 10
 match aspa downstream invalid
 set community 64502:667 additive
route-map FROM-TRANSIT permit 20

Then inspect results with the show commands the FRR docs list:

show rpki aspa
show bgp ipv4 unicast aspa upstream invalid
show bgp ipv4 unicast 203.0.113.0/24

The FRR docs warn that new ASPA data only re-evaluates routes already received if soft-reconfiguration inbound is enabled on the peer, and that a build without ASPA support in the RTR library accepts match aspa but never matches. Check the configure output for ASPA support before trusting a quiet log.

BIRD. Add an aspa channel with its own table to the rpki protocol. In each eBGP import filter call aspa_check(table, bgp_path, true) on customer and peer sessions and aspa_check(table, bgp_path, false) on provider sessions, and in the monitor phase only log or tag ASPA_INVALID. The BIRD docs note the check does not include the local AS and returns ASPA_INVALID for an empty path.

Stage 5: enforce, one session class at a time

When the monitor logs show no false Invalids for a sustained period, enforce. A cautious order:

  1. Customer sessions first, upstream algorithm. Leaks enter here most often, and an Invalid is least likely to be legitimate.
  2. Peer and route server sessions next, upstream algorithm. Peers send only their customer cone, so a valley is a leak.
  3. Provider sessions last, downstream algorithm. Lower local preference for Invalid first, as the FRR documentation example does, then reject.

Follow the draft's policy: Invalid is ineligible but stays in the Adj-RIB-In for re-evaluation; Unknown is treated like Valid. Give your operations center a runbook for "customer reports unreachable prefix" that starts with checking ASPA state.

What are the limits of ASPA?

  • It needs other people's ASPAs. As worked examples 2 and 3 showed, the leak is caught only if the right customer in the path has published. In early deployment many paths come back Unknown, and Unknown is accepted.
  • It needs routers to enforce. Your ASPA protects your routes in other people's routers, not in yours.
  • A missing provider causes real outages. The verification draft's security section says that if a provider is missing from an ASPA, routes may become falsely Invalid. The RIPE NCC page warns that forgetting a provider can lead to the rejection of routes you send through it. The more networks enforce, the bigger the blast radius of a stale object.
  • Extra providers weaken it. Listing a network that is not really your provider reduces leak detection, per the same section.
  • Address family incongruence. One ASPA covers IPv4 and IPv6, so a provider for only one family makes checks for the other more permissive. The draft accepts this to avoid false Invalids.
  • Maturity. The documents and RTR version 2 are drafts, and router support depends on build options and versions.
  • Data path is not checked. Like all control plane checks, ASPA says nothing about where packets actually go after a route is accepted.

Common mistakes

  • Listing peers as providers. A settlement free peer is not a provider. Listing it makes leaks through that peer look legitimate, which is exactly what ASPA exists to catch. The RIPE NCC is explicit that lateral peers and customers must not be included.
  • Forgetting a backup transit or a DDoS scrubbing provider. These only announce your routes when something is already going wrong. If they are missing from your ASPA, the day you fail over is the day enforcing networks reject the backup path. Add them in advance, as the draft recommends.
  • Enforcing before monitoring. Turning on reject for Invalid on day one turns every stale ASPA in the world into your outage. Monitor first, enforce by session class, start with customers.
  • Treating ASPA as BGPsec. ASPA does not sign updates and does not prove a path was traversed. BGPsec does not detect leaks. They answer different questions.
  • Splitting one customer AS across several ASPAs, or forgetting an IPv6 only provider or a non-transparent route server.
  • Getting the direction wrong. Running the upstream algorithm on a provider session will flag ordinary valid paths as Invalid. Derive the direction from the real relationship, through BGP roles or explicit configuration.
  • Assuming a quiet log means it works. A daemon built without ASPA support or an RTR session stuck at version 1 will report nothing. Confirm that ASPA data actually reached the router with a show command before you trust silence.
  • Not watching your customers' ASPAs. The draft says providers should monitor that their AS appears in their customers' ASPAs. A customer that forgets you creates an outage for both of you.

FAQ

Is ASPA an RFC yet?

Not as of 25 October 2026. The profile and the verification documents are IETF Internet-Drafts (revision 29 each) at "WG Consensus: Waiting for Write-Up", with an intended status of Proposed Standard. Check the IETF datatracker for the current state.

What is the difference between ASPA and ROA?

A ROA, signed by a prefix holder, says which AS may originate a prefix. An ASPA, signed by an AS holder, says which ASes are its providers. ROV checks the last AS in the path; ASPA checks the hops in between. The verification draft says using both together can detect accidental leaks and malicious path manipulation.

Does ASPA stop BGP hijacks?

Partly. ASPA's main job is route leaks. It also makes forged-origin and forged-path-segment hijacks harder, because a forged path must still look like a plausible chain of customer and provider links. A forgery through networks without ASPAs or by a provider can still pass.

Should I list my peers in my ASPA?

No. List only providers, plus any non-transparent route servers at exchanges you use. Listing peers weakens leak detection for everyone.

What is an AS0 ASPA?

An ASPA whose provider list contains only AS 0. It states that the AS has no transit providers and is not a client of a non-transparent route server. Transit free networks publish one so that any path showing them as someone's customer can be flagged.

Does my router need RTR version 2 for ASPA?

Yes, in the implementations documented here. The FRRouting documentation says ASPA records require RTR protocol version 2, and the OpenBGPD manual says a minimum RTR version of 2 is required for ASPA. RTR version 2 is itself still an IETF draft.

What happens if I forget a provider in my ASPA?

Routes you send through that provider can be judged Invalid by networks that enforce ASPA and may be dropped. Fix the object at your CA, then allow time for the repository and every relying party to refresh.

How do ASPA and the Only to Customer attribute work together?

OTC, from RFC 9234, stops your own AS from leaking and lets compliant neighbors spot leaks a few hops away. ASPA lets any enforcing router spot leaks created anywhere earlier in the path, without the leaker running anything. The verification draft recommends deploying both.

Where Safeguard fits, honestly

Safeguard does not validate routes, publish ASPAs, monitor BGP or run on routers. The fit is indirect: the validators, CA software and routing daemons above are open source software you build, package and run, often in container images, and they carry dependencies and get security fixes. The rpki-client site currently says the project's continuity is at risk and asks for donations, a reminder that small teams maintain this software. Knowing which versions you run, and what sits inside the images you deploy them in, is ordinary supply chain hygiene.

A router fleet that suddenly needs RTR version 2 also means rebuilding or upgrading the images and packages that carry your validator and daemons, and every rebuild pulls open source dependencies again. The section below is our standard guidance for keeping those dependencies patched without waiting on upstream.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session. It opens the interactive terminal, takes a request to fix a lodash CVE in a repository, reads the finding and the advisory, and asks before any command that changes something while it edits package.json, installs and runs the tests. The same flow applies to the build repositories and container definitions for your validator and routing daemon images: scan them, see which components carry known vulnerabilities, and have the change prepared for review.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with a device code and runs a scan from the terminal, which suits validator and daemon builds kept on internal hosts.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. If your team already asks an assistant questions about its infrastructure code, this shows how to give it read access to your Safeguard findings without handing over everything.

Click through it at your own pace, or open it full screen.

To try it on your own builds, download Safeguard and follow the CLI documentation.

Quick check

A customer sends you a route with the path 64510 64501 64496. AS64501's ASPA does not list AS64510. What does upstream verification return?

Invalid. The hop from 64501 up to 64510 is "Not Provider+", so the maximum up-ramp is 2, which is less than the path length of 3. It is a hairpin leak.

Should a network add its settlement free peers to its ASPA?

No. An ASPA lists only providers and non-transparent route servers. Listing peers makes leaks through those peers look legitimate.

Sources

Related reading: BGP explained, what RPKI route origin validation does not stop and BGP route leak vs hijack.

Last reviewed: 25 October 2026. ASPA is still an IETF draft and implementations change quickly; check the IETF datatracker, your RIR and your software's release notes before relying on a specific behavior.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.