Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/.release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"packages/flarelette-jwt-ts": "1.8.1",
"packages/flarelette-jwt-py": "1.8.2"
"packages/flarelette-jwt-py": "1.8.1"
}
6 changes: 3 additions & 3 deletions THIRD_PARTY_LICENSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ The TypeScript package depends on the following NPM packages:
### TypeScript Package Dependencies Summary

```
@flarelette/jwt-kit-env@1.8.0
@flarelette/jwt-kit-env@1.8.1
│ C:\Users\chris\git\flarelette-jwt-kit
└─┬ @chrislyons-dev/flarelette-jwt@1.8.0 -> .\packages\flarelette-jwt-ts
└─┬ @chrislyons-dev/flarelette-jwt@1.8.1 -> .\packages\flarelette-jwt-ts
│ Environment-driven JWT authentication for Cloudflare Workers with secret-name indirection
└── jose@5.10.0
JWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes
Expand Down Expand Up @@ -77,4 +77,4 @@ This script:

---

**Last generated**: 2025-10-31
**Last generated**: 2025-11-01
2 changes: 1 addition & 1 deletion docs/architecture/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# 🏗️ flarelette-jwt-kit

**Architecture Documentation**
Generated 2025-10-31 12:57:04
Generated 2025-11-01 16:48:43

## Overview

Expand Down
74 changes: 64 additions & 10 deletions docs/architecture/flarelette-jwt-kit-ir.json
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@
"type": "class",
"documentation": {
"summary": "Actor claim for service delegation (RFC 8693).",
"details": "Identifies a service acting on behalf of another principal.\nCan be nested for delegation chains.\n\nStructure:\n sub: Service identifier acting on behalf of original subject\n act: Nested ActorClaim with same structure (recursive delegation chain)"
"details": "Identifies a service acting on behalf of another principal.\nCan be nested for delegation chains.\n\nStructure:\n sub: Service identifier acting on behalf of original subject\n iss: The issuer of the actor token.\n act: Nested ActorClaim with same structure (recursive delegation chain)"
},
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 49,
Expand Down Expand Up @@ -764,7 +764,7 @@
"details": "Includes standard JWT claims, OIDC claims, and common custom claims.\nNote: At runtime, can contain any string key with JwtValue-compatible values,\nbut only defined fields get type checking."
},
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 66,
"lineNumber": 68,
"metadata": {
"language": "python",
"baseClasses": [
Expand All @@ -789,7 +789,7 @@
"details": "Represents the complete configuration profile for JWT operations.\nEnvironment-driven: populated from JWT_* environment variables via profile() function.\nValidates against the JSON Schema at project root for consistency across languages."
},
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 108,
"lineNumber": 110,
"metadata": {
"language": "python",
"baseClasses": [
Expand All @@ -814,7 +814,7 @@
"details": "Subset of JwtProfile containing the fields shared across all operations\n(signing, verification, policy checks). Extracted by common() function\nand merged with algorithm-specific configuration in profile()."
},
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 123,
"lineNumber": 125,
"metadata": {
"language": "python",
"baseClasses": [
Expand Down Expand Up @@ -850,7 +850,7 @@
],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 137,
"lineNumber": 139,
"metadata": {
"language": "python",
"decorators": [],
Expand All @@ -876,7 +876,7 @@
"parameters": [],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 167,
"lineNumber": 169,
"metadata": {
"language": "python",
"decorators": [],
Expand Down Expand Up @@ -909,7 +909,7 @@
],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 181,
"lineNumber": 183,
"metadata": {
"language": "python",
"decorators": [],
Expand Down Expand Up @@ -941,7 +941,7 @@
],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 204,
"lineNumber": 206,
"metadata": {
"language": "python",
"decorators": [],
Expand All @@ -962,7 +962,7 @@
"parameters": [],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 211,
"lineNumber": 213,
"metadata": {
"language": "python",
"decorators": [],
Expand All @@ -983,7 +983,7 @@
"parameters": [],
"isAsync": false,
"filePath": "C:\\Users\\chris\\git\\flarelette-jwt-kit\\packages\\flarelette-jwt-py\\flarelette_jwt\\env.py",
"lineNumber": 226,
"lineNumber": 228,
"metadata": {
"language": "python",
"decorators": [],
Expand Down Expand Up @@ -1998,6 +1998,24 @@
"deployments": [],
"containerRelationships": [],
"componentRelationships": [
{
"description": "copyFileSync | existsSync",
"source": "flarelette_jwt_ts",
"destination": "fs",
"stereotype": "import"
},
{
"description": "dirname | join | resolve",
"source": "flarelette_jwt_ts",
"destination": "path",
"stereotype": "import"
},
{
"description": "imports fileURLToPath",
"source": "flarelette_jwt_ts",
"destination": "url",
"stereotype": "import"
},
{
"description": "imports generateSecret",
"source": "chrislyons_dev_flarelette_jwt__core",
Expand Down Expand Up @@ -2138,6 +2156,42 @@
}
],
"codeRelationships": [
{
"description": "imports copyFileSync",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "fs:copyFileSync",
"stereotype": "import"
},
{
"description": "imports existsSync",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "fs:existsSync",
"stereotype": "import"
},
{
"description": "imports dirname",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "path:dirname",
"stereotype": "import"
},
{
"description": "imports join",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "path:join",
"stereotype": "import"
},
{
"description": "imports resolve",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "path:resolve",
"stereotype": "import"
},
{
"description": "imports fileURLToPath",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/prepare.js",
"destination": "url:fileURLToPath",
"stereotype": "import"
},
{
"description": "imports generateSecret",
"source": "C:/Users/chris/git/flarelette-jwt-kit/packages/flarelette-jwt-ts/src/cli.ts",
Expand Down
18 changes: 9 additions & 9 deletions docs/architecture/flarelette_jwt__util.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ JWT token payload/claims structure.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:66</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:68</code></td>
</tr>
</tbody>
</table>
Expand All @@ -132,7 +132,7 @@ JWT Profile structure matching flarelette-jwt.profile.schema.json.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:108</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:110</code></td>
</tr>
</tbody>
</table>
Expand All @@ -155,7 +155,7 @@ Common JWT configuration from environment variables.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:123</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:125</code></td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -276,7 +276,7 @@ Detect JWT algorithm mode from environment variables based on role.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:137</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:139</code></td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -306,7 +306,7 @@ Get common JWT configuration from environment.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:167</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:169</code></td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -334,7 +334,7 @@ Get JWT profile from environment.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:181</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:183</code></td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -363,7 +363,7 @@ Get JWT profile from environment.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:204</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:206</code></td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -392,7 +392,7 @@ Get JWT profile from environment.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:211</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:213</code></td>
</tr>
</tbody>
</table>
Expand All @@ -419,7 +419,7 @@ Get JWT profile from environment.
</tr>
<tr>
<td><strong>Location</strong></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:226</code></td>
<td><code>C:\Users\chris\git\flarelette-jwt-kit\packages\flarelette-jwt-py\flarelette_jwt\env.py:228</code></td>
</tr>
</tbody>
</table>
Expand Down
4 changes: 4 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,7 @@ nav:
- Cloudflare Workers: cloudflare-workers.md
- Security:
- Security Guide: security-guide.md
- Architecture:
- Overview: architecture/README.md
- TypeScript Package: architecture/chrislyons_dev_flarelette_jwt.md
- Python Package: architecture/flarelette_jwt.md
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "@flarelette/jwt-kit-env",
"version": "1.8.0",
"version": "1.8.1",
"type": "module",
"private": true,
"scripts": {
"archlette": "npx archlette all -f docs\\archlette.config.yaml",
"build": "npm run build --workspaces",
"test": "npm run test:js && npm run test:py",
"test:js": "vitest run",
Expand Down
2 changes: 2 additions & 0 deletions packages/flarelette-jwt-py/flarelette_jwt/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ class ActorClaim(TypedDict, total=False):

Structure:
sub: Service identifier acting on behalf of original subject
iss: The issuer of the actor token.
act: Nested ActorClaim with same structure (recursive delegation chain)
"""

sub: str
iss: str
act: dict[
str, JwtValue
] # Nested ActorClaim (recursive, breaks TypedDict limitation)
Expand Down
4 changes: 2 additions & 2 deletions packages/flarelette-jwt-py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"

[project]
name = "flarelette-jwt"
version = "1.8.2"
version = "1.8.1"
description = "Environment-driven JWT authentication for Cloudflare Workers Python with secret-name indirection"
readme = "docs/README.md"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [{ name = "Chris Lyons", email = "chris@chrislyons.dev" }]
Expand Down
8 changes: 8 additions & 0 deletions packages/flarelette-jwt-ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build output
dist/

# Copied documentation files (generated by prepare.js)
README.md
CONTRIBUTING.md
THIRD_PARTY_LICENSES.md
LICENSE
6 changes: 4 additions & 2 deletions packages/flarelette-jwt-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "@chrislyons-dev/flarelette-jwt",
"version": "1.8.1",
"type": "module",
"description": "Environment-driven JWT authentication for Cloudflare Workers with secret-name indirection",
"keywords": [
"jwt",
Expand Down Expand Up @@ -48,8 +49,9 @@
"flarelette-jwt-keygen": "dist/keygen.js"
},
"scripts": {
"build": "rimraf dist && tsc -p tsconfig.json && cp ../../README.md dist/ && cp ../../CONTRIBUTING.md dist/ && cp ../../THIRD_PARTY_LICENSES.md dist/",
"prepublishOnly": "npm run build"
"prepare": "node prepare.js",
"build": "rimraf dist && tsc -p tsconfig.json",
"prepublishOnly": "npm run prepare && npm run build"
},
"dependencies": {
"jose": "^5.3.0"
Expand Down
30 changes: 30 additions & 0 deletions packages/flarelette-jwt-ts/prepare.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env node
import { copyFileSync, existsSync } from 'fs'
import { dirname, join, resolve } from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const PKG_DIR = resolve(__dirname)
const MD_ROOT = resolve(PKG_DIR, '../..')

const files = [
{ src: join(MD_ROOT, 'README.md'), dst: 'README.md' },
{ src: join(MD_ROOT, 'CONTRIBUTING.md'), dst: 'CONTRIBUTING.md' },
{ src: join(MD_ROOT, 'THIRD_PARTY_LICENSES.md'), dst: 'THIRD_PARTY_LICENSES.md' },
{ src: join(MD_ROOT, 'LICENSE'), dst: 'LICENSE' },
]

console.log(`Copying documentation files from ${MD_ROOT} to ${PKG_DIR} directory...`)

for (const { src, dst } of files) {
if (!existsSync(src)) {
console.error(`ERROR: Missing ${src}`)
process.exit(1)
}
console.log(`Copying ${dst}...`)
copyFileSync(src, join(PKG_DIR, dst))
}

console.log('Copy complete')
6 changes: 4 additions & 2 deletions packages/flarelette-jwt-ts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export interface JwtHeader {
export interface ActorClaim {
/** Service identifier acting on behalf of original subject */
sub: string
/** The issuer of the actor token. */
iss?: string
/** Nested actor for delegation chains (recursive) */
act?: ActorClaim
}
Expand Down Expand Up @@ -216,8 +218,8 @@ export interface Fetcher {
*/
export interface WorkerEnv extends Record<string, unknown> {
// Standard environment variables (strings)
JWT_ISS?: string
JWT_AUD?: string
JWT_ISS?: JwtValue
JWT_AUD?: JwtValue
JWT_TTL_SECONDS?: string
JWT_LEEWAY?: string
JWT_KID?: string
Expand Down
Loading