feat: add JWE (JSON Web Encryption) decryption support#209
Open
bvogel wants to merge 4 commits intoomniauth:masterfrom
Open
feat: add JWE (JSON Web Encryption) decryption support#209bvogel wants to merge 4 commits intoomniauth:masterfrom
bvogel wants to merge 4 commits intoomniauth:masterfrom
Conversation
Adds support for providers that wrap the ID token in a JWE envelope
before returning it (e.g. the Belgian It'sMe identity provider mandates
RSA-OAEP-256 encrypted ID tokens). Previously there was no way to use
such providers with this gem.
New options:
- `id_token_encryption_alg` - the key-wrapping algorithm ('RSA-OAEP',
'RSA-OAEP-256', or 'dir')
- `id_token_encryption_key` - PEM string for RSA algorithms; raw bytes
for 'dir' (direct symmetric key agreement)
`decode_id_token` transparently decrypts the JWE envelope before
passing the inner JWS to the existing verification logic. When
`id_token_encryption_alg` is not set the behaviour is unchanged.
Supported algorithms:
- RSA-OAEP: delegated to the json-jwt gem (already a transitive dep)
- RSA-OAEP-256: custom OpenSSL path - requires OpenSSL >= 3.0
- dir: delegated to the json-jwt gem
Supported content encryption: A128GCM, A256GCM, A128CBC-HS256,
A256CBC-HS512.
All error paths (missing key, bad PEM, decryption failure, unknown enc)
are wrapped in CallbackError to preserve the existing error-handling
contract.
Ref: RFC 7516 (JSON Web Encryption)
|
This looks good to me. Only minor thing I noticed: how about updating the README the options that were added? Overall, the approach seems solid 👍 |
Author
Excellent point, added a section to the README |
Sokre95
reviewed
Mar 5, 2026
| end | ||
|
|
||
| def jwe?(token) | ||
| options.id_token_encryption_alg.to_s != '' && token.to_s.count('.') + 1 == JWE_SEGMENT_COUNT |
There was a problem hiding this comment.
so it's always the same number of segments ?
Author
There was a problem hiding this comment.
for encrypted? yes. Its always 3 for unencrypted and 5 for encrypted
Author
|
We have this code in production for a customer integrating with It'sMe. |
0f1e4c4 to
c3c7835
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Some OpenID Connect providers mandate that ID tokens are wrapped in a JWE (JSON Web Encryption) envelope before being returned to the relying party. A notable example is the Belgian It'sMe identity provider, which requires RSA-OAEP-256 encrypted ID tokens per the OIDC spec (RFC 7516).
There is currently no way to use such providers with this gem.
What this adds
Two new strategy options:
id_token_encryption_alg'RSA-OAEP','RSA-OAEP-256', or'dir'id_token_encryption_key'dir'decode_id_tokenis extended to transparently detect and decrypt a JWE envelope before passing the inner JWS to the existing verification logic. Whenid_token_encryption_algis not configured the behavior is completely unchanged.Supported algorithms
RSA-OAEPRSA-OAEP-256dirError handling
All failure paths (missing key, malformed PEM, decryption failure, unsupported
enc, bad base64) are caught and re-raised asCallbackError, preserving the existing error-handling contract incallback_phase.Tests
New test file
test/lib/omniauth/strategies/openid_connect_jwe_test.rbwith 17 tests covering:jwe?detection (with/without alg configured, 3-segment vs 5-segment)decrypt_jwefor each alg: missing-key errors, delegation to json-jwt, round-trip decryptionDecryptionFailed,CipherError,ArgumentErrordecode_id_tokenintegration (decrypt called for JWE, skipped for JWS)All 53 tests pass (36 existing + 17 new).
References