@aura-stack/jose
JOSE utilities for JWT signing, verification, and encryption
Overview
@aura-stack/jose provides a curated API surface for working with JWS, JWE, and JWT standards.
It also includes a convenience re-export of the official jose library via the path @aura-stack/jose/jose, allowing consumers to access low-level cryptographic primitives when needed.
Features
- Direct re-export of
jose— access all primitives from the upstream package via@aura-stack/jose/jose. - JWE utilities — use
createJWE,encryptJWE, anddecryptJWEfor encryption/decryption flows. - JWS utilities — use
createJWS,signJWS, andverifyJWSfor signature and verification. - JWT helpers — use
createJWT,encodeJWT, anddecodeJWTfor signing and encrypting JSON Web Tokens. - Secure by design — built on top of modern JOSE standards (RFC 7515, 7516, 7519).
Installation
If you haven’t installed the package yet:
npm install @aura-stack/joseThe @aura-stack/jose package is already included as a dependency of @aura-stack/auth. You only need to install it separately
if you want to use it standalone.
JSON Web Token (JWT)
A JSON Web Token (JWT) is a compact format for securely representing claims between two parties. This library supports signing and encryption of JWTs usingg JWSs and JWEs.
The encodeJWT and decodeJWT utilities allow you to sign and verify tokens using a shared secret. For convenience, the createJWT function centralizes their creation.
import { createJWT } from "@aura-stack/jose"
const { encodeJWT, decodeJWT } = createJWT(process.env.AURA_AUTH_SECRET!)
const payload = {
userId: "123",
email: "johndoe@example.com",
}
const jwt = await encodeJWT(payload)
const jwtDecoded = await decodeJWT(jwt)JSON Web Signature (JWS)
JSON Web Signature (JWS) enables signing and verifying digital messages to ensure authenticity and integrity. This library provides three main utilities:
signJWS— signs a payload using a shared secret.verifyJWS— verifies the validity and authenticity of a signed token.createJWS— wraps both functions, binding a secret automatically.
Signing a Token
import { signJWS } from "@aura-stack/jose/sign"
const payload = {
userId: "123",
email: "user@example.com",
role: "admin",
}
const token = await signJWS(payload, process.env.AURA_AUTH_SECRET!)Verifying a Token
import { verifyJWS } from "@aura-stack/jose/sign"
try {
const payload = await verifyJWS(token, process.env.AURA_AUTH_SECRET!)
console.log("User ID:", payload.userId) // "123"
console.log("Email:", payload.email) // "user@example.com"
} catch (error) {
console.error("Invalid token:", error)
}Using createJWS
createJWS simplifies setup by pre-binding the secret key.
import { createJWS } from "@aura-stack/jose/sign"
export const { signJWS, verifyJWS } = createJWS(process.env.AURA_AUTH_SECRET!)JSON Web Encryption (JWE)
JSON Web Encryption (JWE) allows you to encrypt and decrypt sensitive data within a secure, standardized structure.
This library exposes:
encryptJWE— encrypts payloads using a symmetric key.decryptJWE— decrypts previously encrypted tokens.createJWE— centralizes both utilities and binds the secret key.
Encrypting Data
import { encryptJWE } from "@aura-stack/jose/encrypt"
const sensitiveData = {
creditCard: "1234-5678-9012-3456",
ssn: "123-45-6789",
}
const encrypted = await encryptJWE(sensitiveData, process.env.AURA_AUTH_SECRET!)
console.log("Encrypted:", encrypted)Decrypting Data
import { decryptJWE } from "@aura-stack/jose/encrypt"
try {
const decrypted = await decryptJWE(encrypted, process.env.AURA_AUTH_SECRET!)
console.log("Credit Card:", decrypted.creditCard)
} catch (error) {
console.error("Decryption failed:", error)
}Using createJWE
createJWE provides a centralized interface that pre-configures encryption and decryption with your secret key.
import { createJWE } from "@aura-stack/jose/encrypt"
export const { encryptJWE, encryptJWE } = createJWE(process.env.AURA_AUTH_SECRET!)Re-export: jose library
For advanced use cases, you can access the full jose API directly:
import * as jose from "@aura-stack/jose/jose"
import * as jose from "@aura-stack/jose/jose"
// Signing (JWS)
new jose.SignJWT({ userId: "123" }).setProtectedHeader({ alg: "HS256" })
// Verification (JWS)
await jose.jwtVerify(token, secret)
// Encryption (JWE)
await new jose.EncryptJWT({ data }).setProtectedHeader({ alg: "dir", enc: "A256GCM" })
// Decryption (JWE)
await jose.jwtDecrypt(encrypted, secret)Best Practices
Use strong secrets— At least 32 random bytes (256 bits).Prefer encryption for sensitive payloads— Use JWE when confidentiality is required.Validate inputs— Always sanitize data before signing or encrypting.Rotate secrets periodically— Implement secret rotation to improve long-term security.Use environment variables— Never hard-code secrets in your codebase.