Liking cljdoc? Tell your friends :D

Migrating from buddy-sign

buddy-sign is solid for JWS and signed JWT use cases and remains fine for those. jose-clj is useful when a project needs full JWE support, a JWK lifecycle, cached remote JWKS verification, or modern algorithms such as EdDSA and ECDH-ES.

Factually, buddy-sign has been dormant since 2024.

Function mapping

buddy-sign / buddy-core patternjose-clj equivalent
buddy-sign.jwt/signjose.jwt/sign
buddy-sign.jwt/unsignjose.jwt/verify
Parse JWT claims without verificationjose.jwt/claims
buddy-sign.jws/signjose.jws/sign
buddy-sign.jws/unsignjose.jws/verify
buddy-sign.jwe/encryptjose.jwe/encrypt for payloads, or jose.jwt/encrypt for JWT claims
buddy-sign.jwe/decryptjose.jwe/decrypt for payloads, or jose.jwt/decrypt for JWT claims
Local key collectionjose.jwk/jwk-set plus jose.jwks/local-source
Remote JWKS verificationjose.jwks/remote-source plus jose.jws/verify-with-jwks or jose.jwt/verify-with-jwks
buddy-core.keys/public-key or buddy-core.keys/private-key from PEMjose.jwk/parse of a JWK. jose-clj is JWK-centric and does not expose a PEM loader in src/. Convert PEM to JWK with Nimbus JOSE+JWT when needed, then pass the JWK JSON, map, or Nimbus JWK to jose-clj.

JWKs instead of raw Java keys

buddy-based code often passes raw java.security keys from buddy-core key loading helpers. jose-clj APIs take JWK input:

(require '[jose.jwk :as jwk]
         '[jose.jwt :as jwt])

(def key
  (jwk/generate :rsa {:kid "sig-1" :use :sig :alg :rs256}))

(def token
  (jwt/sign key {:sub "alice"} {:expires-in 3600}))

(jwt/verify key token {:required [:sub]})

jwk/parse accepts JWK JSON strings, Clojure maps, or Nimbus JWK values. jwk/->json and jwk/->map serialize keys. jwk/public-jwk returns the public form for asymmetric keys and nil for :oct.

Options

buddy-sign APIs commonly use raw Java keys and option maps around the chosen operation. jose-clj uses JWKs plus keyword algorithm names.

Examples:

Needjose-clj option
RSA signed JWTjwt/sign with {:alg :rs256}
RSA-PSS signed JWTjwt/sign with {:alg :ps256}
ECDSA signed JWTjwt/sign with {:alg :es256}
EdDSA signed JWTjwt/sign with {:alg :eddsa} and an OKP :ed25519 JWK
JWE ECDH-ES with AES-GCMjwt/encrypt or jwe/encrypt with {:alg :ecdh-es :enc :a256gcm}
Header key ID:kid on jwt/sign, jws/sign, jwt/encrypt, or jwe/encrypt
Extra protected headers:headers

Claim validation

buddy-sign signed JWT flows usually combine signing or unsigning with claims such as expiration, not-before, audience, and issuer. In jose-clj:

Claim behaviorjose-clj API
Add expiration at sign timejwt/sign or jwt/encrypt with {:expires-in seconds}
Add issued-at at sign timejwt/sign or jwt/encrypt with {:now-iat? true}
Provide explicit :exp, :nbf, or :iatPut java.time.Instant or epoch seconds in the claims map.
Validate expirationjwt/verify, jwt/decrypt, or jwt/verify-with-jwks checks :exp automatically when present.
Validate not-beforejwt/verify, jwt/decrypt, or jwt/verify-with-jwks checks :nbf automatically when present.
Allow clock skewVerify with {:clock-skew seconds}.
Validate audienceVerify with {:aud "expected-audience"}.
Validate issuerVerify with {:iss "expected-issuer"}.
Require claimsVerify with {:required [:sub :iss]}.

Relevant jose-clj validation error keywords are :expired, :not-yet-valid, :claim-mismatch, :missing-claim, and :invalid-signature.

JWS payloads

For non-JWT JWS payloads:

(require '[jose.jws :as jws])

(def compact
  (jws/sign key "payload" {:alg :rs256 :kid "sig-1"}))

(jws/verify key compact)
;; => {:payload "payload", :payload-bytes ..., :header ...}

jws/sign accepts string or byte-array payloads. jws/verify returns both the UTF-8 string payload and raw bytes.

JWE payloads

For non-JWT encrypted payloads:

(require '[jose.jwe :as jwe])

(def encryption-key
  (jwk/generate :ec {:curve :p-256 :kid "enc-1" :use :enc}))

(def ciphertext
  (jwe/encrypt encryption-key "secret msg" {:alg :ecdh-es :enc :a256gcm}))

(jwe/decrypt encryption-key ciphertext)
;; => {:payload "secret msg", :payload-bytes ..., :header ...}

For JWT claims, prefer jwt/encrypt and jwt/decrypt.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close