{"_id":"@web-ts-toolkit/express-oidc-vault","_rev":"27-632f55dd841c14712a46d2dbae502847","name":"@web-ts-toolkit/express-oidc-vault","dist-tags":{"latest":"0.47.1"},"versions":{"0.28.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.28.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.28.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"b0203bbce8163d2b2dc9a66b370a73f90e7b5fc2","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.28.0.tgz","fileCount":7,"integrity":"sha512-xnngr0YTbjZ4P1eF2AtkSBbTGkAPFsIRf/+lhqudTSUzzx2pQ5+F/3gOxNdbMkplueqny6VsPtZW37DxUfMU7g==","signatures":[{"sig":"MEUCIB+3n6czuMwY8UGQYWCfzV7/KDb5uwKAqstr+sdn/tvSAiEA/fHB/WLw6DyQxqcb1q3WC0fsJHDBQVHpEHfI2Dnt+5g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"a8ca3bcd945fe21197aeb69a2f6e87be496c373d","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.28.0_1785096877789_0.2145357887504482","host":"s3://npm-registry-packages-npm-production"}},"0.29.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.29.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.29.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"f006f75dc836f5d4f4e2c7a51bf6599697c68b09","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.29.0.tgz","fileCount":7,"integrity":"sha512-UoOhvvW3T0U9eCZior/PbQ/I6CvFtBceSnAhRrWdmlL+foKCU515bIwvKdW9/DBcbdHUto4o/3TVcwxFUm0MWA==","signatures":[{"sig":"MEUCIQClSvbtxREz9Mvtu8H8pYfnnHO3Fd8aMZ76qpVkgc/v7gIgNGUhxxTMco4KLi4DOIuberhOwMq4SBPLsYmA4U+3mVs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"0e738e77429042c0a27398f00f6f6a57903eef17","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.29.0_1785288824050_0.5888921138730401","host":"s3://npm-registry-packages-npm-production"}},"0.30.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.30.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.30.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"80382e07bd37a2bae38623ef39e8782cd967c48a","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.30.0.tgz","fileCount":7,"integrity":"sha512-1ShXlcIzAo46NXJui8O7xyPIC2QtB/XRaUTLSHxeZ7OgD0iq8VLrcc98Cm0p4jkvZs0QAkyPDbvUS3tT9aCMvg==","signatures":[{"sig":"MEYCIQCbtxLZxyBlnM5T4NCLkI4n6DUHA7ivMr4z6gQqKLf8hwIhAIUhWT8UdUDYY1AFGu1uJSZ0MnJHKvW3xFJ+qxyIlC4C","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"f771f097d83c9df4b71456b39296b10f36e6b500","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.30.0_1785305202271_0.5261494738202517","host":"s3://npm-registry-packages-npm-production"}},"0.31.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"bee52db073b1f7f8b5e2ffebb63b5dda2b00e357","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.0.tgz","fileCount":7,"integrity":"sha512-/xUZTWGo4VfW8ijujNrO3t/TuFuAKROVfUFuEXmv6fDyeDoWu49E0jwO7E6Y8a6AHtT/RUzsQwV5n0YUZvcS5g==","signatures":[{"sig":"MEQCIGlxuRR1JcPrfZVDUWkdAN7MwxHSeocVPB9II1W2ORusAiA+dLoH1IwDgUAF6LRtW1JoYeZUSKReMgzDyImNnTQnAw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"0d20494fbfff507bba3337f1a5e8cd577d649c9c","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.0_1785347393063_0.9290717981189422","host":"s3://npm-registry-packages-npm-production"}},"0.31.1":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.1","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.1","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"e68ea42c8e47c9a8970f290f02d6774e7ebfa1ab","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.1.tgz","fileCount":7,"integrity":"sha512-oL4bF5qcMGjz0lA4BhNWTjkfMqj/HJfXvAh/y5JkovEr9BtxnWTflzqOSdPFlFudthN38tAPuDRNxsFgwJzOCQ==","signatures":[{"sig":"MEYCIQCkUoYIgpuICO5r5ALkpxIjKnHBq94j1kuskCQxJyx6kAIhAIyk9bbcvrqCdbvLeGB5c7XEvluwBUapuo3guQyEM3d1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"30acc0ac9988bc92937729d277a7ca9b914836aa","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.1_1785393919756_0.8548311184966224","host":"s3://npm-registry-packages-npm-production"}},"0.31.2":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.2","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.2","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"611dc2616a4b62913673ff72289415d40385c1f4","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.2.tgz","fileCount":7,"integrity":"sha512-7yLiC4Y/J1v7UK0b6aMHluHRG6lNZ2qfBPn1ixSwKW+wYldGS0ThegovijT6ZJLABFLnasHiwWfAAFeQ1UQoqg==","signatures":[{"sig":"MEQCIB0dsi3hl8Z6XVy1MQvKu7YYDjNzgWFR8+FFeu1zu/caAiBMVZBwelDlhwvP9TKAqI1WDQY/eOguM65PrObFPTAj8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"4fbdedac42d06f6866c0419c424355b205659620","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.2_1785441826778_0.6050227778485093","host":"s3://npm-registry-packages-npm-production"}},"0.31.3":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.3","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.3","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"f926bab7725b1acf18d9d81ec37734fb7533a11e","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.3.tgz","fileCount":7,"integrity":"sha512-7Fp79U/gUR8XgHvrHJRIP8k7fGVRMm3i8BKM/IK8UukQ7FliDnrMdW3XYfYckSh8Y9xtKjuU47wG9IIBIVO1IA==","signatures":[{"sig":"MEQCIDiq50wWUmbOFmLPdBnaW4x9O67Oa9DS16WsbRS/Y2bpAiA/cC8h7ncEB1to3lkAI4RUvnvA7g77GkQRtFLdaYDvuw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"291160bd9fa2ffb3f4a27bc542e3c45159c1fa90","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.3_1785445957517_0.502318985871842","host":"s3://npm-registry-packages-npm-production"}},"0.31.4":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.4","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.4","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"7fa21f23689ef1e3c5b691912c727f89ab1e32b7","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.4.tgz","fileCount":7,"integrity":"sha512-8TpKGfqUx5utiwElzJucEln7cm50JkY6yvrpd15/lQkSGjILNDRJTQumrk25s2ZuOYrzF7EbAvv7Yef+fOaGnA==","signatures":[{"sig":"MEUCIQCBzRu9Lrkm3EWgFpYl3Z1yMYybfsyiyy8fSzQDOTkw2AIgChe5Krh4R4s4hKnvfiChc8L0vM0iPlJkEcbyMM4J4RU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"f4975b11112e374cc35a0e5f638053788562a798","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.4_1785449721586_0.678320984409551","host":"s3://npm-registry-packages-npm-production"}},"0.31.5":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.31.5","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.31.5","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"a7c1425c14b869639f89c8c3359e7f15c1390b8a","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.31.5.tgz","fileCount":7,"integrity":"sha512-YW+QOO2Q9u65UpK0/QYjZLHGChBz0bVooi5IzD18E4+qKErP3Kx8M46MRa99ohcVYKTIO4JxN/5bxvn6IIGAvg==","signatures":[{"sig":"MEYCIQDUr0eI3KpxKEOQhEL9uIyf96TgCaL7mmIlsAOPg8SVqQIhANlC+V11TIRglRZ/NrFttMLWq95Xds/arlgP14iGSmMH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"bf0fafe571eb86948c1624babdcfb1ab71e90c62","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.31.5_1785450552923_0.3151515238096698","host":"s3://npm-registry-packages-npm-production"}},"0.32.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.32.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.32.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"70405f0157852cf6f153ffddf575df0088be37f7","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.32.0.tgz","fileCount":7,"integrity":"sha512-R/wY+Vplz4S/IgGNgi8LP2pa8mPT/8J3qoDZLOJaJ6GSg334fXIs1yy3JZNnmO7Owq/D4bxiMnPW16uSgUnENg==","signatures":[{"sig":"MEUCIQCgFSERdc1Nq4OcmAoPEj5G8357/LsgaItG7McKo0MIXAIgJnZ2lgh2Mco5Of1xAvKMD0spnT+d+FPB7rApCcSOm1Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":134050},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=20"},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"d47498b9113ecab5de3d866fa6059b03d2436716","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"Cookie-free OIDC session middleware for Express with pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.32.0_1785612102027_0.5237459318932849","host":"s3://npm-registry-packages-npm-production"}},"0.33.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.33.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.33.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"7b889cfa29da43effc54a1ad5e874b7f12556dfb","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.33.0.tgz","fileCount":7,"integrity":"sha512-0PVozDZ58U2kppxA/Y0Ft2iIt1cA86GsPNpnIRz0/jUU/0rkloAB43sXPd3xC3IoBNFL3nXZZoZlH57LPEbOSw==","signatures":[{"sig":"MEUCIDoCHc/jRxeqQOugXGm5sm+R1ncwTOvi1/GGaECM+sY2AiEA6TZTb46jcN5L3HKy9G0snnpxo5xTSeWvv1n3OUG+ub4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"6c0dbaf789971b0dceb8447e865cea5fa055b433","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.17.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.5.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.33.0_1786738050729_0.42980299348854367","host":"s3://npm-registry-packages-npm-production"}},"0.34.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.34.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.34.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"f030ed955f8ce629250c357402ef47482756e0a8","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.34.0.tgz","fileCount":7,"integrity":"sha512-wUctzXBwwUth12utvpDFyoX9H33mfdMYuHLjn14fjcLT8BYg6mGxcQYQjNFU0i6DcNuXs+oxK6uiW1F1AGeS1A==","signatures":[{"sig":"MEYCIQDCIAK72x/cqbZ6vjzEwPjlcLlylQD0pDTkr36s5wMPMAIhANrj4ic6blSmTpCo6cQ0R3yLh+pWkjmNXg/bVAifZw8O","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"4b775162a5edb5bf676db5d21651e2af2063980b","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.34.0_1786766944600_0.9624608946161335","host":"s3://npm-registry-packages-npm-production"}},"0.34.2":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.34.2","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.34.2","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"57f6d824b7806ecc1194a300790a57bf1d78a591","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.34.2.tgz","fileCount":7,"integrity":"sha512-EaaCAcVLxT6e6sESPD4r9kEHe2A8AKFy5ADkCbzolPm5kX7cEHy/LZEzXvCIINJPa8KDL9KNTg/xWnQKrCWhbg==","signatures":[{"sig":"MEQCIETB5OpLLtfLS6t72/y3QeXRbrNWYmb4HZ0foP6LdkXGAiBTiF/JIiKEAKejyS1w0b/lCtEtbvKhhiJcXYSOdhS9sw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"6024e206d84d9dc5313554d293d4d3595ffb4cef","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.34.2_1786771670355_0.13834380812632663","host":"s3://npm-registry-packages-npm-production"}},"0.34.3":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.34.3","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.34.3","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"a1cd8ac47e18b41b92ece32bb7eb0ff32deceb7b","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.34.3.tgz","fileCount":7,"integrity":"sha512-fhhmKwqZ2tK+OjETBbmPrg23TVKbKqgRtuAwMwWyK2DZY/fZ1EsqIr3pelVhW5UHLCBCZNc9gcUIvpUIs/sLRA==","signatures":[{"sig":"MEQCIDeVbe7Y4EJDws5m6GTLprcz3DM2APzqLL5sUwEEWPytAiAPyuPG/wzGO7OtrRk82Ld/QyWc6P1HjizhEgME6NIg/g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"cc9d772e356270023e1e314c7d8939fe4d091f4b","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.34.3_1786776310313_0.9363971449839199","host":"s3://npm-registry-packages-npm-production"}},"0.35.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.35.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.35.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"6db682810c40f1b72e5b699dd73630160d849456","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.35.0.tgz","fileCount":7,"integrity":"sha512-ttdrPKd5Mk2qgxn0h7zbX9Uyh4FRWtGbyWUYp5NXSu9sIRt1esnwWT/8bS223tGVZxP+QKO2nC1kUxQswBhdqw==","signatures":[{"sig":"MEQCICWf7kB8AWPcCXQJOjHtBIw69oEnTdSToT6o9yXH+aiJAiBrWOSxFy9KM9Z98cEliJDFgpnl+j4YDLZZQ3r2ljyqmw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"e6355c8b5150b68f43d182ec8ac1c76b4bae44e0","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.35.0_1787083322238_0.23910336820691258","host":"s3://npm-registry-packages-npm-production"}},"0.36.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.36.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.36.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"04ce1caeacac7faa94abd5743a3c4bdc79e8b2d0","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.36.0.tgz","fileCount":7,"integrity":"sha512-//CjJ6pKkP3qVvArYINacg5cKaGfHOcEFWfTtAPa8noXuvDWHUAAqjoq5RlwENU0KW/ImXSkSl1fpBdrjBaa1g==","signatures":[{"sig":"MEUCIDk8qAuMaqBV6QU+hf9iGlSN5dZ2gdPJK5tLn9fAEjSWAiEAkM8kEZ/EpZfnDMAAlNjp1FtUCMTi5bPWVmHdkZmyXK4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"bc0ab139683fc133978de6cb10945ef4aa37c070","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.36.0_1787087025727_0.3118110848113711","host":"s3://npm-registry-packages-npm-production"}},"0.37.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.37.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.37.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"00db0f112198016348fc9d8e031741b40db6732a","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.37.0.tgz","fileCount":7,"integrity":"sha512-aorD9yKauS7TqkQ4uxPujD/Xgy0w5zW0Ycp149qTgE2cjzQZ2KGoKdcHhUeU/z0Vxsd5t+EchJFL0NKIsVT5wQ==","signatures":[{"sig":"MEUCIQD9gqdowlbOJE6oyjtyxnUZam6soToweLXHZ5c63j6JFQIgZFxVrsjU3aJcoMOq7WM94aXbE+LdrMb2meCz+2zoF3k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"790535ea132e68a3174ebf755da586455ee1bf89","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.37.0_1787243166044_0.9717562889378959","host":"s3://npm-registry-packages-npm-production"}},"0.38.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.38.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.38.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"e80e5d7303a12bf18b4e41b5d774b3a76db9b12e","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.38.0.tgz","fileCount":7,"integrity":"sha512-fVsWgQodTaXEEP1vBq99JKhQX6X6g0Db6Id2C81E9gYm9VFOtyxKCh34tfNivW+lKbzpABach1mFTwArdUTMVg==","signatures":[{"sig":"MEQCIGsTS9eV70Q6hIHSnUfOZWAiBAoOARgZubDN3poxql4JAiBuFbZ+AQmCIrOlZr/FOWmCwxMrxaAxV3H0Q268dw+Vew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"02308fd9625274ada5d4d65b70ed2d204d4cbbaf","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.38.0_1787268140289_0.6061180488095541","host":"s3://npm-registry-packages-npm-production"}},"0.39.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.39.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.39.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"147ec8e284a32ef0ed9b680d3c1a14f20d43e39f","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.39.0.tgz","fileCount":7,"integrity":"sha512-9AZ3TPPmxvN0lxe4ib2phBtctVtdON4RvoW8b4n4Uzkbsonqb2Y0I+fjkU2Q2xYDJozoryLkX8DWFM9KEXiv0g==","signatures":[{"sig":"MEUCIAM3M0a0MJkDrrdp5RuFvJpaiakweV1TG5OBAR09jTseAiEAvoHgPLP6zkYkJbH5iJ8VE1o6tQADFRU26uces/bQ5/E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"25f4fef8af0084275566346aaea52f64677b2b18","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.39.0_1787361925954_0.7566610902065736","host":"s3://npm-registry-packages-npm-production"}},"0.40.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.40.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.40.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"f73a352be012971e4e3632d998651052b1656a8f","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.40.0.tgz","fileCount":7,"integrity":"sha512-8x6FCE0DUm1YJrvlyOLRM078ppxozcwu0xd+8TeJopKaxRYmhy70qYsB4hFknIsr8neijxRxYGtlaVYcbN7N8A==","signatures":[{"sig":"MEUCIQDmxFKSXtfus9m8klh6SSQg6fOI7AInyLhXi/2RyjqI2AIgW3P49bZS74Nl/5tAQksaiJzc1/V1U2Q0CZlJ23ST2Zs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"38c7a372d3e6be38536d11fd5fc0c569d1ed5c73","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.40.0_1787437254905_0.4208625762357072","host":"s3://npm-registry-packages-npm-production"}},"0.40.1":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.40.1","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.40.1","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"083f8bba29d8daccd4575d2d6826757e7e7ad360","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.40.1.tgz","fileCount":7,"integrity":"sha512-tlSjRJvHXaKclgKwIZdgllRYnibTdBsH6Df9xItUnsLM+BQkSFEzWLr1UvgnI7A1oOEbeMewZyGJvtUU1vBhWw==","signatures":[{"sig":"MEUCIQC/DFGXSSAyNu+HNRJsij+UAv1fdjkw1N6JABkR6qtklQIgCZGqhOl71ib3gYu4WBnPFFU+Wrs8SEjjtJN7skbFa7I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"2f18781c5473803b1975527c3e8b268cbbfefc32","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.40.1_1787443371812_0.38455562425723055","host":"s3://npm-registry-packages-npm-production"}},"0.41.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.41.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.41.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"b44160188c224b67a30c78a4b4243e5f16055acf","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.41.0.tgz","fileCount":7,"integrity":"sha512-cSjcs7ByxqZjC58uTMa9xQoXidVgL/XH/rxx0wQ1DKj7oi4S0ImsWM8fjf7CjcjGCzwwXqDAW6s4OxEsuAN62g==","signatures":[{"sig":"MEUCIQCGitrhOpNpnH2SS3acDZ1FizpPmFdwKPu31bMuiPHmbAIgJDc/AKQMX9SRV8ZKg3tXuXT4I+eqNX3IitvyJJj2714=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"e6bb90c90e8eeb1246cef31e2f1d3fc88a643a52","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.41.0_1787603971160_0.14099451184410827","host":"s3://npm-registry-packages-npm-production"}},"0.42.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.42.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.42.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"ec6f64815681e3fefa0a634dbbef1ab759349269","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.42.0.tgz","fileCount":7,"integrity":"sha512-+9schEn0EJ54ow4MI7Ry6tjG6C97Tqyq8QcUlDCfbSnfOQqotKWV4duqmBzLKXoro+G7jgv5yG+G2muDQwDLzA==","signatures":[{"sig":"MEUCIQCjTYZKMAR+9R8n4WPDeim7SgaDX/+IMEvucu4Hu1ExiQIgfr2MEw8q5s06I6bNna0aWnvmQvLEsN7a5qh6jwp8ALU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"d3628cce447c21a912079fb06ec8b2bb4e42fd61","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.42.0_1787932386125_0.4289941078894015","host":"s3://npm-registry-packages-npm-production"}},"0.42.1":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.42.1","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.42.1","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"5b6b4e89bfed8b8385706905d1f0e6d5565f8712","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.42.1.tgz","fileCount":7,"integrity":"sha512-41lkdeI/rhAXdZib8+DR60Q6j4NxO4CpAfuCRpLhfB5/jsIL8Co1jy6kcxxk8n1Uk4fow4oPHNAykLsQxyIrmw==","signatures":[{"sig":"MEUCIQCSehV8vYWAIRFE+cvaP9wHKRKsOuQoprR8T7WglhveawIgDSvHbn/4wjvevPjpa7Vt3hKLCqeAy0FGzEJL8PCJFiQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"51cb36bd600655f6ee817ac605d2f5f6946abdc4","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.42.1_1787935095346_0.13446351021922842","host":"s3://npm-registry-packages-npm-production"}},"0.42.2":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.42.2","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.42.2","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"8223b3755f7065b9c9e3117d6a79f55e4338d380","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.42.2.tgz","fileCount":7,"integrity":"sha512-vMrfMnMH1E0B2KKTm5ZePElfRpUXj55Fdefjh7S6BDs1XONstwHyPmlyGJIpKfdjqBOCP98RS6ZiMYFYUZz+eA==","signatures":[{"sig":"MEQCICgc/9PhsxzyyBzgXuSlUT1Y9gXBBGshQMLOMWHEYk5AAiB4AR8x5lHl6f+EFRsOYGP8DqF9pQIXsAtvkYt1yXpL3Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"fef4e010dbb8c78a09b41f2a5200a92b34752fca","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.42.2_1787936388929_0.865982436912371","host":"s3://npm-registry-packages-npm-production"}},"0.43.0":{"name":"@web-ts-toolkit/express-oidc-vault","version":"0.43.0","keywords":["express","oidc","oauth","session","authentication"],"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","_id":"@web-ts-toolkit/express-oidc-vault@0.43.0","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"b2854f66f5aa26d862bb009449811d0686b70658","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.43.0.tgz","fileCount":7,"integrity":"sha512-aMKN+gyu3Z+5F2hCu3DqsCmBggmnvQJj10XJtJsFmxz70DM9NFqqkeocSEpQox1PBx+ZsPK/1NHWt3mARtx/sw==","signatures":[{"sig":"MEYCIQD2S6ejVEwnus9JegC9+X56JMS99fFYtp3mmO1iBRl2QAIhAKL0DaUlBy/bTo5gamRgJokLxGQfbpfa52532rUWdAQC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187919},"main":"./index.js","types":"./index.d.ts","module":"./index.mjs","engines":{"node":">=22"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"72ddbf5ccee387767b6edcc0786e0fe7ad815a39","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/express-oidc-vault_0.43.0_1788237048602_0.03361338793520052","host":"s3://npm-registry-packages-npm-production"}},"0.47.1":{"_id":"@web-ts-toolkit/express-oidc-vault@0.47.1","bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"dist":{"shasum":"9a17d43af8c7788e311f9ea0cb12a4af8fd02219","tarball":"https://registry.npmjs.org/@web-ts-toolkit/express-oidc-vault/-/express-oidc-vault-0.47.1.tgz","fileCount":7,"integrity":"sha512-onyUAHrrD1dSTabKRX3dyYjXV2YfzyR04fkZSXLFL2jpTvaST7l+hfWnpzM+BpgJgr0waaQdsVbAPWy0EH/Flw==","signatures":[{"sig":"MEYCIQCHLSZdbe+YRLzf69Y3/of1OpR9bVT/NwCx8hGt7oSJJQIhAOdZBE1hUjTgyhfdfqL2o0Nmg/F4SEZieDGDQEXR1fub","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCI3BmrzOw+puzdrfvxdT5IYa8u8xCu5RIaV7JbyoK6WQIgT2AioDLoOfdYjEUX1YAAVtn3RAexPZU5uTWGi/anntY="}],"unpackedSize":286005},"main":"./index.js","name":"@web-ts-toolkit/express-oidc-vault","types":"./index.d.ts","author":{"name":"Junmin Ahn"},"module":"./index.mjs","engines":{"node":">=22.12.0"},"exports":{".":{"types":{"import":"./index.d.mts","default":"./index.d.ts","require":"./index.d.ts"},"import":"./index.mjs","default":"./index.js","require":"./index.js"}},"gitHead":"ee4d553b7b38f6ba17231fa0502d8e36beb31fdd","license":"Apache-2.0","version":"0.47.1","_npmUser":{"name":"junminahn","email":"junminahn@outlook.com"},"homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","keywords":["express","oidc","oauth","session","authentication"],"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"_npmVersion":"11.19.0","description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","directories":{},"maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"sideEffects":false,"_nodeVersion":"26.7.0","dependencies":{"jose":"^6.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"express":">=5.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/express-oidc-vault_0.47.1_1790919739166_0.12270229788078568"}}},"time":{"created":"2026-07-26T20:14:37.623Z","modified":"2026-10-02T05:42:19.973Z","0.28.0":"2026-07-26T20:14:37.912Z","0.29.0":"2026-07-29T01:33:44.198Z","0.30.0":"2026-07-29T06:06:42.444Z","0.31.0":"2026-07-29T17:49:53.236Z","0.31.1":"2026-07-30T06:45:19.911Z","0.31.2":"2026-07-30T20:03:46.913Z","0.31.3":"2026-07-30T21:12:37.683Z","0.31.4":"2026-07-30T22:15:21.763Z","0.31.5":"2026-07-30T22:29:13.074Z","0.32.0":"2026-08-01T19:21:42.168Z","0.33.0":"2026-08-14T20:07:30.908Z","0.34.0":"2026-08-15T04:09:04.755Z","0.34.2":"2026-08-15T05:27:50.519Z","0.34.3":"2026-08-15T06:45:10.452Z","0.35.0":"2026-08-18T20:02:02.394Z","0.36.0":"2026-08-18T21:03:45.887Z","0.37.0":"2026-08-20T16:26:06.218Z","0.38.0":"2026-08-20T23:22:20.523Z","0.39.0":"2026-08-22T01:25:26.111Z","0.40.0":"2026-08-22T22:20:55.043Z","0.40.1":"2026-08-23T00:02:51.954Z","0.41.0":"2026-08-24T20:39:31.327Z","0.42.0":"2026-08-28T15:53:06.259Z","0.42.1":"2026-08-28T16:38:15.469Z","0.42.2":"2026-08-28T16:59:49.070Z","0.43.0":"2026-09-01T04:30:48.741Z","0.47.1":"2026-10-02T05:42:19.290Z"},"bugs":{"url":"https://github.com/egose/web-ts-toolkit/issues"},"author":{"name":"Junmin Ahn"},"license":"Apache-2.0","homepage":"https://web-ts-toolkit.pages.dev/docs/packages/express-oidc-vault","keywords":["express","oidc","oauth","session","authentication"],"repository":{"url":"git+https://github.com/egose/web-ts-toolkit.git","type":"git","directory":"packages/express-oidc-vault"},"description":"OIDC session middleware for Express with body or cookie transport and pluggable vault stores","maintainers":[{"name":"junminahn","email":"junminahn@outlook.com"}],"readme":"# `@web-ts-toolkit/express-oidc-vault`\n\nOIDC session middleware for Express with body or cookie session transport and server-side storage of upstream refresh tokens and logout-capable `id_token`s.\n\n## Status\n\nThis package now implements the core OIDC flow with body or cookie session transport.\n\nCurrent implementation includes:\n\n- the core middleware factory\n- OIDC login redirect with PKCE, `state`, and `nonce`\n- callback token exchange, server-side session creation, and one-time local exchange codes\n- session refresh with session ID rotation\n- server-driven upstream logout redirect using stored `id_token`\n- OIDC backchannel logout handling via `logout_token`\n- public TypeScript interfaces for hooks, sessions, config helpers, and store providers\n\n## Installation\n\n```sh\npnpm add @web-ts-toolkit/express-oidc-vault express\n```\n\nFor the quick start, also install `@web-ts-toolkit/express-oidc-vault-memory-store`. TypeScript applications need `@types/express` and `@types/node` as development dependencies. Express `>=5.0.0` is the runtime peer dependency.\n\nUse **named imports from the package root**. There is no default export or public subpath API.\n\n## Requirements\n\n- Node.js `>=22.12.0`. The published CJS entry (`index.js`) synchronously requires the ESM-only `jose` dependency, which needs Node's `require(esm)` support. That support is enabled by default starting with Node `22.12.0`; earlier Node 22 releases fail to load the CJS root with `ERR_REQUIRE_ESM` unless an experimental flag is passed. Both the CJS (`require`) and ESM (`import`) roots load without experimental flags on every verified runtime (`22.12.0`, `22.18.0`, `22.20.0`, `24.x`, `26.x`).\n- TypeScript consumers typecheck with `skipLibCheck: false` under strict `NodeNext`/`Bundler` settings. ESM consumers resolve the `import` declaration condition (`index.d.mts`); CommonJS (`.cts`) consumers resolve the `require` condition (`index.d.ts`). Both include the public Express `req.auth` augmentation. Workspace builds place these files under `dist/`; release packaging moves them to the package root and rewrites metadata accordingly. Consumer imports always use the package name.\n\n## Frontend Storage Policy\n\nDefault browser-side transport:\n\n- mirror `sessionId` into `sessionStorage`\n- keep `accessToken` in memory only\n- do not store either value in `localStorage`\n\nWhy:\n\n- `sessionId` needs to survive page refresh so the frontend can call `POST /auth/oidc/refresh` during app bootstrap\n- `accessToken` is the credential used on normal API requests and should remain non-persistent in the browser\n- `sessionStorage` is still readable by JavaScript, so it reduces persistence but does not remove XSS risk\n\nOptional alternative:\n\n- set `sessionTransport: 'cookie'`\n- store `sessionId` in an `HttpOnly` browser cookie instead of `sessionStorage`\n- keep `accessToken` in memory only\n\nThat mode simplifies the frontend and keeps the session pointer out of JavaScript-visible storage, but it reintroduces cookie deployment concerns such as `SameSite`, `Secure`, and cross-origin credential handling.\n\n## Session Transport Modes\n\nThe package supports two ways to move the opaque `sessionId` between browser and backend.\n\n### `sessionTransport: 'body'`\n\nThis is the default mode.\n\n- `exchange` and `refresh` responses include `sessionId`\n- the frontend stores `sessionId`, typically in `sessionStorage`\n- the frontend sends `sessionId` back in the JSON body for `refresh` and `logout`\n- `refresh` and `logout` do not read session cookies in this mode\n\n### `sessionTransport: 'cookie'`\n\nThis mode stores `sessionId` in a backend-managed cookie.\n\n- `exchange` sets the session cookie and omits `sessionId` from the JSON body\n- `refresh` reads the cookie, rotates the session, and updates the cookie\n- `logout` reads the cookie and clears it\n- `refresh` and `logout` require the cookie and reject body-only `sessionId` values\n- the frontend does not need to keep `sessionId` in `sessionStorage`\n\nBackchannel logout is separate from both transport modes because it is a server-to-server request from the IdP and does not rely on browser storage at all.\n\nAvailable cookie options:\n\n- `cookie.name`\n- `cookie.deploymentMode`: `'same-origin' | 'same-site' | 'cross-site'`\n- `cookie.sameSite`: `'lax' | 'strict' | 'none'`\n- `cookie.secure`\n- `cookie.domain`\n- `cookie.path`\n- `trustedOrigins`: browser origins allowed to call cookie-authenticated `refresh` and `logout`; required when cross-site cookie transport is enabled\n\n`cookie.httpOnly` is always enforced as `true`. Middleware creation rejects `httpOnly: false` and unsafe cookie names, domains, or paths so untrusted values cannot be serialized into `Set-Cookie` headers. `__Secure-` names require an effectively `Secure` cookie; `__Host-` names additionally require no `cookie.domain` and `cookie.path: '/'`.\n\nDefault cookie behavior:\n\n- `name`: `oidc_vault_session`\n- `path`: `/`\n- `httpOnly`: `true`\n- `deploymentMode`: `same-origin`\n- `sameSite`: `lax` unless `deploymentMode` is `cross-site`\n- `secure`: `true` for HTTPS `backendOrigin`, `sameSite: 'none'`, or `deploymentMode: 'cross-site'`; otherwise `false` as an intentional HTTP local-development policy (set `secure: true` explicitly when terminating TLS upstream of an `http` origin, or `secure: false` explicitly to opt out on HTTPS)\n- `SameSite=None` is always serialized with `Secure` because browsers reject `SameSite=None` without it, even with explicit `secure: false`\n\nCookie-authenticated `refresh` and `logout` requests use a fail-closed CSRF policy for every `SameSite` mode. The request must include an `Origin` header, or a valid `Referer` header, whose origin matches `backendOrigin` or one of the configured `trustedOrigins`. Requests with no source-origin header are rejected. Backchannel logout is not affected because it is authenticated with the signed OIDC logout token rather than the browser session cookie.\n\nRecommended frontend boot flow:\n\n1. Read `sessionId` from `sessionStorage`.\n2. If present, call `POST /auth/oidc/refresh` immediately.\n3. If refresh succeeds, replace the stored `sessionId` with the rotated value and keep the returned `accessToken` in memory only.\n4. If refresh fails, clear `sessionStorage` and treat the user as logged out.\n\nIf you use `sessionTransport: 'cookie'`, the frontend boot flow becomes simpler:\n\n1. Keep `accessToken` in memory only.\n2. Call `POST /auth/oidc/refresh` on app startup.\n3. Let the backend read and rotate the session cookie.\n4. Clear in-memory auth state if refresh fails.\n\n## Endpoints\n\nThe core middleware exposes these endpoints under a configurable base path:\n\n- `GET /auth/oidc/login`\n- `GET /auth/oidc/callback`\n- `POST /auth/oidc/exchange`\n- `POST /auth/oidc/refresh`\n- `POST /auth/oidc/logout`\n- `POST /auth/oidc/backchannel-logout`\n\nThe mounted OIDC router parses JSON and `application/x-www-form-urlencoded` request bodies with an explicit default limit of `16kb`. This covers the small route payloads used by `exchange`, `refresh`, `logout`, and form-encoded backchannel logout. If an IdP requires a larger `logout_token`, set `requestBodyLimit` to a string or byte count accepted by Express body parsers.\n\nParser failures return a JSON client error before route handlers or store/provider hooks run. The stable error codes are:\n\n- `OIDC_VAULT_REQUEST_BODY_TOO_LARGE`\n- `OIDC_VAULT_REQUEST_BODY_PARAMETER_LIMIT_EXCEEDED`\n- `OIDC_VAULT_UNSUPPORTED_REQUEST_BODY_ENCODING`\n- `OIDC_VAULT_MALFORMED_REQUEST_BODY`\n- `OIDC_VAULT_INVALID_REQUEST_BODY`\n\n## Quick Start\n\n```ts\nimport express from 'express';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createMemoryOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-memory-store';\n\nconst app = express();\nconst storeProvider = createMemoryOidcVaultStore();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    storeProvider,\n    sessionTtlMs: 8 * 60 * 60 * 1000, // Opt in to an eight-hour absolute session lifetime.\n  }),\n);\n```\n\nUse the memory store for local development and tests. For production deployments, prefer a Redis or MongoDB store provider.\n\n`backendOrigin` must be the public backend origin registered with your OIDC provider, such as `https://api.example.com`. Callback `redirect_uri` values are built from this pinned origin and the configured `basePath`, so reverse proxies and untrusted `Host` headers cannot change the provider callback URL. Configure Express `trust proxy` only for other request metadata needs; it is not used to derive the OIDC callback origin.\n\n## Public Options And Defaults\n\n| Option                          | Default                              | Contract                                                                                                                                                                                                                                             |\n| ------------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `basePath`                      | `/auth/oidc`                         | Mount path for the OIDC router. Route paths listed in this README are relative to this value.                                                                                                                                                        |\n| `backendOrigin`                 | required                             | Public backend origin registered with the OIDC provider. Callback redirect URIs are derived from this pinned origin, not request host headers.                                                                                                       |\n| `storeProvider`                 | required                             | Durable vault store provider. Use Redis or MongoDB for production and multi-instance deployments.                                                                                                                                                    |\n| `config`                        | required provider values             | Supply `issuer` and `clientId`, or use `resolveOidcVaultConfigFromEnv(process.env)`. Endpoint settings select manual mode; see Config Helpers.                                                                                                       |\n| `frontendRedirectUri`           | unset                                | Default browser return target after backend callback completion. Required if login accepts a custom `returnTo`. Validated before durable callback state; missing destination fails the callback with `500 OIDC_VAULT_MISSING_FRONTEND_REDIRECT_URI`. |\n| `postLogoutRedirectUri`         | unset                                | Optional provider-registered HTTP(S) URL used in the upstream end-session redirect. Only consulted for redirected logout (`redirect: true`); upstream failures fall back to local `200 { loggedOut: true }` with `onError`.                          |\n| `fetchUserInfo`                 | implementation default               | When enabled, UserInfo claims are fetched and merged only after the `sub` matches the verified ID token subject.                                                                                                                                     |\n| `authorizationTransactionTtlMs` | `600000`                             | TTL for one-time authorization transactions created during login.                                                                                                                                                                                    |\n| `exchangeCodeTtlMs`             | `30000`                              | TTL for one-time local exchange codes returned to the frontend callback route.                                                                                                                                                                       |\n| `sessionTtlMs`                  | unset                                | Opt-in positive safe-integer lifetime in milliseconds from callback session creation. Hooks may shorten it; refresh never extends it.                                                                                                                |\n| `sessionTransport`              | `body`                               | `body` returns and accepts JSON `sessionId`; `cookie` stores the session pointer in an `HttpOnly` cookie and rejects body-only refresh/logout IDs.                                                                                                   |\n| `cookie`                        | see cookie defaults above            | Cookie transport options. `httpOnly` is always enforced as `true`; unsafe names, paths, domains, and `__Secure-`/`__Host-` prefix violations are rejected.                                                                                           |\n| `trustedOrigins`                | `[]` plus `backendOrigin` internally | Browser origins allowed to call cookie-authenticated `refresh` and `logout`. Required for cross-site cookie transport.                                                                                                                               |\n| `requestBodyLimit`              | `16kb`                               | Express JSON and URL-encoded parser limit for OIDC route bodies. Increase only for known provider backchannel logout token size needs.                                                                                                               |\n| `providerRequestTimeoutMs`      | `5000`                               | Deadline per provider HTTP exchange (headers plus complete body). Cancellation is attempted without awaiting cleanup. Positive finite integer; validated before cache lookup.                                                                        |\n| `hooks`                         | unset                                | Pre-commit hooks can veto operations by throwing; post-commit notification hook failures are reported to `onError` without undoing committed state.                                                                                                  |\n| `tokenIssuer`                   | unset                                | Issues app-local access tokens for `exchange` and `refresh`. This lifetime is separate from upstream token and vault-session lifetimes.                                                                                                              |\n\nConstruction takes an internal resolved snapshot of the options object without mutating it: normalized values are stored on the snapshot, `cookie`/`trustedOrigins`/`config` containers are shallow-copied, and `storeProvider`/`hooks`/`tokenIssuer`/`now` service references are retained live (never deep-cloned). Frozen inputs work, reused inputs are not mutated, and mutating or replacing the caller object after creation has no effect on the created router.\n\n## Absolute Session Lifetime\n\nThe quick start opts in with `sessionTtlMs: 8 * 60 * 60 * 1000`. New server-side sessions receive `expiresAt = now + sessionTtlMs` at **callback session creation**, not login start. Refresh preserves that timestamp. At `now >= expiresAt`, the store treats the session as expired, so exchange and refresh can no longer use it, even if an exchange code is still live.\n\nBefore `onBeforeSessionCreate`, the session already has its expiry. A hook may shorten it with a valid integer epoch-millisecond timestamp. Removing, extending, or assigning an invalid expiry restores the original cap after the hook; hook delay and changes to `createdAt` do not move that cap. For example, add this optional hook to the middleware options to shorten new sessions to one hour:\n\n```ts\nhooks: {\n  onBeforeSessionCreate({ session }) {\n    if (session?.expiresAt !== undefined) {\n      session.expiresAt = Math.min(session.expiresAt, session.createdAt + 60 * 60 * 1000);\n    }\n  },\n},\n```\n\nOmitting `sessionTtlMs` assigns no default session expiry and retains application/hook/store-owned policy. Enabling it affects new sessions; it does not retrofit existing sessions. Upstream OAuth `expires_in`, local access-token lifetime, and vault-session lifetime are independent.\n\n`authorizationTransactionTtlMs` (default 10 minutes), `exchangeCodeTtlMs` (default 30 seconds), and optional `sessionTtlMs` must be positive safe-integer numbers of milliseconds. Construction rejects zero, negative, fractional, nonnumeric, null, NaN, infinite, and unsafe values. It samples `now` (default `Date.now`): the clock and computed expiry must be integer epoch milliseconds within JavaScript Date's inclusive ±8,640,000,000,000,000 ms range, with expiry after now. Record creation rechecks computed expiries; an unusable later clock/expiry returns sanitized HTTP 500 / `OIDC_VAULT_INTERNAL_ERROR` before new transaction/session/code persistence, with the original error available to `hooks.onError`.\n\n## Frontend Integration Example\n\nThe backend flow is only half of the integration. In default body transport mode, keep `accessToken` in memory, mirror `sessionId` into `sessionStorage`, and deduplicate refresh calls.\n\nThe shared promise below coordinates callers in this JavaScript context only. It does not coordinate tabs, backend instances, or response arrival order; see [Known Browser And Concurrency Limits](#known-browser-and-concurrency-limits).\n\n```ts\ntype AuthState = {\n  accessToken: string | null;\n  sessionId: string | null;\n};\n\nconst authState: AuthState = {\n  accessToken: null,\n  sessionId: sessionStorage.getItem('sessionId'),\n};\n\nlet refreshPromise: Promise<void> | null = null;\n\nfunction persistSessionId(sessionId: string | null): void {\n  authState.sessionId = sessionId;\n\n  if (sessionId) {\n    sessionStorage.setItem('sessionId', sessionId);\n  } else {\n    sessionStorage.removeItem('sessionId');\n  }\n}\n\nfunction setAuthState(payload: { accessToken?: string; sessionId: string }): void {\n  authState.accessToken = payload.accessToken ?? null;\n  persistSessionId(payload.sessionId);\n}\n\nfunction clearAuthState(): void {\n  authState.accessToken = null;\n  persistSessionId(null);\n}\n\nasync function exchangeCallbackCode(code: string): Promise<void> {\n  const response = await fetch('/auth/oidc/exchange', {\n    method: 'POST',\n    headers: { 'content-type': 'application/json' },\n    body: JSON.stringify({ code }),\n  });\n\n  if (!response.ok) {\n    clearAuthState();\n    throw new Error('OIDC code exchange failed.');\n  }\n\n  setAuthState(await response.json());\n}\n\nasync function refreshAuthState(): Promise<void> {\n  if (!authState.sessionId) {\n    clearAuthState();\n    return;\n  }\n\n  const response = await fetch('/auth/oidc/refresh', {\n    method: 'POST',\n    headers: { 'content-type': 'application/json' },\n    body: JSON.stringify({ sessionId: authState.sessionId }),\n  });\n\n  if (!response.ok) {\n    clearAuthState();\n    throw new Error('OIDC refresh failed.');\n  }\n\n  setAuthState(await response.json());\n}\n\nasync function ensureFreshAccessToken(): Promise<void> {\n  if (!refreshPromise) {\n    refreshPromise = refreshAuthState().finally(() => {\n      refreshPromise = null;\n    });\n  }\n\n  await refreshPromise;\n}\n\nasync function fetchWithAuth(input: RequestInfo | URL, init: RequestInit = {}): Promise<Response> {\n  const headers = new Headers(init.headers);\n\n  if (authState.accessToken) {\n    headers.set('authorization', `Bearer ${authState.accessToken}`);\n  }\n\n  let response = await fetch(input, { ...init, headers });\n\n  if (response.status !== 401 || !authState.sessionId) {\n    return response;\n  }\n\n  await ensureFreshAccessToken();\n\n  const retryHeaders = new Headers(init.headers);\n\n  if (authState.accessToken) {\n    retryHeaders.set('authorization', `Bearer ${authState.accessToken}`);\n  }\n\n  response = await fetch(input, { ...init, headers: retryHeaders });\n  return response;\n}\n\nasync function bootstrapAuth(): Promise<void> {\n  if (!authState.sessionId) {\n    return;\n  }\n\n  try {\n    await refreshAuthState();\n  } catch {\n    clearAuthState();\n  }\n}\n\nasync function logout(): Promise<void> {\n  const sessionId = authState.sessionId;\n\n  clearAuthState();\n\n  if (!sessionId) {\n    return;\n  }\n\n  await fetch('/auth/oidc/logout', {\n    method: 'POST',\n    headers: { 'content-type': 'application/json' },\n    body: JSON.stringify({ sessionId }),\n  });\n}\n```\n\nRecommended browser flow:\n\n1. Redirect the user to `GET /auth/oidc/login` when they click login.\n2. On the frontend callback route, read `code` from the query string and call `exchangeCallbackCode(code)`.\n3. Remove the `code` query parameter from the address bar after a successful exchange.\n4. Call `bootstrapAuth()` once during app startup so a reloaded tab can recover from `sessionStorage`.\n5. Use `fetchWithAuth(...)` or equivalent interceptor logic for normal API requests.\n\n### Cookie transport frontend example\n\nWhen `sessionTransport` is set to `'cookie'`, the frontend no longer needs to store `sessionId`.\n\n```ts\ntype AuthState = {\n  accessToken: string | null;\n};\n\nconst authState: AuthState = {\n  accessToken: null,\n};\n\nlet refreshPromise: Promise<void> | null = null;\n\nfunction setAuthState(payload: { accessToken?: string }): void {\n  authState.accessToken = payload.accessToken ?? null;\n}\n\nfunction clearAuthState(): void {\n  authState.accessToken = null;\n}\n\nasync function refreshAuthState(): Promise<void> {\n  const response = await fetch('/auth/oidc/refresh', {\n    method: 'POST',\n    credentials: 'include',\n  });\n\n  if (!response.ok) {\n    clearAuthState();\n    throw new Error('OIDC refresh failed.');\n  }\n\n  setAuthState(await response.json());\n}\n\nasync function ensureFreshAccessToken(): Promise<void> {\n  if (!refreshPromise) {\n    refreshPromise = refreshAuthState().finally(() => {\n      refreshPromise = null;\n    });\n  }\n\n  await refreshPromise;\n}\n\nasync function exchangeCallbackCode(code: string): Promise<void> {\n  const response = await fetch('/auth/oidc/exchange', {\n    method: 'POST',\n    headers: { 'content-type': 'application/json' },\n    credentials: 'include',\n    body: JSON.stringify({ code }),\n  });\n\n  if (!response.ok) {\n    clearAuthState();\n    throw new Error('OIDC code exchange failed.');\n  }\n\n  setAuthState(await response.json());\n}\n```\n\nFor cross-origin cookie deployments, also remember:\n\n- the frontend requests must use `credentials: 'include'`\n- the backend CORS policy must allow credentials\n- the cookie typically needs `SameSite=None` and `Secure`\n- set `trustedOrigins` so refresh and logout only accept requests from your frontend origin\n\n## Backchannel Logout\n\nThe package supports OIDC backchannel logout at:\n\n- `POST /auth/oidc/backchannel-logout`\n\nExpected request shape:\n\n- `application/x-www-form-urlencoded`\n- field: `logout_token=<provider-signed-jwt>`\n\nThe middleware validates the `logout_token` against the provider JWKS and then revokes matching local sessions by:\n\n- upstream `sid` when present\n- otherwise `sub`\n\nThe logout token must include `iat`, `exp`, `jti`, the standard backchannel logout event claim, and either `sid` or `sub`. If the protected header includes `typ`, it must be `logout+jwt`; tokens without `typ` remain accepted for provider compatibility. Each `jti` is reserved once per issuer/client ID (replay keys namespace the raw `jti`, so independent issuers sharing a store and reusing a `jti` do not suppress each other) and remembered until the token `exp`. The first presentation performs the idempotent session deletion and emits `onLogout`; a duplicate presentation repeats the same idempotent deletion without emitting `onLogout` unless the catch-up actually removed sessions (retry after a deletion failure still revokes and still delivers the hook). A sequential replay after completed revocation returns `revokedSessions: 0` without a hook. Hooks are therefore at-least-once under failure/concurrency, except a crash between durable deletion and hook delivery can lose that delivery. Pre-upgrade raw-`jti` replay records expire naturally with their token `exp` and are never matched by namespaced keys.\n\nExample request:\n\n```ts\nawait fetch('/auth/oidc/backchannel-logout', {\n  method: 'POST',\n  headers: { 'content-type': 'application/x-www-form-urlencoded' },\n  body: new URLSearchParams({\n    logout_token: '<provider-signed-logout-token>',\n  }),\n});\n```\n\nExample response:\n\n```json\n{\n  \"loggedOut\": true,\n  \"revokedSessions\": 1\n}\n```\n\nNotes:\n\n- this route is intended for the IdP to call directly, not the browser\n- cookie transport does not change how backchannel logout works\n- after a successful backchannel logout, the next browser refresh will fail because the local session is gone; in cookie mode the package clears the stale session cookie on that failed refresh\n\n## Backend Wiring Examples\n\nUse one of the store packages depending on your deployment model.\n\n### Memory store\n\n```ts\nimport express from 'express';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createMemoryOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-memory-store';\n\nconst app = express();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    storeProvider: createMemoryOidcVaultStore(),\n  }),\n);\n```\n\n### Redis store\n\n```ts\nimport express from 'express';\nimport { createClient } from 'redis';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createRedisOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-redis-store';\n\nconst app = express();\nconst redis = createClient({ url: process.env.REDIS_URL });\n\nawait redis.connect();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    storeProvider: createRedisOidcVaultStore({\n      client: redis,\n      keyPrefix: 'oidc-vault',\n    }),\n  }),\n);\n```\n\n### MongoDB store\n\n```ts\nimport express from 'express';\nimport { MongoClient } from 'mongodb';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createMongoOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-mongodb-store';\n\nconst app = express();\nconst mongo = new MongoClient(process.env.MONGODB_URI!);\n\nawait mongo.connect();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    storeProvider: createMongoOidcVaultStore({\n      db: mongo.db('app-auth'),\n    }),\n  }),\n);\n```\n\n### Cookie transport\n\n```ts\nimport express from 'express';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createRedisOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-redis-store';\nimport { createClient } from 'redis';\n\nconst app = express();\nconst redis = createClient({ url: process.env.REDIS_URL });\n\nawait redis.connect();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    sessionTransport: 'cookie',\n    cookie: {\n      // Host-only (no `domain`): the browser scopes the cookie to\n      // `api.example.com` and still sends it on credentialed cross-origin\n      // requests from `https://frontend.example.com`.\n      deploymentMode: 'same-site',\n      secure: true,\n    },\n    trustedOrigins: ['https://frontend.example.com'],\n    storeProvider: createRedisOidcVaultStore({\n      client: redis,\n      keyPrefix: 'oidc-vault',\n    }),\n  }),\n);\n```\n\nOnly set `cookie.domain` (for example `.example.com`) as an advanced expansion when sibling subdomains must share the credential. Sharing widens the credential trust boundary and is not required for normal cross-origin API requests.\n\n## Main Exports\n\n- `createOidcVaultAccessTokenMiddleware(...)`\n- `createOidcVaultJwtAccessTokenValidator(...)`\n- `createOidcVaultMiddleware(...)`\n- `DEFAULT_OIDC_VAULT_BASE_PATH`\n- `DEFAULT_AUTHORIZATION_TRANSACTION_TTL_MS`\n- `DEFAULT_EXCHANGE_CODE_TTL_MS`\n- `DEFAULT_OIDC_SCOPES`\n- `DEFAULT_OIDC_VAULT_REQUEST_BODY_LIMIT`\n- `OIDC_VAULT_ROUTE_PATHS`\n- `OIDC_VAULT_URL_ENCODED_PARAMETER_LIMIT`\n- `normalizeOidcVaultBasePath(...)`\n- `resolveOidcVaultConfig(...)`\n- `resolveOidcVaultConfigFromEnv(...)`\n- `type OidcVaultOptions`\n- `type OidcVaultHooks`\n- `type OidcVaultStoreProvider`\n- `type OidcVaultSession`\n- `type OidcVaultConfig`\n- `type OidcVaultSessionInput`\n- `OidcVaultStoreConflictError`\n- `type OidcVaultExchangeResult`\n- `type OidcVaultLogoutResult`\n- `type OidcVaultAccessTokenValidator`\n- `type OidcVaultAuthenticatedRequest`\n- `type OidcVaultJwtAccessTokenValidatorOptions`\n- `type OidcVaultTokenIssuer`\n- `type OidcVaultTokenIssueResult`\n- `type OidcVaultProviderMetadata`\n\n## Store Provider Contract\n\nThe built-in memory, Redis, and MongoDB store packages share a portable subset with the lifetime, ID-reuse, serialization and deletion-accounting variations below. Their shipped READMEs describe backend startup/shutdown and resource bounds.\n\n- `createAuthorizationTransaction` and `createExchangeCode` are deliberate upserts keyed by `state` and `code`.\n- `createSession` duplicate-ID behavior is provider-specific: the memory and MongoDB providers replace the existing session (upsert), while the Redis provider rejects a live duplicate with `OidcVaultStoreConflictError` without changing the existing record or indexes (create-only, preserving index ownership). Portable callers must always create sessions with a fresh unused `sessionId` and handle `OidcVaultStoreConflictError`; reusing a live ID is non-portable. See `OidcVaultStoreProvider.createSession` for the full contract.\n- Store metadata is portable when it is JSON-compatible: strings, finite numbers, booleans, null, arrays, and plain objects. Do not rely on functions, symbols, Dates, Maps, Sets, custom prototypes, undefined object properties, or object identity surviving a store round-trip.\n- For that portable domain, inputs are captured at invocation before asynchronous work, including nested provider/user/metadata fields and object deletion scopes. Mutating inputs immediately after calling, or mutating returned values, cannot change the committed value or eventual result. Memory uses `structuredClone`; MongoDB/Redis copy plain containers while preserving native backend serialization outside the portable subset. Opaque native objects/custom serializers have no portable mutation-isolation guarantee.\n- Expiry timestamps are epoch milliseconds. Memory/MongoDB check `expiresAt <= now`; Redis uses server-owned key TTLs and server time for index cleanup, not the optional application clock. Preserve matching Redis TTLs/index scores on restore: reads do not independently audit payload expiry after externally altered TTLs. Backchannel logout JTI expiry must be finite and in the future relative to the store clock or the consume call returns `false` without storing the JTI.\n- Backchannel logout replay keys passed to `consumeBackchannelLogoutTokenJti` are opaque namespaced strings (issuer/client ID/`jti`); providers store them verbatim and need no schema change.\n- `rotateSession` requires an existing source session and a distinct unused target `sessionId`. Equivalent missing-source, same-ID, and existing-target rotation conflicts throw `OidcVaultStoreConflictError` without deleting or overwriting source or target data.\n- Session rotation preserves the logical session ID when the next session omits one. With finite expiry, each old ID revokes its lineage only before its immediate successor's `expiresAt`; later rotations do not extend earlier aliases. `A -> B (T1) -> C (T2)` leaves A expiring at T1 even if T2 is later or absent. `getSession(A)` returns `null`. After that window use the live ID or logical/subject/provider-session deletion. With `A/L1 -> B/L1 -> C/L2`, the new B alias targets L2; retained A targets L1 with its original deadline. Memory eagerly retires inactive old-lineage aliases on rotation/upsert; MongoDB/Redis can retain them until expiry or explicit cleanup. Use distinct logical IDs for unrelated login families.\n- Without successor `expiresAt`, retention is provider-specific: memory and Redis impose no alias time limit and can accumulate arbitrarily many aliases; MongoDB uses `rotatedSessionAliasRetentionMs` (default 5 minutes). Core refresh uses the live ID and preserves expiry. This retains the [SVH-05 decision](https://github.com/egose/web-ts-toolkit/blob/main/docs/tasks/20260908-130120-oidc-vault-stores-health-follow-up.md#task-svh-05-decide-a-portable-rotation-alias-lifetime-contract).\n- Deleting a live public ID removes that record; an unexpired alias revokes its logical lineage. Subject/provider-session object inputs match each supplied issuer/client field; string inputs omit those filters. Logical deletion and aliases have no issuer/client filter. Scoped/direct deletion preserves unexpired aliases while a live member survives, including another provider scope. MongoDB retains alias rows under reused create IDs until expiry/lineage cleanup; memory/Redis clear target aliases on reuse.\n- Bulk counts cover primary records deleted, never alias cleanup: memory excludes expired sessions, MongoDB can count expired documents awaiting TTL cleanup, and Redis counts actual primary deletions including matching rotation successors. MongoDB scoped deletes repeat until an empty query (continuous arrivals can prolong them); Redis makes one cursor traversal. Later arrivals can survive and errors can follow committed deletions. Counts are not proof of an empty scope or a portable live-user census. Neither backend provides a global logout snapshot.\n- Operational bounds are local, not total-work guarantees: memory's 64-slot sweeps still rebuild full key snapshots and scan maps for lineage cleanup; MongoDB materializes affected IDs/survivors with potentially large `$in` sets; Redis SCAN/ZSCAN COUNT values are hints and Lua can materialize whole lineages/alias sets. Maintenance progress depends on operations/backend availability.\n- Compatibility: surviving aliases and invocation-time portable input ownership now remain intact across scoped deletion and caller mutation. Redis repairs keyed-record/index corruption conservatively and emits only fixed operation text for post-commit maintenance warnings. Arbitrary backend errors may still carry secrets: log allowlisted categories rather than records, raw errors, credential URLs or token-valued labels. Alias lifetime and duplicate-create variations remain intentional.\n\n## Session Identity And Store Namespaces\n\nExchange, refresh, and logout of a **live session** compare every stored `provider.issuer` and `provider.clientId` that is not undefined against the resolved middleware configuration. Each known field must match independently. Stored identifiers are compared verbatim, without trimming or URL canonicalization; issuer trailing-slash variants are distinct. Configuration strings still receive construction-time trimming.\n\nA known mismatch returns HTTP 401 with `{\"code\":\"OIDC_VAULT_INVALID_SESSION\",\"message\":\"Session is missing or expired.\"}` before discovery, upstream token use, local issuance, lifecycle hooks, rotation, or lineage deletion. It neither sets nor clears a cookie and produces no provider logout redirect. The normal `onError` observer runs without the foreign session in its context.\n\nLegacy sessions with absent `provider`, an empty provider object, or omitted/undefined identity fields remain supported. Only known fields are checked: an omitted issuer permits cross-issuer use, an omitted client ID permits cross-client use, and entirely absent identity permits both. Refresh does not backfill identity.\n\nFor complete identity isolation, use separate store namespaces for **session/alias, exchange-code, and authorization-transaction records**. Live-session checks alone do not isolate shared namespaces: exchange consumes the one-time code before checking identity, so a rejected foreign exchange still spends the owner's code. When logout finds no live session, it still calls `deleteSession` through the stale-alias path without an identity check, which can revoke a foreign lineage in shared storage.\n\n## Known Browser And Concurrency Limits\n\n- **Browser binding:** `state`, nonce, PKCE, and one-time codes do not bind login/callback/exchange completion to the initiating browser. A transferred callback/frontend URL can cause login/session swapping; a stolen unused exchange code can be redeemed by another browser in either transport. `exchange` has no source-origin check and accepts URL-encoded forms. CORS, `SameSite`, and `trustedOrigins` on cookie refresh/logout do not establish this missing binding.\n- **Refresh families:** local atomic rotation allows one winner, but overlapping requests can send the same upstream refresh token multiple times, including across backend instances. A single-use provider with reuse detection can revoke the entire upstream refresh family, leaving the local winner unable to refresh. Deduplicate frontend refreshes, including bootstrap and retry paths; a per-context promise is not a distributed guarantee.\n- **Cookie ordering:** a loser reaching a local rotation conflict (or a stale missing-session retry) clears the cookie. A late clear can erase the winner's cookie even while its server session remains live. Upstream-failure losers do not set a cookie. Response ordering is not enforced.\n- **Logout and stateless tokens:** local/provider/backchannel logout revoke vault refresh sessions, not outstanding stateless application access tokens. Those remain valid until their own expiry unless your validator checks application revocation state. A refresh racing logout can still return 200 and an access token after its lineage is deleted. Keep local tokens short-lived; immediate API revocation requires application-owned validation state. Vault-session expiry likewise does not revoke an already-issued stateless token.\n\nBrowser-bound proofs (BOV-02-FU1), cross-instance refresh reservation (BOV-03-FU1), and stale-cookie ordering (BOV-03-FU2) remain proposed in the [boundary review](https://github.com/egose/web-ts-toolkit/blob/main/docs/tasks/20260908-070811-express-oidc-vault-boundary-review.md). The lifetime, identity, and response changes documented here do not implement those protocols.\n\n## Key Integration Notes\n\n- The browser should never receive the upstream refresh token.\n- The backend should store the latest upstream `id_token` so logout can call the upstream end-session endpoint with `id_token_hint`.\n- `sessionId` should rotate on refresh.\n- The frontend should deduplicate concurrent refresh calls so only one refresh is in-flight at a time.\n- Upstream OAuth `expires_in` describes the upstream access token only. It does not set `OidcVaultSession.expiresAt` or shorten the refresh-token-backed vault session.\n- `OidcVaultSession.expiresAt`, assigned by `sessionTtlMs`, application code, or store policy, is an explicit vault-session expiry in epoch milliseconds and remains enforced by store providers.\n- With `issuer` and `clientId` but no endpoint settings, discovery is used and the discovered issuer must exactly equal the configured issuer (only configured surrounding whitespace is trimmed; `/tenant`, `/tenant/`, and `/tenant//` are distinct identifiers).\n- Provider discovery metadata and remote JWKS resolvers are cached in bounded process-wide maps; these keys are intended to come from static middleware configuration, not request input. Discovery fetches are isolated by `(issuer, providerRequestTimeoutMs)` so differing instance policies never inherit each other's deadline, while settled successful metadata is additionally shared across timeouts for reuse. JWKS resolvers are isolated by `(jwks_uri, providerRequestTimeoutMs)` because JOSE fixes the fetch timeout at creation.\n- Successful discovery entries are reused for up to 10 minutes and both discovery and JWKS resolver maps retain at most 32 entries with oldest-entry eviction. Failed discovery requests evict only the owning policy entry so a later request can retry. Timeout options are validated before any cache lookup, so cached entries cannot bypass option validation.\n- Discovery, token, UserInfo, and remote JWKS HTTP requests use a 5 second default deadline covering response headers plus complete success/error body consumption; stalled or slow bodies fail with sanitized endpoint-specific timeout errors. Cancellation is attempted promptly without awaiting its promise, so an uncooperative custom stream cannot hold up error delivery through pending cleanup. Request completion does not guarantee completed resource cleanup; the hanging-cancellation evidence uses custom streams, with no native-undici remote exploit established. Upstream redirects are never followed. Set `providerRequestTimeoutMs` to a positive integer number of milliseconds to change the bound. JWKS documents additionally enforce 1 MiB and 100-key limits.\n- Pre-header network rejection and mid-body transport reset return HTTP 502 with `OIDC_VAULT_DISCOVERY_FAILED`, `OIDC_VAULT_TOKEN_REQUEST_FAILED`, or `OIDC_VAULT_USERINFO_FAILED` and message `OIDC provider request failed.` JWKS transport failures use `OIDC_VAULT_JWKS_FAILED`; JOSE timeouts retain `ERR_JWKS_TIMEOUT`. Discovery success-body timeout/size/JSON failures retain `OIDC_VAULT_DISCOVERY_INVALID`. Original transport diagnostics are privately available as `hooks.onError` context `error.cause` (narrow the unknown error before reading it); they are not browser payload fields.\n- Provider response parse errors return sanitized client messages; oversized or malformed provider bodies are not returned to callers. Discovery, token, and UserInfo JSON bodies must be non-null, non-array objects; valid non-object JSON (`null`, arrays, strings, booleans, numbers) is a controlled 502 provider error.\n- Non-success token/UserInfo responses always surface 502 with a stable code/message (`OIDC_VAULT_TOKEN_REQUEST_FAILED` / `OIDC_VAULT_USERINFO_FAILED`) regardless of JSON versus HTML bodies and without leaking body content or the upstream status. Upstream redirects are never followed, so a rejected 302 never becomes a browser-facing 3xx.\n- If manual endpoints are configured, manual endpoints are used and discovery is not performed; `issuer` is still required so ID and logout tokens are issuer-bound against the exact configured identifier.\n- Token responses must include `token_type: Bearer`; `expires_in`, when present, must be a finite non-negative integer. Present `access_token`/`id_token`/`refresh_token` fields must be non-empty strings and a present `scope` must be a string; malformed present fields are rejected rather than treated as omissions.\n- Callback (authorization-code) responses additionally require `id_token` and `refresh_token`; no session or exchange code is persisted until all provider checks pass. The callback destination (transaction `returnTo` or `frontendRedirectUri`) is validated before any provider call or durable session/code creation and fails with `500 OIDC_VAULT_MISSING_FRONTEND_REDIRECT_URI` when neither is configured, so a missing destination cannot strand credentials.\n- ID tokens must include `sub`, `exp`, and `iat`; `azp` must match `clientId` when present and is required for multi-audience ID tokens.\n- UserInfo responses must be objects including a `sub` matching the verified ID-token subject before claims are merged into the session user; JSON `null` never bypasses the subject check.\n- Refresh responses may omit `id_token`, `refresh_token`, `access_token`, and `scope`; omitted fields retain their current session values (omitted `id_token` keeps the existing verified identity without requiring the original ID token to still be current). If refresh returns a new `id_token`, its `sub` must match the current session subject; no rotation happens until all provider checks pass.\n- Refresh profile precedence: fresh verified ID claims are the base when a new `id_token` is present, freshly fetched matching UserInfo overlays whichever base applies, and the retained profile is used only when no new `id_token` arrives (fresh UserInfo still overlays the retained base per key). Retained values are never merged over fresh claims and are never treated as fresh UserInfo. Claims absent from the fresh sources are dropped when fresh identity arrives, so removed provider claims disappear; keep application custom attributes in `session.metadata`, not in `user`, because application-added `user` keys are not carried forward across a fresh identity refresh.\n- `backendOrigin` is the public origin registered with your OIDC provider for the backend callback URI. The middleware normalizes it to an origin and uses it for `/callback` redirect URIs instead of trusting request `Host` headers.\n- `frontendRedirectUri` is the default browser return target after the backend completes the upstream callback. It stays optional at middleware creation because non-callback routes do not need it, but the callback fails fast before durable state when neither the transaction `returnTo` nor this value is configured.\n- `postLogoutRedirectUri` is optional. When configured, it must be an absolute HTTP(S) URL registered with the OIDC provider for post-logout redirects. It may be hosted on a different origin from `frontendRedirectUri` when that exact URL is provider-registered. It is only consulted for redirected logout (`redirect: true`).\n- After live-session identity checks, local logout (`redirect` unset or `false`) never contacts the provider: it revokes the local session lineage, clears the cookie under cookie transport, delivers `onLogout` for a live session, and returns `200 { loggedOut: true }`. Redirected logout (`redirect: true`) commits the same local outcome before attempting an upstream end-session redirect. Discovery errors are reported through `onError`; errors or an absent `endSessionEndpoint` fall back to local `200 { loggedOut: true }`. With no live session, logout attempts stale-alias deletion and returns local success without `onLogout`; an expired alias may no longer identify a live lineage.\n- backchannel logout revokes local sessions by upstream `sid` when available, otherwise by `sub`\n- Every vault route response carries `Cache-Control: no-store` (login/callback/logout redirects, exchange/refresh/logout/backchannel JSON, and error JSON including body-parser errors) so caches do not retain session/access credentials, one-time exchange codes, or authorization redirects. Only `no-store` is emitted: legacy `Pragma`/`Expires` add no protection once `no-store` is present, and no `Referrer-Policy` is set because redirect targets intentionally expose protocol-required values (provider authorization URL, frontend `?code=`, upstream `id_token_hint`) to the navigation target. This does not clear browser history, disable reverse-proxy request logging, strip `?code=` from frontend URLs/history (the frontend must still clean up the callback URL, e.g. `history.replaceState`), or hide intentional provider redirect exposure. Verify with `curl -i` (expect `Cache-Control: no-store` on `GET /auth/oidc/login`, `POST /auth/oidc/exchange`, `POST /auth/oidc/refresh`, and `POST /auth/oidc/logout`) or assert `response.headers['cache-control'] === 'no-store'` in integration tests under both transports.\n\n## Config Helpers\n\n```ts\nimport { resolveOidcVaultConfigFromEnv } from '@web-ts-toolkit/express-oidc-vault';\n\nconst config = resolveOidcVaultConfigFromEnv(process.env);\n```\n\nResolution behavior:\n\n- the issuer identifier is syntax-validated (absolute http/https URL without userinfo, query, or fragment; `http` is accepted for local-test providers) but otherwise preserved exactly after surrounding-whitespace trimming: no trailing slash is added and `/tenant`, `/tenant/`, and `/tenant//` remain distinct\n- `OIDC_CLIENT_ID` is always required; with `OIDC_ISSUER` and no endpoint settings, discovery resolves endpoints and requires exact discovered-issuer equality\n- any nonempty endpoint (`authorizationEndpoint`, `tokenEndpoint`, `jwksUri`, `userInfoEndpoint`, or `endSessionEndpoint`) selects manual mode with no discovery; this includes `OIDC_USERINFO_ENDPOINT` and `OIDC_END_SESSION_ENDPOINT`. Manual mode requires `issuer`, `authorizationEndpoint`, `tokenEndpoint`, and `jwksUri`, plus `clientId`. Optional endpoints are not partial discovery overrides\n- undefined, empty, and whitespace-only config/env strings are absent after trimming; complete manual configuration preserves valid optional endpoints\n- `OIDC_SCOPES` defaults to `openid email profile`\n\nDiscovery may omit `userinfo_endpoint` and `end_session_endpoint`. If present, each must be a nonempty absolute HTTP(S) URL string. Null, arrays, objects, numbers, booleans, blank strings, malformed URLs, and non-HTTP(S) URLs invalidate metadata with HTTP 502 / `OIDC_VAULT_DISCOVERY_INVALID`, identifying the field without echoing its value. Failed metadata is evicted so later requests can fetch corrected metadata; only validated successes are shared across timeout policies. During redirected logout, discovery errors instead reach `onError` while local revocation still succeeds; local-only logout does not discover metadata.\n\n### Manual endpoint mode\n\nIf your provider metadata is not discoverable from `OIDC_ISSUER`, configure the endpoints directly.\n\n```ts\nimport express from 'express';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createRedisOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-redis-store';\nimport { createClient } from 'redis';\n\nconst app = express();\nconst redis = createClient({ url: process.env.REDIS_URL });\n\nawait redis.connect();\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      authorizationEndpoint: process.env.OIDC_AUTHORIZATION_ENDPOINT,\n      tokenEndpoint: process.env.OIDC_TOKEN_ENDPOINT,\n      userInfoEndpoint: process.env.OIDC_USERINFO_ENDPOINT,\n      jwksUri: process.env.OIDC_JWKS_URI,\n      endSessionEndpoint: process.env.OIDC_END_SESSION_ENDPOINT,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n      scopes: process.env.OIDC_SCOPES,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    storeProvider: createRedisOidcVaultStore({\n      client: redis,\n      keyPrefix: 'oidc-vault',\n    }),\n  }),\n);\n```\n\nIn manual mode, the minimum required config is:\n\n- `authorizationEndpoint`\n- `tokenEndpoint`\n- `jwksUri`\n- `clientId`\n- `issuer`\n\n`userInfoEndpoint` and `endSessionEndpoint` are optional but recommended when your provider supports them.\n\n## Local Access Token Example\n\nThe middleware can return a local backend access token during `exchange` and `refresh` by providing a `tokenIssuer`.\n\n```ts\nimport express from 'express';\nimport { SignJWT } from 'jose';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createMemoryOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-memory-store';\n\nconst app = express();\n\n// Fail startup when no suitably strong signing key is configured. There is no\n// public fallback: `APP_JWT_SECRET` must be a strong random value that encodes\n// to at least 32 bytes for HS256.\nconst requireSigningKey = (raw: string | undefined): Uint8Array => {\n  if (!raw) {\n    throw new Error('APP_JWT_SECRET must be set to a strong random value at least 32 bytes long.');\n  }\n\n  const key = new TextEncoder().encode(raw);\n\n  if (key.length < 32) {\n    throw new Error('APP_JWT_SECRET must decode to at least 32 bytes for HS256 local access tokens.');\n  }\n\n  return key;\n};\n\nconst jwtSecret = requireSigningKey(process.env.APP_JWT_SECRET);\nconst localTokenIssuer = 'https://api.example.com';\nconst localTokenAudience = 'api-audience';\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    postLogoutRedirectUri: 'https://frontend.example.com/logged-out',\n    storeProvider: createMemoryOidcVaultStore(),\n    tokenIssuer: {\n      async issue({ session }) {\n        const accessToken = await new SignJWT({\n          sub: session.subject,\n          sid: session.sessionId,\n          scope: session.scope,\n        })\n          .setProtectedHeader({ alg: 'HS256' })\n          .setIssuer(localTokenIssuer)\n          .setAudience(localTokenAudience)\n          .setIssuedAt()\n          .setExpirationTime('15m')\n          .sign(jwtSecret);\n\n        return {\n          accessToken,\n          expiresIn: 900,\n          tokenType: 'Bearer',\n        };\n      },\n    },\n  }),\n);\n```\n\nThat local token is separate from the upstream IdP access token:\n\n- the upstream refresh token stays in the server-side vault\n- the frontend receives local token fields and the session's `user` profile; body transport also includes the opaque `sessionId`, while cookie transport omits it\n- the app-issued access token can contain only the claims your backend APIs actually need\n\n### Local issuer result contract\n\n`tokenIssuer.issue` must resolve to a non-null, non-array object with:\n\n- `accessToken`: nonempty opaque string, returned verbatim without trimming or a new whitespace policy;\n- `expiresIn`: finite nonnegative safe-integer seconds, from 0 through `Number.MAX_SAFE_INTEGER`;\n- `tokenType`: optional exact literal `'Bearer'`. Omitted/undefined stays absent in JSON; null, lowercase `'bearer'`, and other values are invalid.\n\nOnly these three fields are copied once into a fresh result. Extra fields (including upstream tokens, `metadata`, `sessionId`, `user`, and `toJSON`) are ignored without evaluating their getters. The vault supplies the response session ID/profile. Omitting `tokenIssuer` is supported and returns no local token fields.\n\nMalformed results return HTTP 500 with `{\"code\":\"OIDC_VAULT_INTERNAL_ERROR\",\"message\":\"Unexpected OIDC vault error.\"}` inside issuance rollback: the logical lineage is revoked and cookie transport clears its cookie instead of minting one. Exchange has already consumed its code; refresh has already contacted the provider and rotated the handle, and its success notification does not run. Correct the issuer and start a new login. Field-specific diagnostics are the original `hooks.onError` context `error` (narrow it before use); allowed-field getter exceptions also enter rollback.\n\nThis projection contains accidental result extensions. Issuers/hooks remain trusted code with mutable session/request/response access; application profiles and deliberate secrets placed in allowed fields are not redacted.\n\n## Migration And Behavior Changes\n\n- Optional-only endpoint settings previously ignored now select manual mode and fail without the complete manual set. Supply all required manual values or remove endpoint settings to use discovery. Correct malformed optional discovery capabilities at the provider, or omit unsupported fields.\n- Invalid transaction/code TTLs previously had store-dependent behavior; supply positive safe-integer milliseconds. `sessionTtlMs` is opt-in for new sessions and never renews on refresh. Custom clocks are now sampled during construction.\n- Route each session to its owning issuer/client configuration. Known foreign live sessions now fail with 401. Correct inaccurate stored identity only from trusted provenance or require login again; do not remove identity fields to bypass the guard. Legacy omissions and shared code/alias limits remain as described above.\n- Issuers must return the declared local credential shape; previously accepted malformed results now fail with rollback. Extra result properties no longer extend/override JSON responses.\n- Provider network/reset failures now produce sanitized endpoint-specific 502s instead of generic internal errors. Cancellation no longer waits for an uncooperative cleanup promise. Alias-retention wording reflects existing SVH-05 behavior, with no store migration.\n\n## Access Token Validation Middleware\n\nThe OIDC route/session middleware and the normal API bearer-token middleware are separate concerns.\n\nUse `createOidcVaultMiddleware(...)` for:\n\n- login\n- callback\n- exchange\n- refresh\n- logout\n\nUse `createOidcVaultAccessTokenMiddleware(...)` for:\n\n- validating the app-issued local access token on protected API routes\n- attaching authenticated auth context to `req.auth`\n- rejecting missing, malformed, invalid, or expired bearer tokens with `401`\n\n`onAuthContext` is a pre-`next()` veto hook, not a post-commit notification:\nwhen it throws, downstream middleware never runs and `req.auth` is detached\nbefore the error response is sent. A valid token plus a failing hook never\nsurfaces as an invalid-token `401`: an `OidcVaultHttpError` from the hook keeps\nits own status/code/client message (only a `401` veto carries the `Bearer`\nchallenge), while any other hook error becomes a sanitized `500\nOIDC_VAULT_AUTH_CONTEXT_FAILED` without leaking the original message. Pass\n`onError` to observe the original bearer error object (extraction, validator,\nor hook failure) for private server-side logs; it never affects the sanitized\nclient response.\n\n```ts\nimport express from 'express';\nimport { createOidcVaultAccessTokenMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { jwtVerify } from 'jose';\n\nconst app = express();\n\n// Fail startup when no suitably strong signing key is configured. There is no\n// public fallback: `APP_JWT_SECRET` must be a strong random value that encodes\n// to at least 32 bytes for HS256.\nconst requireSigningKey = (raw: string | undefined): Uint8Array => {\n  if (!raw) {\n    throw new Error('APP_JWT_SECRET must be set to a strong random value at least 32 bytes long.');\n  }\n\n  const key = new TextEncoder().encode(raw);\n\n  if (key.length < 32) {\n    throw new Error('APP_JWT_SECRET must decode to at least 32 bytes for HS256 local access tokens.');\n  }\n\n  return key;\n};\n\nconst jwtSecret = requireSigningKey(process.env.APP_JWT_SECRET);\nconst localTokenIssuer = 'https://api.example.com';\nconst localTokenAudience = 'api-audience';\n\napp.get(\n  '/api/me',\n  createOidcVaultAccessTokenMiddleware({\n    validator: {\n      async validate(token) {\n        const result = await jwtVerify(token, jwtSecret, {\n          issuer: localTokenIssuer,\n          audience: localTokenAudience,\n          algorithms: ['HS256'],\n        });\n\n        return {\n          subject: String(result.payload.sub),\n          sessionId: typeof result.payload.sid === 'string' ? result.payload.sid : undefined,\n          scope: typeof result.payload.scope === 'string' ? result.payload.scope : undefined,\n          claims: result.payload as Record<string, unknown>,\n        };\n      },\n    },\n  }),\n  (req, res) => {\n    res.json({\n      subject: req.auth?.subject,\n      sessionId: req.auth?.sessionId,\n      scope: req.auth?.scope,\n    });\n  },\n);\n```\n\nReturned auth context shape:\n\n- `req.auth.token`\n- `req.auth.subject`\n- `req.auth.sessionId`\n- `req.auth.scope`\n- `req.auth.claims`\n\nThe package augments Express request typing so `req.auth` is available without casting in TypeScript route handlers.\n\n### JWT validator helper\n\nIf your local access token is a JWT, you can avoid rewriting the same `jwtVerify(...)` adapter each time.\n\n```ts\nimport {\n  createOidcVaultAccessTokenMiddleware,\n  createOidcVaultJwtAccessTokenValidator,\n} from '@web-ts-toolkit/express-oidc-vault';\n\nconst requireSigningKey = (raw: string | undefined): Uint8Array => {\n  if (!raw) {\n    throw new Error('APP_JWT_SECRET must be set to a strong random value at least 32 bytes long.');\n  }\n\n  const key = new TextEncoder().encode(raw);\n\n  if (key.length < 32) {\n    throw new Error('APP_JWT_SECRET must decode to at least 32 bytes for HS256 local access tokens.');\n  }\n\n  return key;\n};\n\nconst jwtSecret = requireSigningKey(process.env.APP_JWT_SECRET);\n\napp.get(\n  '/api/me',\n  createOidcVaultAccessTokenMiddleware({\n    validator: createOidcVaultJwtAccessTokenValidator({\n      key: jwtSecret,\n      issuer: 'https://api.example.com',\n      audience: 'api-audience',\n      algorithms: ['HS256'],\n    }),\n  }),\n  (req, res) => {\n    res.json({\n      subject: req.auth?.subject,\n      sessionId: req.auth?.sessionId,\n      scope: req.auth?.scope,\n    });\n  },\n);\n```\n\nDefault JWT claim mapping:\n\n- `sub` -> `auth.subject`\n- `sid` -> `auth.sessionId`\n- `scope` -> `auth.scope`\n- full verified payload -> `auth.claims`\n\nIf you need a custom mapping, pass `mapClaims(...)` to `createOidcVaultJwtAccessTokenValidator(...)`.\n\nRecommended separation:\n\n- keep login/session lifecycle in `createOidcVaultMiddleware(...)`\n- keep normal API bearer validation in `createOidcVaultAccessTokenMiddleware(...)`\n- keep authorization decisions outside the validator middleware\n\n## Hook Examples\n\nHooks let the app observe or extend the core OIDC flow without forking the middleware.\n\n### Audit and user provisioning hooks\n\n```ts\nimport { createHmac } from 'node:crypto';\nimport express from 'express';\nimport { createOidcVaultMiddleware } from '@web-ts-toolkit/express-oidc-vault';\nimport { createMemoryOidcVaultStore } from '@web-ts-toolkit/express-oidc-vault-memory-store';\n\nconst app = express();\nconst auditKey = new TextEncoder().encode(process.env.APP_AUDIT_KEY ?? '');\n\n// Purpose-specific keyed fingerprint for audit logs. Never log the raw\n// refresh-session ID: it is a credential that redeems a new session.\nconst fingerprintSessionId = (sessionId: string | undefined): string | undefined => {\n  if (!sessionId || auditKey.length === 0) {\n    return undefined;\n  }\n\n  return createHmac('sha256', auditKey).update(sessionId, 'utf8').digest('hex').slice(0, 16);\n};\n\n// Query-free route label. Never log `req.originalUrl`: callback and frontend\n// URLs can carry `code`, `state`, or tokens in the query string.\nconst queryFreeRoute = (req: { method?: string; path?: string }): string =>\n  `${req.method ?? 'UNKNOWN'} ${req.path ?? 'unknown'}`;\n\n// Selected sanitized error fields. Never log the arbitrary error object or its\n// message: provider, store, and hook errors may carry secrets or token bodies.\nconst sanitizeErrorForLog = (error: unknown): { code: string; status?: number } => {\n  if (typeof error === 'object' && error !== null && 'code' in error) {\n    const { code, status } = error as { code?: unknown; status?: unknown };\n\n    return {\n      code: typeof code === 'string' ? code : 'UNKNOWN',\n      ...(typeof status === 'number' ? { status } : {}),\n    };\n  }\n\n  return { code: 'UNKNOWN' };\n};\n\napp.use(\n  createOidcVaultMiddleware({\n    basePath: '/auth/oidc',\n    backendOrigin: 'https://api.example.com',\n    config: {\n      issuer: process.env.OIDC_ISSUER,\n      clientId: process.env.OIDC_CLIENT_ID,\n      clientSecret: process.env.OIDC_CLIENT_SECRET,\n    },\n    frontendRedirectUri: 'https://frontend.example.com/callback',\n    storeProvider: createMemoryOidcVaultStore(),\n    hooks: {\n      async onLoginStart({ req }) {\n        console.log('OIDC login started', {\n          ip: req.ip,\n          userAgent: req.get('user-agent'),\n        });\n      },\n      async onSessionCreated({ session }) {\n        if (!session?.user) {\n          return;\n        }\n\n        await upsertLocalUser({\n          oidcSubject: session.subject,\n          email: typeof session.user.email === 'string' ? session.user.email : undefined,\n          displayName: typeof session.user.name === 'string' ? session.user.name : undefined,\n        });\n      },\n      async onSessionRefreshed({ session, metadata }) {\n        console.log('OIDC session rotated', {\n          previousSession: fingerprintSessionId(\n            typeof meta","readmeFilename":"README.md"}