Join our Newsletter — 33% off our NHI Course
Home› Guides› JWS vs JWE: when to sign tokens and…
Guide Web & API Security

JWS vs JWE: when to sign tokens and when to encrypt them

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 14 November 2026 17 min read
On this page

Most teams sign their JSON Web Tokens and assume the contents are protected, yet a JWS payload is only base64url encoded and anyone holding the token can read every claim. JSON Web Signature (JWS, RFC 7515) gives integrity and origin authentication; JSON Web Encryption (JWE, RFC 7516) gives confidentiality. They solve different problems, use different algorithm registries and fail in different ways. This guide compares the two for architects, API security engineers and identity teams deciding whether a token, request object or message needs signing, encryption or both, and how to run the keys behind each. For token validation basics, start with the JWT Security Guide; this page goes deeper on the sign versus encrypt decision.

Key takeaways

  • Signing is not hiding. RFC 7515 protects integrity and authenticates the origin of the content; it does not encrypt the payload, so claims in a signed JWT are visible to clients, browsers, proxies and logs.
  • Encryption alone does not prove who sent it. A JWE with a publicly known recipient key can be created by anyone, so encryption on its own is not sender authentication.
  • Sign, then encrypt, when you need both. RFC 7519 Section 11.2 says producers should normally sign and then encrypt, producing a Nested JWT with cty set to JWT; OpenID Connect requires that order for encrypted ID Tokens.
  • Different registries, different traps. JWS risks centre on alg confusion, none and weak HMAC secrets; JWE risks centre on RSA1_5, invalid curve points in ECDH-ES, compression and unbounded PBES2 iteration counts.
  • Keys decide the outcome. One key per algorithm and purpose, allowlisted algorithms, and explicit typ values (RFC 8725 Sections 3.1, 3.11 and 3.12) do more for safety than the choice of format.

The short answer

Use JWS when the recipient must be able to trust who issued the data and that it has not changed, and the data is not sensitive to whoever carries it. That covers most access tokens, ID Tokens, signed request objects and software statements. Use JWE when the data must stay unreadable to intermediaries, the client or the user agent, for example claims containing personal data, internal entitlements or secrets in transit through an untrusted hop. Use both, as a Nested JWT signed first and encrypted second, when the recipient needs confidentiality and proof of origin. If confidentiality is the only concern and the client never needs to read the token, an opaque reference token is often simpler than JWE; see JWT vs Opaque Tokens.

Side by side: what each format actually is

PropertyJWS (RFC 7515)JWE (RFC 7516)
Security goalIntegrity and origin authentication (signature or MAC)Confidentiality and integrity of the ciphertext (AEAD)
Compact serialisation3 parts: protected header, payload, signature5 parts: protected header, encrypted key, initialisation vector, ciphertext, authentication tag
JSON serialisationMultiple signatures over one payload via a signatures array; a flattened form for one signerMultiple recipients via a recipients array; a flattened form for one recipient; supports Additional Authenticated Data (AAD)
Key header parametersalg, kid, jku, jwk, x5u, x5c, crit, typalg (key management), enc (content encryption, required), zip, kid, typ, cty
Who holds which keyIssuer holds the private key (or shared HMAC key); verifiers hold the public keyRecipient holds the private key; anyone with the public key can encrypt to it
Readable by carriersYes, payload is base64url onlyNo, only the holder of the decryption key
Proves senderYes (asymmetric) or proves a key holder (HMAC)Not by itself with asymmetric key management
Typical usesOAuth access tokens (RFC 9068), ID Tokens, client assertions, signed request objects, webhooksEncrypted ID Tokens and UserInfo responses, tokens carrying personal data, encrypted request objects, sensitive claims between services

JWS in depth: threat model, architecture and failure modes

Threat model

JWS defends against tampering and forgery: a client that edits its own scope claim, a proxy that alters a webhook body, or an attacker who mints a token for another user. It does not defend against disclosure, and it does not stop replay of a valid token; replay controls are exp, jti, audience restriction and sender-constrained tokens (RFC 7515 Section 10.10 covers replay protection as a separate concern).

Architecture in words

An issuer builds a protected header naming alg and kid, base64url encodes header and payload, and computes a signature over both. Verifiers fetch the issuer's public keys from a JWKS endpoint they have pinned in configuration, select the key by kid, check that the key's permitted algorithm matches the header, verify the signature, and only then evaluate claims. With HMAC (HS256 and friends) every verifier holds the same secret as the issuer, so any verifier can also mint tokens; RFC 7515 Section 10.5 spells out this difference between signatures and MACs.

Algorithms

JWS algRFC 7518 requirementNotes
HS256RequiredShared secret; key at least 256 bits; every verifier can forge
RS256RecommendedRSA PKCS #1 v1.5 signature; keys 2048 bits or larger
ES256Recommended+ECDSA P-256; RFC 8725 recommends deterministic ECDSA (RFC 6979)
PS256, PS384, PS512OptionalRSASSA-PSS; keys 2048 bits or larger
noneOptionalUnsecured JWS; must not be accepted by default

The draft successor to RFC 8725 (draft-ietf-oauth-rfc8725bis-10, in the RFC Editor queue when checked in November 2026) also recommends fully specified identifiers such as Ed25519 over the polymorphic EdDSA for new deployments, per RFC 9864. Drafts change, so treat that as direction rather than a fixed rule.

Failure modes

  • Algorithm confusion: a verifier that trusts the header alg can be tricked into verifying an RS256 public key as an HS256 secret. RFC 8725 Section 3.1 requires libraries to let callers fix the allowed algorithm set and to bind each key to exactly one algorithm.
  • Accepting none: RFC 7518 says implementations must not accept unsecured JWS by default.
  • Weak HMAC secrets: RFC 8725 Section 3.5 says human-memorable passwords must never be used directly as HMAC keys; they can be brute forced offline from a single token.
  • Trusting header key references: jku, x5u and jwk let the token tell you which key to trust. The 8725bis draft treats kid, jku and x5u as attacker controllable, with injection and SSRF risks.
  • Cross-JWT confusion: an ID Token replayed as an access token, or a token for one API accepted by another. RFC 8725 Sections 3.8 to 3.12 call for issuer, audience and explicit type checks.

Forged or tampered tokens map to ATT&CK T1606 Forge Web Credentials; the defensive answer is strict verification rather than detection after the fact.

JWE in depth: threat model, architecture and failure modes

Threat model

JWE defends against disclosure to anyone other than the intended recipient: the browser that stores an access token, a TLS-terminating gateway, a log pipeline, or the client itself. RFC 9068 Section 6 notes that clients and end users can read claims in unencrypted JWT access tokens, and lists encryption, omitting sensitive claims or opaque tokens as mitigations. JWE also detects tampering with the ciphertext, because every enc value is an authenticated encryption algorithm, but with asymmetric key management that integrity says nothing about who created it.

Architecture in words

The sender generates a random Content Encryption Key (CEK), encrypts the plaintext with the enc algorithm, and protects the CEK for the recipient according to the alg key management mode. RFC 7516 Section 2 defines five modes: Key Encryption (for example RSA-OAEP), Key Wrapping (AES Key Wrap), Direct Key Agreement (ECDH-ES), Key Agreement with Key Wrapping (ECDH-ES+A256KW) and Direct Encryption (dir, where the shared key is the CEK). The protected header is used as AAD, so altering alg or enc breaks decryption.

Algorithms

ParameterValueRFC 7518 requirementGuidance
algRSA-OAEP, RSA-OAEP-256Recommended+, OptionalPreferred RSA key transport; RFC 8725 prefers OAEP over PKCS #1 v1.5
algRSA1_5Recommended- (likely to decrease)Avoid; deprecated in the 8725bis draft because of chosen ciphertext attacks
algECDH-ES, ECDH-ES+A128KW, ECDH-ES+A256KWRecommended+, RecommendedValidate ephemeral public keys on the curve (RFC 8725 Section 3.4)
algA128KW, A256KW, dirRecommendedSymmetric; sender and recipient share a key
algPBES2-HS256+A128KW and siblingsOptionalPassword based; cap the p2c iteration count
encA128CBC-HS256, A256CBC-HS512RequiredAES-CBC with HMAC as a composite AEAD
encA128GCM, A256GCMRecommendedAES-GCM; never reuse an IV with the same key

Failure modes

  • RSA1_5 padding oracles: RFC 7516 Section 11.4 describes adaptive chosen ciphertext attacks and downgrade from RSA-OAEP to RSA1_5; Section 11.5 says recipients should not reveal key format errors and should substitute a random CEK to avoid timing leaks.
  • Invalid curve points: an ECDH-ES recipient that does not validate the sender's ephemeral key can leak its private key. RFC 8725 Section 3.4 points to partial public-key validation in NIST SP 800-56A Rev. 3, Section 5.6.2.3.4.
  • Compression before encryption: the zip value DEF can leak plaintext through ciphertext length (RFC 8725 Section 3.6), and the 8725bis draft also asks implementations to cap decompressed size to avoid resource exhaustion.
  • Unbounded PBES2 work: an attacker-chosen p2c can make the recipient burn CPU. The 8725bis draft suggests rejecting counts above twice the OWASP-recommended 600,000 iterations.
  • Treating decryption as authentication: anyone can encrypt to a published recipient key. If the recipient acts on decrypted claims without an inner signature, an attacker can inject claims.

Nested JWTs: signing and encrypting together

A Nested JWT is a JWT used as the payload of an outer JWS or JWE. RFC 7519 Section 5.2 makes cty required in this one case, with the value JWT, so the recipient knows to process the inner token. Section 11.2 says the operations can be applied in either order but producers should normally sign first and then encrypt, because that stops an attacker stripping the signature from an encrypted message and keeps the signer's identity private; it also notes that signatures over encrypted content are not considered valid in many jurisdictions. OpenID Connect Core Section 2 states that an encrypted ID Token must be signed and then encrypted, and Section 3.1.3.7 says the relying party should reject an unencrypted ID Token when encryption was negotiated.

PatternWhat the recipient learnsWhen it fits
JWS onlyWho issued it, unchanged; content public to carriersAccess tokens with non-sensitive claims, client assertions, webhooks
JWE only (symmetric, dir or AES KW)Confidential; origin limited to holders of the shared keyClosed systems where one service encrypts state for itself, such as encrypted cookies
JWE only (asymmetric)Confidential; origin unknownRarely appropriate for claims a recipient will act on
Sign then encrypt (Nested)Confidential and origin authenticated; signer hidden from carriersEncrypted ID Tokens, tokens with personal data crossing untrusted hops
Encrypt then signOrigin of the ciphertext, not necessarily of the plaintextAvoid for tokens; RFC 7519 recommends the opposite order

RFC 8725 Section 3.3 requires the recipient to reject the whole token if any cryptographic operation fails, inner or outer, and Section 3.11 requires the inner JWT of a Nested JWT to carry typ. A recipient that decrypts and then forgets to verify the inner signature has turned a Nested JWT back into unauthenticated JWE.

Key management for each format

Key ownership is reversed between the two formats, and that drives who runs what infrastructure.

  • JWS keys belong to the issuer: the authorisation server or token service holds signing keys, ideally in an HSM or cloud KMS, and publishes public keys via JWKS. Rotation is a publish, overlap, switch, retire cycle; see the JWKS Signing Key Rotation Guide.
  • JWE keys belong to the recipient: each client or resource server that wants encrypted tokens holds a decryption private key and publishes the public part, for example through its registered JWKS. That means every recipient becomes a key custodian, which is a real operational cost for large fleets of services and non-human identities.
  • Separate keys by use: RFC 8725 Section 3.1 binds each key to one algorithm and Section 3.12 recommends different keys for different kinds of JWT. Set the JWK use (sig or enc) and alg members so a library cannot repurpose an encryption key for signing.
  • Symmetric shortcuts: dir and HMAC are fast and simple but every party holding the key can both read and forge. Keep them inside a single trust boundary.

The Cryptographic Key Management Guide covers custody, rotation and destruction in general.

Decision guidance and trade-offs

QuestionIf yesIf no
Does the recipient act on the claims (authorisation, identity)?A signature is mandatoryEncryption alone may suffice for opaque state
Would disclosure to the client, browser or a log harm someone?Encrypt, minimise claims, or use opaque tokensJWS is enough
Does the client need to read the token?JWS, or JWE to the client itself (ID Tokens)Opaque or encrypted to the resource server
Can every recipient manage a decryption key safely?JWE is viablePrefer claim minimisation or opaque tokens
Is latency or token size critical (headers, cookies, mobile)?Measure; JWE adds two parts and an extra key operationLittle concern
  • Performance: JWE adds a key management operation and an AEAD pass per token, and Nested JWTs add both a signature and a decryption. ECDH-ES and AES-GCM are cheap on modern hardware; RSA decryption at high request rates is the usual hotspot, so benchmark at peak load rather than assuming.
  • Size: the encrypted key, IV and tag plus double base64url encoding in Nested JWTs grow tokens; check HTTP header and cookie limits on gateways.
  • Visibility: encrypted tokens hide claims from gateways and security tooling too. If your gateway enforces scopes, it then needs the decryption key, widening key exposure; see API Gateway vs In-Service Token Validation.
  • Small versus large organisations: a small team with one API is usually better served by short-lived signed tokens with minimal claims. Large estates with regulated personal data in tokens, or federation across organisations, are where JWE earns its operational cost.

Worked scenarios

Scenario 1, an internal microservice API: a token service issues access tokens to workloads with sub, aud, scope and exp. Nothing sensitive is in the claims, and TLS protects every hop. Choice: JWS with ES256, typ at+jwt as RFC 9068 Section 2.1 prefers, a 5 to 15 minute lifetime, and verifiers pinned to ES256 and the issuer's JWKS URL. Adding JWE would make every service a key custodian for no gain.

Scenario 2, a health portal's ID Token: the identity provider includes date of birth and a patient identifier for the relying party. The ID Token passes through the browser on a front-channel flow. Choice: sign then encrypt, with the relying party's registered RSA-OAEP-256 or ECDH-ES key and A256GCM, so the browser and any extensions see only ciphertext. The relying party decrypts, then verifies the inner RS256 or ES256 signature, and rejects the token if either step fails. Better still, move sensitive attributes to the UserInfo endpoint and keep the ID Token minimal.

Scenario 3, session state in a cookie: one web application stores a small state blob for itself. Choice: JWE with dir and A256GCM under a key only that application holds.

How to implement

  1. Inventory token flows: list every JWT type you issue or accept, who reads it, which hops it crosses and which claims it carries. Flag any token with personal data or internal entitlements.
  2. Minimise claims first: remove what the recipient does not need. The cheapest confidentiality control is a claim that is not there.
  3. Fix the algorithm allowlist: configure libraries with explicit alg (and for JWE, enc) values per token type, reject none, RSA1_5 and anything unlisted.
  4. Introduce explicit types: set typ per token kind (for example at+jwt) and reject mismatches.
  5. Pilot encryption on one flow: register the recipient's encryption key, enable sign then encrypt for one client, and run both paths in parallel in a test ring; confirm the recipient rejects unencrypted tokens once encryption is negotiated.
  6. Load test: measure latency and token size at peak, including gateway header limits.
  7. Roll out with rollback: keep the issuer able to fall back to signed-only tokens per client through configuration, and remove the fallback once the pilot is stable.
  8. Automate rotation: schedule signing and encryption key rotation separately, with overlap windows published through JWKS.

Detection and measurement

Log verification and decryption outcomes at the validating component, never the token itself; see the JWT and Session Tokens in Code and Logs Guide. Useful signals are tokens presenting an unexpected alg or enc, unknown kid values, header jku or x5u pointing outside your allowlist, bursts of decryption failures from one source (a possible oracle probe), and unencrypted tokens arriving where encryption was negotiated.

  • Allowlist coverage: percentage of token validators with an explicit algorithm allowlist (target 100%).
  • Sensitive claims exposed: number of token types carrying personal data without encryption or minimisation (target 0).
  • Deprecated algorithm use: count of tokens or keys using RSA1_5, none or HMAC secrets under 256 bits (target 0).
  • Rejection rate by reason: verification and decryption failures per million tokens, split by cause, to spot attacks and misconfiguration.
  • Key rotation age: days since last rotation for each signing and encryption key against policy.

Common failure patterns

  • Personal data in signed tokens: teams put email, phone or entitlements in a JWS access token believing the signature hides them; the client, the browser and every log can read them.
  • Decrypt and trust: a service decrypts a JWE with its private key and authorises on the claims without checking an inner signature, so anyone who knows its public key can mint claims.
  • One key for everything: the same RSA key pair used for RS256 signing and RSA-OAEP decryption, or a single HMAC secret shared across token types, enabling cross-purpose and cross-JWT attacks.
  • Library defaults left alone: verifiers that read alg from the header, accept none or follow jku to arbitrary URLs.
  • Encryption used to avoid fixing storage: encrypting a token that is then stored insecurely in the browser still leaves a bearer credential to steal; encryption hides claims, it does not stop replay. See the Browser Storage Security Guide.

Framework mapping

FrameworkReferenceJWSJWE
NIST SP 800-53 Rev 5SC-8 Transmission Confidentiality and IntegrityIntegrity of tokens in transitConfidentiality of claims beyond TLS endpoints
NIST SP 800-53 Rev 5SC-12 Cryptographic Key Establishment and Management; SC-13 Cryptographic ProtectionSigning key custody, allowed algorithmsRecipient key custody, key management modes
NIST SP 800-53 Rev 5AU-10 Non-repudiation; SI-7 Information IntegrityAsymmetric signatures bind originOnly via an inner signature
NIST CSF 2.0PR.DS-02 data in transit protectedIntegrityConfidentiality and integrity
MITRE ATT&CKT1606 Forge Web CredentialsStrict verification prevents forged tokensInner signature prevents injected claims

Practitioner checklist

  • Classify every JWT type you issue or accept as sign only, encrypt only or nested, and record why.
  • Remove claims recipients do not need before considering encryption.
  • Pin alg and enc allowlists per token type; reject none and RSA1_5.
  • Use sign then encrypt with cty JWT whenever both properties are needed, and verify the inner signature every time.
  • Set explicit typ values and enforce issuer and audience checks to prevent cross-JWT confusion.
  • Give every key a single algorithm and a use of sig or enc; never share keys across purposes.
  • Validate ECDH-ES ephemeral keys, disable or cap zip decompression, and cap PBES2 p2c.
  • Ignore or allowlist jku, x5u and embedded jwk headers; take keys from pinned configuration.
  • Rotate signing and encryption keys on separate schedules with JWKS overlap windows.

Standards and references

Related NHI Mgmt Group resources: JWT Security Guide · Digital Signatures vs Encryption · JWT vs OAuth · JWT Client Authentication (private_key_jwt) Guide · SD-JWT and SD-JWT VC Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 14 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org