Skip to content

Commit f3fc994

Browse files
committed
updated Readme.md file
Signed-off-by: Ishan Jogi <ijogi@redhat.com>
1 parent a656bb5 commit f3fc994

File tree

1 file changed

+104
-85
lines changed

1 file changed

+104
-85
lines changed
Lines changed: 104 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,162 @@
11
# JWT Parser Function
22

3-
The JWT Parser function allows Serverless Workflow 1.x workflows to parse and extract information from JWT (JSON Web Token) tokens using jq expressions. This function decodes the JWT payload and optionally extracts specific claims.
3+
A Serverless Workflow 1.x function that decodes JWT (JSON Web Token) payloads using jq expressions. This function provides pure jq-based JWT parsing without external dependencies.
44

5-
## Overview
5+
## Technical Implementation
66

7-
This function uses a `set` task with jq expressions to:
8-
- Decode JWT tokens (with or without "Bearer " prefix)
9-
- Extract the complete JWT payload as JSON
10-
- Optionally extract specific claims using jq paths
7+
This function implements JWT payload extraction through a `set` task using jq expressions:
8+
9+
**Core JWT Decoding Logic:**
10+
```jq
11+
if (.token | startswith("Bearer ")) then
12+
(.token[7:] | split(".")[1] | @base64d | fromjson)
13+
else
14+
(.token | split(".")[1] | @base64d | fromjson)
15+
end
16+
```
17+
18+
**Technical Steps:**
19+
1. **Prefix Handling**: Detects and removes "Bearer " prefix if present
20+
2. **Token Splitting**: Splits JWT on "." to isolate header, payload, signature
21+
3. **Payload Extraction**: Selects the middle part (index 1) containing claims
22+
4. **Base64 Decoding**: Uses `@base64d` to decode the base64url payload
23+
5. **JSON Parsing**: Converts decoded string to JSON object with `fromjson`
24+
6. **Optional Claim Navigation**: Uses jq path expressions for specific claim extraction
1125

1226
## Usage
1327

14-
### Basic JWT Parsing (Complete Payload)
28+
### Complete Payload Extraction
1529

1630
```yaml
1731
document:
1832
dsl: 1.0.0-alpha1
19-
namespace: examples
20-
name: jwt-parsing
33+
namespace: technical
34+
name: jwt-full-decode
2135
version: 1.0.0
2236
do:
23-
- parseToken:
37+
- decodeJWT:
2438
use: jwt-parser
2539
with:
2640
token: ${ .headers.authorization }
41+
# Returns: { claims: {...}, result: {...} }
2742
```
2843

29-
### Extract Specific Claims
44+
### Specific Claim Extraction
3045

3146
```yaml
3247
document:
3348
dsl: 1.0.0-alpha1
34-
namespace: examples
35-
name: jwt-user-extraction
49+
namespace: technical
50+
name: jwt-claim-extraction
3651
version: 1.0.0
3752
do:
38-
- extractUsername:
53+
- extractSubject:
3954
use: jwt-parser
4055
with:
4156
token: ${ .headers.authorization }
42-
claimPath: ".preferred_username"
43-
- extractEmail:
57+
claimPath: ".sub"
58+
# Returns: { claims: {...}, result: "user-id-123" }
59+
- extractNestedClaim:
4460
use: jwt-parser
4561
with:
4662
token: ${ .headers.authorization }
47-
claimPath: ".email"
63+
claimPath: ".custom.department"
64+
# Returns: { claims: {...}, result: "engineering" }
4865
```
4966

50-
### Multiple Claim Extraction
67+
### Token Format Handling
5168

5269
```yaml
5370
document:
5471
dsl: 1.0.0-alpha1
55-
namespace: examples
56-
name: jwt-multi-claims
72+
namespace: technical
73+
name: jwt-format-handling
5774
version: 1.0.0
5875
do:
59-
- getUserInfo:
76+
- parseRawToken:
6077
use: jwt-parser
6178
with:
62-
token: ${ .headers["x-authorization-acme_financial_auth"] }
63-
- processUserData:
64-
use: set
65-
set:
66-
username: ${ .result.preferred_username }
67-
email: ${ .result.email }
68-
userId: ${ .result.sub }
69-
message: ${ "Welcome " + .username + "! Your request has been processed." }
70-
```
71-
72-
## Complete Example - Loan Approval with User Personalization
73-
74-
```yaml
75-
document:
76-
dsl: 1.0.0-alpha1
77-
namespace: examples
78-
name: loan-approval-jwt
79-
version: 1.0.0
80-
do:
81-
- extractUserInfo:
79+
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature"
80+
- parseBearerToken:
8281
use: jwt-parser
8382
with:
84-
token: ${ .headers["x-authorization-acme_financial_auth"] }
85-
- processLoanApproval:
86-
use: set
87-
set:
88-
user: ${ .result.preferred_username }
89-
userId: ${ .result.sub }
90-
email: ${ .result.email }
91-
loanApproved: true
92-
message: ${ "Congrats " + .user + "! Your loan has been approved!" }
83+
token: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.signature"
84+
# Both handle the token format automatically
9385
```
9486

95-
## Parameters
87+
## Function Specification
9688

89+
### Input Parameters
9790
| Parameter | Type | Required | Description |
9891
|-----------|------|----------|-------------|
99-
| `token` | string | Yes | The JWT token to parse (Bearer prefix will be automatically handled) |
100-
| `claimPath` | string | No | jq path to extract specific claim (e.g., ".sub", ".preferred_username", ".email") |
101-
102-
## Output
92+
| `token` | string | Yes | JWT token (raw or with "Bearer " prefix) |
93+
| `claimPath` | string | No | jq path expression for specific claim extraction |
94+
95+
### Output Structure
96+
```json
97+
{
98+
"claims": {
99+
"sub": "user-123",
100+
"preferred_username": "john.doe",
101+
"email": "john@example.com",
102+
"exp": 1234567890,
103+
"iat": 1234567800
104+
},
105+
"result": "..." // Complete payload or specific claim based on claimPath
106+
}
107+
```
103108

104-
The function returns:
105-
- `claims`: The complete decoded JWT payload as JSON object
106-
- `result`: Either the complete payload (if no claimPath) or the specific claim value (if claimPath provided)
109+
## Technical Details
107110

108-
## Token Format Support
111+
### JWT Token Structure
112+
```
113+
header.payload.signature
114+
```
115+
The function processes the **payload** section (index 1 after splitting on ".")
109116

110-
The function supports JWT tokens in various formats:
111-
- Raw JWT token: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`
112-
- Bearer token: `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...`
117+
### jq Expression Breakdown
113118

114-
## jq Expression Details
119+
**Primary Expression:**
120+
```jq
121+
if (.token | startswith("Bearer ")) then
122+
(.token[7:] | split(".")[1] | @base64d | fromjson)
123+
else
124+
(.token | split(".")[1] | @base64d | fromjson)
125+
end
126+
```
115127

116-
The function uses these jq expressions:
117-
- **Token cleanup**: Removes "Bearer " prefix if present
118-
- **JWT decoding**: Splits token, extracts payload (part 1), base64 decodes, and parses JSON
119-
- **Claim extraction**: Uses jq path navigation to extract specific claims
128+
**Claim Path Expression:**
129+
```jq
130+
if .claimPath then
131+
.claims | getpath(.claimPath | split(".") | map(select(. != "")))
132+
else
133+
.claims
134+
end
135+
```
120136

121-
## Common Claim Paths
137+
### Supported Token Formats
138+
- **Raw JWT**: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0.sig`
139+
- **Bearer Format**: `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0.sig`
122140

123-
- `.sub` - Subject (user ID)
124-
- `.preferred_username` - Username
125-
- `.email` - Email address
126-
- `.name` - Full name
127-
- `.given_name` - First name
128-
- `.family_name` - Last name
129-
- `.roles` - User roles array
130-
- `.exp` - Expiration timestamp
131-
- `.iat` - Issued at timestamp
141+
### Claim Path Examples
142+
| Path | Description | Example Result |
143+
|------|-------------|----------------|
144+
| `.sub` | Subject identifier | `"user-123"` |
145+
| `.preferred_username` | Username | `"john.doe"` |
146+
| `.custom.department` | Nested custom claim | `"engineering"` |
147+
| `.roles[0]` | First role in array | `"admin"` |
132148

133-
## Error Handling
149+
## Error Conditions
134150

135-
The jq expressions will fail if:
136-
- Token is null or empty
137-
- Token format is invalid (not 3 parts separated by dots)
138-
- JWT payload is not valid base64 or JSON
139-
- Specified claimPath does not exist
151+
The function will fail with jq errors if:
152+
- **Invalid token format**: Not exactly 3 parts separated by dots
153+
- **Invalid base64**: Payload section cannot be base64 decoded
154+
- **Invalid JSON**: Decoded payload is not valid JSON
155+
- **Invalid claim path**: Specified jq path does not exist in payload
140156

141-
## Security Note
157+
## Implementation Notes
142158

143-
This function extracts claims from JWT tokens without signature verification. In production environments, ensure proper token validation is performed at the API gateway or authentication layer before tokens reach the workflow.
159+
- **No signature verification**: Function extracts claims without cryptographic validation
160+
- **Base64URL decoding**: Uses jq's `@base64d` which handles base64url format
161+
- **Path navigation**: Uses jq's `getpath()` for safe claim extraction
162+
- **Prefix handling**: Automatically detects and strips "Bearer " prefix

0 commit comments

Comments
 (0)