Help us shape the future of Go! Take the 2026 Go Developer Survey

xpki

module
v1.0.316 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: Apache-2.0

README

xpki

Go Reference

Go library and CLI tools for building PKI: hardware or cloud backed keys (PKCS#11, AWS KMS, GCP KMS), certificate signing requests, a certificate authority with policy profiles, OCSP and CRL signing, certificate bundling and verification, and JWT/DPoP token issuance and validation.

The module is github.com/effective-security/xpki and targets Go 1.27.

Packages

Package Purpose
cryptoprov Provider abstraction (Provider, KeyManager, Crypto), config loading, key URIs, PEM helpers
crypto11 PKCS#11 provider (HSM, SoftHSM): crypto.Signer/crypto.Decrypter backed by device keys
cryptoprov/awskmscrypto AWS KMS provider
cryptoprov/gcpkmscrypto Google Cloud KMS provider
cryptoprov/inmemcrypto In-memory provider for tests and development
csr CSR generation and parsing, key requests, SAN and CRL distribution point encoding
authority Certificate Authority: issuers, certificate profiles, Sign, OCSP and CRL signing
certutil Certificate, PEM, chain and bundle helpers, hashes, OCSP request creation
jwt JWT signing and verification, claims, static and remote JWKS key sets
jwt/dpop DPoP proof creation and verification (RFC 9449)
jwt/accesstoken Opaque access-token helpers on top of jwt
jwt/oauth2client OAuth2 client for token endpoints
dataprotection Symmetric AEAD protection of small payloads and JSON objects
armor Armored (PEM-like) block decoding
oid Human-readable names for key usages and object identifiers
x/print Pretty printers for certificates, CSRs, CRLs and OCSP responses
testca Test-only CA and certificate generator

See Documentation/codemap.md for entry points and invariants per package, FINDINGS.md for known defects, and ROADMAP.md for planned work.

Install

go get github.com/effective-security/xpki
go install github.com/effective-security/xpki/cmd/hsm-tool@latest
go install github.com/effective-security/xpki/cmd/xpki-tool@latest

Configuration

Crypto provider

A provider is described by a small JSON or YAML token config. The Manufacturer selects the registered loader; the remaining fields are provider specific. Import the provider package for its side-effect registration.

SoftHSM / PKCS#11 (crypto11, manufacturer SoftHSM):

{
  "Manufacturer": "SoftHSM",
  "Path": "/usr/lib/softhsm/libsofthsm2.so",
  "TokenLabel": "xpki_unittest",
  "Pin": "file:/home/me/softhsm2/xpki_pin.txt"
}

AWS KMS (awskmscrypto, manufacturer AWSKMS):

{
  "Manufacturer": "AWSKMS",
  "Model": "14555",
  "Attributes": "Endpoint=http://localhost:14555,Region=us-west-2"
}

In-memory (inmemcrypto, manufacturer inmem):

{
  "Manufacturer": "inmem",
  "TokenLabel": "inmem_unittest",
  "Pin": "file:inmem_pin.txt"
}

Pin accepts a literal value, file:<path>, or an environment reference, see cryptoprov.TokenConfig in the code map.

Private keys that live in a provider are referenced by a PKCS#11 style URI and can be used anywhere a PEM key is accepted (issuer config, JWT config):

pkcs11:manufacturer=AWSKMS;id=c98c624e-3609-4d8f-a615-9031b3a811d4;serial=arn:aws:kms:eu-west-2:111122223333:key/c98c624e-3609-4d8f-a615-9031b3a811d4;type=private
Certificate Authority
authority:
  issuers:
    - label: TrustyCA
      type: trusty
      cert: /tmp/xpki/certs/l2_ca.pem
      key: /tmp/xpki/certs/l2_ca.key # PEM file or pkcs11: URI
      ca_bundle: /tmp/xpki/certs/l1_ca.pem
      root_bundle: /tmp/xpki/certs/root_ca.pem
      aia:
        issuer_url: http://localhost:7880/v1/cert/${ISSUER_ID}
        crl_url: http://localhost:7880/v1/crl/${ISSUER_ID}
        ocsp_url: http://localhost:7880/v1/ocsp

profiles:
  server:
    expiry: 168h
    backdate: 30m
    usages: [signing, key encipherment, server auth]
    allowed_extensions:
      - 1.3.6.1.5.5.7.1.1 # AIA
      - 2.5.29.17 # SAN

A profile controls validity, key usages, allowed extensions, name and SAN policies, and path length. Requester CSR fields not permitted by the profile are dropped or rejected at Issuer.Sign.

allowed_extensions governs extensions from two sources. For the trusted SignRequest.Extensions an empty list allows all. For the untrusted CSR an empty list allows none, and key usage, EKU, SAN, basic constraints, key identifiers and OCSP no-check are never taken from a CSR; the SAN is rebuilt from the allowed_fields names. An allow-listed CSR AIA or CRL DP is kept only when the issuer does not generate one. Explicit NotBefore/NotAfter must fit the profile: lifetime no longer than expiry, NotBefore no earlier than now minus backdate. A populated allowed_profiles on an issuer limits it to the listed profiles, issuer-specific and issuer_label: "*" alike.

JWT provider
issuer: trusty-dev.com
token_expiry: 12h
kid: 0
keys:
  - id: 0
    seed: <symmetric seed>

or, for an asymmetric signer:

issuer: trusty-dev.com
private_key: pkcs11:manufacturer=AWSKMS;id=...;type=private

Token verification against an OpenID Connect issuer:

issuer: https://accounts.google.com
jwks_uri: https://www.googleapis.com/oauth2/v3/certs

Usage

Load providers and sign with an HSM key
import (
    "github.com/effective-security/xpki/cryptoprov"
    _ "github.com/effective-security/xpki/crypto11"                 // registers "SoftHSM"
    _ "github.com/effective-security/xpki/cryptoprov/awskmscrypto"  // registers "AWSKMS"
)

crypto, err := cryptoprov.Load("/etc/xpki/softhsm.json", []string{"/etc/xpki/awskms.json"})
if err != nil {
    return err
}
// Load a key by PEM file or by pkcs11: URI, whichever the file holds.
signer, err := crypto.NewSignerFromFromFile("/etc/xpki/ca.key")
Create a key and CSR
prov := csr.NewProvider(crypto.Default())
req := &csr.CertificateRequest{
    CommonName: "localhost",
    SAN:        []string{"localhost", "127.0.0.1", "spiffe://trusty/all"},
    KeyRequest: prov.NewKeyRequest("server", "ECDSA", 256, csr.SigningKey),
    Names:      []csr.X509Name{{Country: "US", Organization: "trusty.com"}},
}
csrPEM, priv, keyID, err := prov.GenerateKeyAndRequest(req)
Run a CA
cfg, err := authority.LoadConfig("/etc/xpki/ca-config.yaml")
if err != nil {
    return err
}
ca, err := authority.NewAuthority(cfg, crypto)
if err != nil {
    return err
}
issuer, err := ca.GetIssuerByProfile("server")
if err != nil {
    return err
}
cert, certPEM, err := issuer.Sign(csr.SignRequest{
    Request: string(csrPEM),
    Profile: "server",
    SAN:     []string{"localhost"},
})

Issuer.SignOCSP and the CRL helpers produce signed OCSP responses and CRLs for the issuer's certificates.

Verify a certificate chain
bundle, status, err := certutil.LoadAndVerifyBundleFromPEM(
    "server.pem", "intermediates.pem", "roots.pem",
    certutil.WithKeyUsages(x509.ExtKeyUsageServerAuth),
)

Without a root file the bundler only checks that each certificate signs the previous one (Force). To verify against the platform trust store, pass certutil.WithSystemRoots(true); system roots are never trusted implicitly.

Issue and verify JWTs
prov, err := jwt.LoadProvider("/etc/xpki/jwtprov.yaml", crypto)
if err != nil {
    return err
}
claims := jwt.CreateClaims("jti-1", "subject", prov.Issuer(), []string{"api"}, time.Hour, nil)
token, err := prov.Sign(ctx, claims)

parsed, err := prov.ParseToken(ctx, token, &jwt.VerifyConfig{
    ExpectedIssuer:   prov.Issuer(),
    ExpectedAudience: []string{"api"},
})

Tokens from a third-party OIDC issuer are verified with jwt.NewParser(cfg), which loads keys from a static JWKS or a jwks_uri. A key is chosen by kid and the token algorithm; a token without kid needs exactly one eligible signing key. Remote sets refetch when no cached key fits, at most once per 10s, with a 10s fetch timeout and a 1 MiB response limit (jwt.NewRemoteKeySet options change these).

CLI tools

  • hsm-tool: list, inspect, generate and delete keys in an HSM or KMS; create CSRs and sign certificates with those keys.
  • xpki-tool: inspect and validate certificates, CSRs, CRLs and OCSP responses.
hsm-tool --cfg /tmp/xpki/softhsm_unittest.json hsm list
xpki-tool cert info server.pem

Development

Requirements: Go 1.27, a C compiler for PKCS#11/cgo, SoftHSM2 (softhsm2-util and its module), and Docker for the local AWS KMS emulator. Generating a new test PIN also requires openssl.

make hsmconfig builds bin/hsm-tool, initializes the test token using softhsm2-util, then verifies the generated configuration and PIN with bin/hsm-tool --cfg /tmp/xpki/softhsm_unittest.json hsm list. OpenSC (pkcs11-tool) is optional: it is needed only when invoking scripts/config-softhsm.sh directly with --list-slots or --list-object.

make tools            # golangci-lint, cov-report, govulncheck, gomarkdoc (pinned versions)
make hsmconfig        # create the SoftHSM token and /tmp/xpki/softhsm_unittest.json
make start-local-kms  # start two local-kms containers on :14555 and :14556
make test             # full test suite (needs the two steps above)
make test RACE=true   # under the race detector
make covtest coverage # coverage report
make lint             # fmt-check, go vet, govulncheck, golangci-lint (read-only)
make build            # builds bin/hsm-tool and bin/xpki-tool
make docs             # regenerate Documentation/*.md (gomarkdoc) and CLI help dumps
make all              # clean, tools, generate, hsmconfig, start-local-kms, covtest

The AWS emulator does not check credentials, but the SDK requires them:

export AWS_ACCESS_KEY_ID=notusedbyemulator
export AWS_SECRET_ACCESS_KEY=notusedbyemulator
export AWS_DEFAULT_REGION=us-west-2

CI (.github/workflows/unittest.yml) runs make lint and make covtest with SoftHSM and local-kms and requires more than 90% total coverage; documentation-only pull requests skip the job. Merges to main are tagged from .VERSION plus the commit count.

Contributing

Read AGENTS.md for coding, error handling, testing and documentation rules, and keep Documentation/codemap.md current in the same change as the code.

Generated API reference (make docs, gomarkdoc, do not edit): Documentation/api

License

See LICENSE.

Directories

Path Synopsis
Package armor implements OpenPGP ASCII Armor, see RFC 9580 §6.
Package armor implements OpenPGP ASCII Armor, see RFC 9580 §6.
Package authority implements an in-process Certification Authority.
Package authority implements an in-process Certification Authority.
Package certutil provides utilities to work with certificates.
Package certutil provides utilities to work with certificates.
cmd
hsm-tool command
Command hsm-tool manages keys in a PKCS#11 HSM, AWS KMS, GCP KMS or an in-memory provider, and creates CSRs and certificates signed with those keys.
Command hsm-tool manages keys in a PKCS#11 HSM, AWS KMS, GCP KMS or an in-memory provider, and creates CSRs and certificates signed with those keys.
hsm-tool/cli
Package cli implements the hsm-tool command tree: hsm list/info/generate/ remove and csr create/gen-cert/sign.
Package cli implements the hsm-tool command tree: hsm list/info/generate/ remove and csr create/gen-cert/sign.
xpki-tool command
Command xpki-tool inspects and validates PKI artifacts: certificates, certificate requests, CRLs and OCSP responses.
Command xpki-tool inspects and validates PKI artifacts: certificates, certificate requests, CRLs and OCSP responses.
xpki-tool/cli
Package cli implements the xpki-tool command tree: csr-info, cert info/validate, crl info/fetch and ocsp info/fetch.
Package cli implements the xpki-tool command tree: csr-info, cert info/validate, crl info/fetch and ocsp info/fetch.
Package crypto11 provides a Go interface to PKCS#11 cryptographic devices such as Hardware Security Modules (HSMs) and smart cards.
Package crypto11 provides a Go interface to PKCS#11 cryptographic devices such as Hardware Security Modules (HSMs) and smart cards.
Package cryptoprov provides a unified interface for cryptographic operations across different providers and hardware security modules (HSMs).
Package cryptoprov provides a unified interface for cryptographic operations across different providers and hardware security modules (HSMs).
awskmscrypto
Package awskmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over AWS KMS asymmetric signing keys (RSA 2048/3072/4096 and NIST P-256, P-384, P-521).
Package awskmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over AWS KMS asymmetric signing keys (RSA 2048/3072/4096 and NIST P-256, P-384, P-521).
gcpkmscrypto
Package gcpkmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over Google Cloud KMS (HSM protection level).
Package gcpkmscrypto implements cryptoprov.Provider and cryptoprov.KeyManager over Google Cloud KMS (HSM protection level).
inmemcrypto
Package inmemcrypto is a software cryptoprov.Provider that keeps RSA and ECDSA keys in memory and can export them as PEM.
Package inmemcrypto is a software cryptoprov.Provider that keeps RSA and ECDSA keys in memory and can export them as PEM.
testprov
Package testprov is a test-only in-memory cryptoprov.Provider whose keys are not exportable: ExportKey returns a pkcs11: URI like the HSM and KMS providers do, and the key wrapper implements crypto.Decrypter.
Package testprov is a test-only in-memory cryptoprov.Provider whose keys are not exportable: ExportKey returns a pkcs11: URI like the HSM and KMS providers do, and the key wrapper implements crypto.Decrypter.
Package csr provides utilities for creating, parsing, and validating Certificate Signing Requests (CSRs) as defined by RFC 2986.
Package csr provides utilities for creating, parsing, and validating Certificate Signing Requests (CSRs) as defined by RFC 2986.
Package dataprotection provides authenticated encryption of small payloads behind the Provider interface, plus helpers to protect and unprotect JSON objects as base64url strings.
Package dataprotection provides authenticated encryption of small payloads behind the Provider interface, plus helpers to protect and unprotect JSON objects as base64url strings.
internal
testenv
Package testenv gates tests that need external fixtures, such as the local-kms emulator or the SoftHSM token (XPKI-100).
Package testenv gates tests that need external fixtures, such as the local-kms emulator or the SoftHSM token (XPKI-100).
version
Package version exposes the build version of the binaries.
Package version exposes the build version of the binaries.
jwt
Package jwt provides JSON Web Token (JWT) signing, verification, and parsing capabilities.
Package jwt provides JSON Web Token (JWT) signing, verification, and parsing capabilities.
accesstoken
Package accesstoken wraps a jwt.Provider and a dataprotection.Provider to issue opaque encrypted access tokens of the form "pat.<base64url(AES-GCM (claims))>" while still parsing plain JWTs through the inner provider.
Package accesstoken wraps a jwt.Provider and a dataprotection.Provider to issue opaque encrypted access tokens of the form "pat.<base64url(AES-GCM (claims))>" while still parsing plain JWTs through the inner provider.
dpop
Package dpop implements OAuth 2.0 Demonstrating Proof of Possession (RFC 9449): clients build DPoP proof JWTs for HTTP requests with Signer and ForRequest; servers verify them with VerifyRequestClaims or VerifyClaimsContext and bind the resulting key thumbprint to the access token "cnf.jkt" claim.
Package dpop implements OAuth 2.0 Demonstrating Proof of Possession (RFC 9449): clients build DPoP proof JWTs for HTTP requests with Signer and ForRequest; servers verify them with VerifyRequestClaims or VerifyClaimsContext and bind the resulting key thumbprint to the access token "cnf.jkt" claim.
oauth2client
Package oauth2client holds the configuration model and registry for OAuth2 and OpenID Connect identity-provider clients, looked up by provider id, email or email domain, and a helper to build token-endpoint requests.
Package oauth2client holds the configuration model and registry for OAuth2 and OpenID Connect identity-provider clients, looked up by provider id, email or email domain, and a helper to build token-endpoint requests.
Package metricskey defines the metrics.Describe descriptors emitted by the crypto providers (perf_crypto) and the certificate authority (perf_ca, perf_ca_signreq), and the Metrics list used to register them.
Package metricskey defines the metrics.Describe descriptors emitted by the crypto providers (perf_crypto) and the certificate authority (perf_ca, perf_ca_signreq), and the Metrics list used to register them.
Package oid maps well-known X.509 object identifiers, key usages and extended key usages to human-readable names and back.
Package oid maps well-known X.509 object identifiers, key usages and extended key usages to human-readable names and back.
Package testca provides utilities for creating test Certificate Authorities and certificates for testing and development purposes.
Package testca provides utilities for creating test Certificate Authorities and certificates for testing and development purposes.
x
print
Package print writes human-readable descriptions of certificates, certificate requests, CRLs and OCSP responses to an io.Writer, and a JSON helper for CLI output.
Package print writes human-readable descriptions of certificates, certificate requests, CRLs and OCSP responses to an io.Writer, and a JSON helper for CLI output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL