npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@atlasauth/pca-spiffe

v0.4.3

Published

Bridge PCA agent identity with SPIFFE/SPIRE workload identity: parse/verify JWT-SVIDs and X.509-SVID SPIFFE IDs, map a SPIFFE ID to/from a PCA agent holder.

Readme

@atlasauth/pca-spiffe

Bridge Proof-Carrying Authority agent identity with SPIFFE / SPIRE workload identity. A SPIFFE workload is the kind of attested, non-human principal PCA calls an agent holder. This package validates SPIFFE IDs, verifies JWT-SVIDs, parses and verifies X.509-SVIDs, and maps a SPIFFE ID to and from a PCA holder (a base64url Ed25519 public key usable as Capability.holder).

Install

npm i @atlasauth/pca-spiffe @atlasauth/pca jose

Usage

import { parseSpiffeId, verifyJwtSvid, parseX509Svid, verifyX509Svid, svidToHolder, holderToSpiffeId, SpiffeError } from '@atlasauth/pca-spiffe';

// Verify a JWT-SVID (audience is mandatory; `key` may also be a JWKS resolver from jose).
const svid = await verifyJwtSvid(token, { audience: 'rs', key: bundleKey, trustDomain: 'example.org' });
svid.spiffeId.path; // '/ns/prod/agent-7'

// Or parse an X.509-SVID leaf (PEM or DER): one URI SAN, CA:FALSE, digitalSignature, no keyCertSign/cRLSign.
const x509 = parseX509Svid(pem);

// Verify the leaf and its chain against the trust domain's bundle authorities (signatures, CA flags,
// keyCertSign, pathLenConstraint, validity, trust domain).
const verified = verifyX509Svid(chainPem, { trustDomain: 'example.org', roots: [bundleCaPem] });

// Bind the workload to a PCA holder key, then use `.holder` with mintRoot / delegate.
// svidToHolder takes only a VERIFIED SVID (R3-18). X.509 with an Ed25519 key: the holder is the cert key.
const h = svidToHolder(verified);
// Any other holder key needs a signature by the SVID key over holderBindingMessage(spiffeId, holder):
//   svidToHolder(verified, agentPublicKeyB64u, { proof })
// A JWT-SVID is a bearer token: it needs a matching cnf.jwk, or { acceptUnboundJwtHolder: true } if you authenticated the key another way.
const hj = svidToHolder(svid, agentPublicKeyB64u, { acceptUnboundJwtHolder: true });
h.holder;               // use as Capability.holder
holderToSpiffeId(h);    // 'spiffe://example.org/ns/prod/agent-7'

try { parseSpiffeId('spiffe://Bad/x'); } catch (e) { (e as SpiffeError).code; } // 'invalid_trust_domain'

API

  • parseSpiffeId, verifyJwtSvid, parseX509Svid, verifyX509Svid, svidToHolder, holderBindingMessage, holderToSpiffeId, JWT_SVID_ALGORITHMS.
  • Types: SpiffeId, JwtSvid, X509Svid, SpiffeHolder, SpiffeError (with a stable code).

Status

Experimental and unaudited. Breaking in R3-18: verifyJwtSvid requires trustDomain (no unpinned mode), and svidToHolder accepts only the object returned by verifyJwtSvid / verifyX509Svid (strings, parsed IDs and parse-only SVIDs throw unverified_svid). An X.509-SVID binds its own Ed25519 key, or another holder key with a proof signed by the SVID key. A JWT-SVID has no key of its own, so a holder key is bound only through a cnf.jwk claim, or by your explicit acceptUnboundJwtHolder attestation that you authenticated the key by other means.

What is validated:

  • SPIFFE IDs follow the SPIFFE-ID standard, checked with the character-by-character rules of go-spiffe v2 (every code point 0 to 255 in the trust domain and the path, empty and dot segments, scheme, percent-encoding, length limits), and compared against py-spiffe 0.3.2 on 545 strings. py-spiffe is more lenient than the standard (case-insensitive scheme and trust domain, no length limits, accepts a trailing newline); this package follows the standard.
  • X.509-SVID leaves: the go-spiffe test certificates are checked, including each deliberately wrong leaf (CA flag set, keyCertSign, cRLSign, no digitalSignature, no URI SAN) and signing certificate (not a CA, no keyCertSign), each rejected with its own error code. The SPIFFE ID is read from the DER subjectAltName.
  • verifyX509Svid builds the chain to a bundle authority using Node's certificate signature checks. Its accept and reject decisions on nine chains (valid, path-length violation, signer without keyCertSign, signer that is not a CA, expired, not yet valid, unrelated root, missing intermediate) match both the OpenSSL command-line verifier and the Python cryptography verifier.
  • JWT-SVIDs: tokens signed by PyJWT (ES256, RS256, PS256) are accepted, and the tampered variants (wrong audience, expired, missing exp or aud, bad sub, other signer, wrong typ, wrong trust domain) get the same verdict as py-spiffe. Only the algorithms the JWT-SVID specification allows (RS, ES, PS families) are accepted by default; none and HMAC are always refused.

parseX509Svid rejects CA certificates and certificates without digitalSignature (releases before this one accepted any certificate with a single URI SAN), and verifyJwtSvid refuses HMAC algorithms even when given raw key bytes.

Not validated: certificate revocation and name constraints are not checked (a critical extension this package does not understand makes verification fail); verifyX509Svid has not been compared against go-spiffe's own chain verifier; trust bundle retrieval and rotation, the Workload API, and SPIFFE federation are out of scope.

License

MIT - see LICENSE

Canonical token spelling

Before any JOSE verification this package runs assertCanonicalCompactJws from @atlasauth/pca on the JWT-SVID (rejected with code malformed_token): one accepted string form per token, so the token string (or its hash) is safe to use as a dedupe / replay / ledger key. Padded, + / alphabet, altered-trailing-bit, whitespace and duplicate-header-key re-encodings are rejected with a typed reason before the signature is even checked.