@lindorm/aegis 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -5
- package/dist/classes/Aegis.d.ts +20 -5
- package/dist/classes/Aegis.d.ts.map +1 -1
- package/dist/classes/Aegis.js +259 -45
- package/dist/classes/Aegis.js.map +1 -1
- package/dist/classes/CoseKit.d.ts +31 -0
- package/dist/classes/CoseKit.d.ts.map +1 -0
- package/dist/classes/CoseKit.js +64 -0
- package/dist/classes/CoseKit.js.map +1 -0
- package/dist/classes/CweKit.d.ts +24 -0
- package/dist/classes/CweKit.d.ts.map +1 -0
- package/dist/classes/CweKit.js +73 -0
- package/dist/classes/CweKit.js.map +1 -0
- package/dist/classes/CwmKit.d.ts +22 -0
- package/dist/classes/CwmKit.d.ts.map +1 -0
- package/dist/classes/CwmKit.js +54 -0
- package/dist/classes/CwmKit.js.map +1 -0
- package/dist/classes/CwsKit.d.ts +24 -0
- package/dist/classes/CwsKit.d.ts.map +1 -0
- package/dist/classes/CwsKit.js +60 -0
- package/dist/classes/CwsKit.js.map +1 -0
- package/dist/classes/CwtKit.d.ts +31 -0
- package/dist/classes/CwtKit.d.ts.map +1 -0
- package/dist/classes/CwtKit.js +65 -0
- package/dist/classes/CwtKit.js.map +1 -0
- package/dist/classes/JoseKit.d.ts +32 -0
- package/dist/classes/JoseKit.d.ts.map +1 -0
- package/dist/classes/JoseKit.js +66 -0
- package/dist/classes/JoseKit.js.map +1 -0
- package/dist/classes/JweKit.d.ts.map +1 -1
- package/dist/classes/JweKit.js +31 -3
- package/dist/classes/JweKit.js.map +1 -1
- package/dist/classes/JwsKit.d.ts.map +1 -1
- package/dist/classes/JwsKit.js +19 -3
- package/dist/classes/JwsKit.js.map +1 -1
- package/dist/classes/JwtKit.d.ts +4 -1
- package/dist/classes/JwtKit.d.ts.map +1 -1
- package/dist/classes/JwtKit.js +100 -20
- package/dist/classes/JwtKit.js.map +1 -1
- package/dist/classes/SignatureKit.d.ts.map +1 -1
- package/dist/classes/SignatureKit.js +5 -1
- package/dist/classes/SignatureKit.js.map +1 -1
- package/dist/constants/token-type.d.ts +1 -1
- package/dist/constants/token-type.d.ts.map +1 -1
- package/dist/constants/token-type.js +2 -0
- package/dist/constants/token-type.js.map +1 -1
- package/dist/errors/AegisError.d.ts +1 -0
- package/dist/errors/AegisError.d.ts.map +1 -1
- package/dist/errors/AegisError.js +1 -0
- package/dist/errors/AegisError.js.map +1 -1
- package/dist/errors/JweError.d.ts +1 -0
- package/dist/errors/JweError.d.ts.map +1 -1
- package/dist/errors/JweError.js +1 -0
- package/dist/errors/JweError.js.map +1 -1
- package/dist/errors/JwsError.d.ts +1 -0
- package/dist/errors/JwsError.d.ts.map +1 -1
- package/dist/errors/JwsError.js +1 -0
- package/dist/errors/JwsError.js.map +1 -1
- package/dist/errors/JwtError.d.ts +1 -0
- package/dist/errors/JwtError.d.ts.map +1 -1
- package/dist/errors/JwtError.js +1 -0
- package/dist/errors/JwtError.js.map +1 -1
- package/dist/interfaces/Aegis.d.ts +6 -1
- package/dist/interfaces/Aegis.d.ts.map +1 -1
- package/dist/internal/claims/events.d.ts +5 -0
- package/dist/internal/claims/events.d.ts.map +1 -0
- package/dist/internal/claims/events.js +3 -0
- package/dist/internal/claims/events.js.map +1 -0
- package/dist/internal/claims/registry.d.ts +14 -0
- package/dist/internal/claims/registry.d.ts.map +1 -0
- package/dist/internal/claims/registry.js +61 -0
- package/dist/internal/claims/registry.js.map +1 -0
- package/dist/internal/claims/sub-id.d.ts +7 -0
- package/dist/internal/claims/sub-id.d.ts.map +1 -0
- package/dist/internal/claims/sub-id.js +11 -0
- package/dist/internal/claims/sub-id.js.map +1 -0
- package/dist/internal/cose/act-claim.d.ts +4 -0
- package/dist/internal/cose/act-claim.d.ts.map +1 -0
- package/dist/internal/cose/act-claim.js +8 -0
- package/dist/internal/cose/act-claim.js.map +1 -0
- package/dist/internal/cose/alg-labels.d.ts +4 -0
- package/dist/internal/cose/alg-labels.d.ts.map +1 -0
- package/dist/internal/cose/alg-labels.js +42 -0
- package/dist/internal/cose/alg-labels.js.map +1 -0
- package/dist/internal/cose/cbor.d.ts +11 -0
- package/dist/internal/cose/cbor.d.ts.map +1 -0
- package/dist/internal/cose/cbor.js +37 -0
- package/dist/internal/cose/cbor.js.map +1 -0
- package/dist/internal/cose/compact-map.d.ts +11 -0
- package/dist/internal/cose/compact-map.d.ts.map +1 -0
- package/dist/internal/cose/compact-map.js +43 -0
- package/dist/internal/cose/compact-map.js.map +1 -0
- package/dist/internal/cose/cose-key-thumbprint.d.ts +5 -0
- package/dist/internal/cose/cose-key-thumbprint.d.ts.map +1 -0
- package/dist/internal/cose/cose-key-thumbprint.js +60 -0
- package/dist/internal/cose/cose-key-thumbprint.js.map +1 -0
- package/dist/internal/cose/cose-key.d.ts +8 -0
- package/dist/internal/cose/cose-key.d.ts.map +1 -0
- package/dist/internal/cose/cose-key.js +98 -0
- package/dist/internal/cose/cose-key.js.map +1 -0
- package/dist/internal/cose/cose-typ.d.ts +2 -0
- package/dist/internal/cose/cose-typ.d.ts.map +1 -0
- package/dist/internal/cose/cose-typ.js +8 -0
- package/dist/internal/cose/cose-typ.js.map +1 -0
- package/dist/internal/cose/cwt-claims.d.ts +7 -0
- package/dist/internal/cose/cwt-claims.d.ts.map +1 -0
- package/dist/internal/cose/cwt-claims.js +94 -0
- package/dist/internal/cose/cwt-claims.js.map +1 -0
- package/dist/internal/cose/enc-labels.d.ts +5 -0
- package/dist/internal/cose/enc-labels.d.ts.map +1 -0
- package/dist/internal/cose/enc-labels.js +47 -0
- package/dist/internal/cose/enc-labels.js.map +1 -0
- package/dist/internal/cose/structures.d.ts +20 -0
- package/dist/internal/cose/structures.d.ts.map +1 -0
- package/dist/internal/cose/structures.js +22 -0
- package/dist/internal/cose/structures.js.map +1 -0
- package/dist/internal/cose/sub-id-claim.d.ts +4 -0
- package/dist/internal/cose/sub-id-claim.d.ts.map +1 -0
- package/dist/internal/cose/sub-id-claim.js +18 -0
- package/dist/internal/cose/sub-id-claim.js.map +1 -0
- package/dist/internal/profiles/definitions/access-token.d.ts +3 -0
- package/dist/internal/profiles/definitions/access-token.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/access-token.js +31 -0
- package/dist/internal/profiles/definitions/access-token.js.map +1 -0
- package/dist/internal/profiles/definitions/client-assertion.d.ts +3 -0
- package/dist/internal/profiles/definitions/client-assertion.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/client-assertion.js +18 -0
- package/dist/internal/profiles/definitions/client-assertion.js.map +1 -0
- package/dist/internal/profiles/definitions/default.d.ts +3 -0
- package/dist/internal/profiles/definitions/default.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/default.js +14 -0
- package/dist/internal/profiles/definitions/default.js.map +1 -0
- package/dist/internal/profiles/definitions/delegation.d.ts +3 -0
- package/dist/internal/profiles/definitions/delegation.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/delegation.js +19 -0
- package/dist/internal/profiles/definitions/delegation.js.map +1 -0
- package/dist/internal/profiles/definitions/erasure-token.d.ts +3 -0
- package/dist/internal/profiles/definitions/erasure-token.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/erasure-token.js +28 -0
- package/dist/internal/profiles/definitions/erasure-token.js.map +1 -0
- package/dist/internal/profiles/definitions/id-token.d.ts +3 -0
- package/dist/internal/profiles/definitions/id-token.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/id-token.js +26 -0
- package/dist/internal/profiles/definitions/id-token.js.map +1 -0
- package/dist/internal/profiles/definitions/introspection.d.ts +3 -0
- package/dist/internal/profiles/definitions/introspection.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/introspection.js +18 -0
- package/dist/internal/profiles/definitions/introspection.js.map +1 -0
- package/dist/internal/profiles/definitions/jarm.d.ts +3 -0
- package/dist/internal/profiles/definitions/jarm.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/jarm.js +19 -0
- package/dist/internal/profiles/definitions/jarm.js.map +1 -0
- package/dist/internal/profiles/definitions/logout-token.d.ts +3 -0
- package/dist/internal/profiles/definitions/logout-token.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/logout-token.js +20 -0
- package/dist/internal/profiles/definitions/logout-token.js.map +1 -0
- package/dist/internal/profiles/definitions/security-event.d.ts +3 -0
- package/dist/internal/profiles/definitions/security-event.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/security-event.js +20 -0
- package/dist/internal/profiles/definitions/security-event.js.map +1 -0
- package/dist/internal/profiles/definitions/userinfo.d.ts +3 -0
- package/dist/internal/profiles/definitions/userinfo.d.ts.map +1 -0
- package/dist/internal/profiles/definitions/userinfo.js +18 -0
- package/dist/internal/profiles/definitions/userinfo.js.map +1 -0
- package/dist/internal/profiles/registry.d.ts +4 -0
- package/dist/internal/profiles/registry.d.ts.map +1 -0
- package/dist/internal/profiles/registry.js +41 -0
- package/dist/internal/profiles/registry.js.map +1 -0
- package/dist/internal/utils/assemble-common-claims.d.ts +12 -0
- package/dist/internal/utils/assemble-common-claims.d.ts.map +1 -0
- package/dist/internal/utils/assemble-common-claims.js +66 -0
- package/dist/internal/utils/assemble-common-claims.js.map +1 -0
- package/dist/internal/utils/build-profile-claims.d.ts +14 -0
- package/dist/internal/utils/build-profile-claims.d.ts.map +1 -0
- package/dist/internal/utils/build-profile-claims.js +75 -0
- package/dist/internal/utils/build-profile-claims.js.map +1 -0
- package/dist/internal/utils/compute-jwk-thumbprint.js +8 -1
- package/dist/internal/utils/compute-jwk-thumbprint.js.map +1 -1
- package/dist/internal/utils/compute-typ-header.d.ts.map +1 -1
- package/dist/internal/utils/compute-typ-header.js +20 -5
- package/dist/internal/utils/compute-typ-header.js.map +1 -1
- package/dist/internal/utils/create-hash.d.ts.map +1 -1
- package/dist/internal/utils/create-hash.js +7 -7
- package/dist/internal/utils/create-hash.js.map +1 -1
- package/dist/internal/utils/enforce-verify-floor.d.ts +12 -0
- package/dist/internal/utils/enforce-verify-floor.d.ts.map +1 -0
- package/dist/internal/utils/enforce-verify-floor.js +43 -0
- package/dist/internal/utils/enforce-verify-floor.js.map +1 -0
- package/dist/internal/utils/extract-claims.d.ts +2 -1
- package/dist/internal/utils/extract-claims.d.ts.map +1 -1
- package/dist/internal/utils/extract-claims.js +10 -4
- package/dist/internal/utils/extract-claims.js.map +1 -1
- package/dist/internal/utils/jose-header.d.ts.map +1 -1
- package/dist/internal/utils/jose-header.js +38 -7
- package/dist/internal/utils/jose-header.js.map +1 -1
- package/dist/internal/utils/jwt-payload.d.ts +8 -6
- package/dist/internal/utils/jwt-payload.d.ts.map +1 -1
- package/dist/internal/utils/jwt-payload.js +32 -96
- package/dist/internal/utils/jwt-payload.js.map +1 -1
- package/dist/internal/utils/jwt-validate.d.ts.map +1 -1
- package/dist/internal/utils/jwt-validate.js +7 -1
- package/dist/internal/utils/jwt-validate.js.map +1 -1
- package/dist/internal/utils/jwt-verify.d.ts.map +1 -1
- package/dist/internal/utils/jwt-verify.js +17 -4
- package/dist/internal/utils/jwt-verify.js.map +1 -1
- package/dist/internal/utils/map-content-to-claims.d.ts +8 -0
- package/dist/internal/utils/map-content-to-claims.d.ts.map +1 -0
- package/dist/internal/utils/map-content-to-claims.js +89 -0
- package/dist/internal/utils/map-content-to-claims.js.map +1 -0
- package/dist/internal/utils/parse-introspection.d.ts.map +1 -1
- package/dist/internal/utils/parse-introspection.js +5 -1
- package/dist/internal/utils/parse-introspection.js.map +1 -1
- package/dist/internal/utils/parse-userinfo.d.ts.map +1 -1
- package/dist/internal/utils/parse-userinfo.js +5 -1
- package/dist/internal/utils/parse-userinfo.js.map +1 -1
- package/dist/internal/utils/resolve-cert-binding.d.ts.map +1 -1
- package/dist/internal/utils/resolve-cert-binding.js +3 -0
- package/dist/internal/utils/resolve-cert-binding.js.map +1 -1
- package/dist/internal/utils/rules/act-chain-shape.d.ts +4 -0
- package/dist/internal/utils/rules/act-chain-shape.d.ts.map +1 -0
- package/dist/internal/utils/rules/act-chain-shape.js +52 -0
- package/dist/internal/utils/rules/act-chain-shape.js.map +1 -0
- package/dist/internal/utils/rules/alg-permitted.d.ts +6 -0
- package/dist/internal/utils/rules/alg-permitted.d.ts.map +1 -0
- package/dist/internal/utils/rules/alg-permitted.js +35 -0
- package/dist/internal/utils/rules/alg-permitted.js.map +1 -0
- package/dist/internal/utils/rules/at-least-one-of.d.ts +4 -0
- package/dist/internal/utils/rules/at-least-one-of.d.ts.map +1 -0
- package/dist/internal/utils/rules/at-least-one-of.js +13 -0
- package/dist/internal/utils/rules/at-least-one-of.js.map +1 -0
- package/dist/internal/utils/rules/aud-single-resource.d.ts +4 -0
- package/dist/internal/utils/rules/aud-single-resource.d.ts.map +1 -0
- package/dist/internal/utils/rules/aud-single-resource.js +18 -0
- package/dist/internal/utils/rules/aud-single-resource.js.map +1 -0
- package/dist/internal/utils/rules/cnf-shape.d.ts +4 -0
- package/dist/internal/utils/rules/cnf-shape.d.ts.map +1 -0
- package/dist/internal/utils/rules/cnf-shape.js +55 -0
- package/dist/internal/utils/rules/cnf-shape.js.map +1 -0
- package/dist/internal/utils/rules/cross-field.d.ts +4 -0
- package/dist/internal/utils/rules/cross-field.d.ts.map +1 -0
- package/dist/internal/utils/rules/cross-field.js +21 -0
- package/dist/internal/utils/rules/cross-field.js.map +1 -0
- package/dist/internal/utils/rules/events-shape.d.ts +4 -0
- package/dist/internal/utils/rules/events-shape.d.ts.map +1 -0
- package/dist/internal/utils/rules/events-shape.js +33 -0
- package/dist/internal/utils/rules/events-shape.js.map +1 -0
- package/dist/internal/utils/rules/every-element-has-key.d.ts +4 -0
- package/dist/internal/utils/rules/every-element-has-key.d.ts.map +1 -0
- package/dist/internal/utils/rules/every-element-has-key.js +20 -0
- package/dist/internal/utils/rules/every-element-has-key.js.map +1 -0
- package/dist/internal/utils/rules/forbid-present.d.ts +4 -0
- package/dist/internal/utils/rules/forbid-present.d.ts.map +1 -0
- package/dist/internal/utils/rules/forbid-present.js +10 -0
- package/dist/internal/utils/rules/forbid-present.js.map +1 -0
- package/dist/internal/utils/rules/index.d.ts +14 -0
- package/dist/internal/utils/rules/index.d.ts.map +1 -0
- package/dist/internal/utils/rules/index.js +14 -0
- package/dist/internal/utils/rules/index.js.map +1 -0
- package/dist/internal/utils/rules/iss-uri.d.ts +4 -0
- package/dist/internal/utils/rules/iss-uri.d.ts.map +1 -0
- package/dist/internal/utils/rules/iss-uri.js +11 -0
- package/dist/internal/utils/rules/iss-uri.js.map +1 -0
- package/dist/internal/utils/rules/require-present.d.ts +4 -0
- package/dist/internal/utils/rules/require-present.d.ts.map +1 -0
- package/dist/internal/utils/rules/require-present.js +10 -0
- package/dist/internal/utils/rules/require-present.js.map +1 -0
- package/dist/internal/utils/rules/required-when.d.ts +8 -0
- package/dist/internal/utils/rules/required-when.d.ts.map +1 -0
- package/dist/internal/utils/rules/required-when.js +13 -0
- package/dist/internal/utils/rules/required-when.js.map +1 -0
- package/dist/internal/utils/rules/sub-id-shape.d.ts +4 -0
- package/dist/internal/utils/rules/sub-id-shape.d.ts.map +1 -0
- package/dist/internal/utils/rules/sub-id-shape.js +26 -0
- package/dist/internal/utils/rules/sub-id-shape.js.map +1 -0
- package/dist/internal/utils/select-encoder.d.ts +6 -0
- package/dist/internal/utils/select-encoder.d.ts.map +1 -0
- package/dist/internal/utils/select-encoder.js +4 -0
- package/dist/internal/utils/select-encoder.js.map +1 -0
- package/dist/internal/utils/validate-actor.d.ts +8 -1
- package/dist/internal/utils/validate-actor.d.ts.map +1 -1
- package/dist/internal/utils/validate-actor.js +9 -7
- package/dist/internal/utils/validate-actor.js.map +1 -1
- package/dist/internal/utils/validate-profile-claims.d.ts +8 -0
- package/dist/internal/utils/validate-profile-claims.d.ts.map +1 -0
- package/dist/internal/utils/validate-profile-claims.js +45 -0
- package/dist/internal/utils/validate-profile-claims.js.map +1 -0
- package/dist/internal/utils/validate.d.ts.map +1 -1
- package/dist/internal/utils/validate.js +8 -1
- package/dist/internal/utils/validate.js.map +1 -1
- package/dist/internal/utils/verify-cert-binding.d.ts.map +1 -1
- package/dist/internal/utils/verify-cert-binding.js +9 -1
- package/dist/internal/utils/verify-cert-binding.js.map +1 -1
- package/dist/internal/utils/verify-dpop-proof.d.ts.map +1 -1
- package/dist/internal/utils/verify-dpop-proof.js +41 -7
- package/dist/internal/utils/verify-dpop-proof.js.map +1 -1
- package/dist/types/claims/aegis-introspection.d.ts +2 -1
- package/dist/types/claims/aegis-introspection.d.ts.map +1 -1
- package/dist/types/claims/index.d.ts +2 -0
- package/dist/types/claims/index.d.ts.map +1 -1
- package/dist/types/claims/index.js +2 -0
- package/dist/types/claims/index.js.map +1 -1
- package/dist/types/claims/jwt/index.d.ts +2 -0
- package/dist/types/claims/jwt/index.d.ts.map +1 -1
- package/dist/types/claims/jwt/index.js +2 -0
- package/dist/types/claims/jwt/index.js.map +1 -1
- package/dist/types/claims/jwt/jwt-claims.d.ts +3 -1
- package/dist/types/claims/jwt/jwt-claims.d.ts.map +1 -1
- package/dist/types/claims/jwt/lindorm-claims-wire.d.ts +1 -2
- package/dist/types/claims/jwt/lindorm-claims-wire.d.ts.map +1 -1
- package/dist/types/claims/jwt/oidc-claims-wire.d.ts +2 -0
- package/dist/types/claims/jwt/oidc-claims-wire.d.ts.map +1 -1
- package/dist/types/claims/jwt/rar-claims-wire.d.ts +5 -0
- package/dist/types/claims/jwt/rar-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/rar-claims-wire.js +2 -0
- package/dist/types/claims/jwt/rar-claims-wire.js.map +1 -0
- package/dist/types/claims/jwt/set-claims-wire.d.ts +9 -0
- package/dist/types/claims/jwt/set-claims-wire.d.ts.map +1 -0
- package/dist/types/claims/jwt/set-claims-wire.js +2 -0
- package/dist/types/claims/jwt/set-claims-wire.js.map +1 -0
- package/dist/types/claims/lindorm-claims.d.ts +1 -2
- package/dist/types/claims/lindorm-claims.d.ts.map +1 -1
- package/dist/types/claims/oidc-claims.d.ts +2 -0
- package/dist/types/claims/oidc-claims.d.ts.map +1 -1
- package/dist/types/claims/rar-claims.d.ts +5 -0
- package/dist/types/claims/rar-claims.d.ts.map +1 -0
- package/dist/types/claims/rar-claims.js +2 -0
- package/dist/types/claims/rar-claims.js.map +1 -0
- package/dist/types/claims/set-claims.d.ts +8 -0
- package/dist/types/claims/set-claims.d.ts.map +1 -0
- package/dist/types/claims/set-claims.js +2 -0
- package/dist/types/claims/set-claims.js.map +1 -0
- package/dist/types/jwt/index.d.ts +1 -0
- package/dist/types/jwt/index.d.ts.map +1 -1
- package/dist/types/jwt/index.js +1 -0
- package/dist/types/jwt/index.js.map +1 -1
- package/dist/types/jwt/jwt-claim-matchers.d.ts +2 -1
- package/dist/types/jwt/jwt-claim-matchers.d.ts.map +1 -1
- package/dist/types/jwt/jwt-parse.d.ts +2 -2
- package/dist/types/jwt/jwt-parse.d.ts.map +1 -1
- package/dist/types/jwt/jwt-sign.d.ts +8 -6
- package/dist/types/jwt/jwt-sign.d.ts.map +1 -1
- package/dist/types/jwt/profile.d.ts +99 -0
- package/dist/types/jwt/profile.d.ts.map +1 -0
- package/dist/types/jwt/profile.js +2 -0
- package/dist/types/jwt/profile.js.map +1 -0
- package/dist/types/level-of-assurance.d.ts +0 -1
- package/dist/types/level-of-assurance.d.ts.map +1 -1
- package/package.json +19 -18
package/README.md
CHANGED
|
@@ -20,8 +20,8 @@ npm install @lindorm/amphora @lindorm/logger
|
|
|
20
20
|
|
|
21
21
|
Aegis exposes two layers:
|
|
22
22
|
|
|
23
|
-
- **`Aegis`** — async façade that resolves keys from an `IAmphora` key store and delegates to the kit classes. Use this when you want JWT/JWS/JWE operations driven by a managed key store with `kid`-based lookup.
|
|
24
|
-
- **Kit classes** (`JwtKit`, `JwsKit`, `JweKit`, `SignatureKit`) — synchronous, single-key primitives. You supply an `IKryptos` key directly. Use these when you already have the key in hand and don't need the Amphora layer.
|
|
23
|
+
- **`Aegis`** — async façade that resolves keys from an `IAmphora` key store and delegates to the kit classes. Use this when you want JWT/JWS/JWE or COSE/CWT operations driven by a managed key store with `kid`-based lookup.
|
|
24
|
+
- **Kit classes** (`JwtKit`, `JwsKit`, `JweKit`, `SignatureKit`, plus the `CoseKit` COSE facade) — synchronous, single-key primitives. You supply an `IKryptos` key directly. Use these when you already have the key in hand and don't need the Amphora layer.
|
|
25
25
|
|
|
26
26
|
The `Aegis` instance methods are async because they perform key lookups. All kit instance methods are synchronous.
|
|
27
27
|
|
|
@@ -80,7 +80,7 @@ const plain = await aegis.aes.decrypt(encoded);
|
|
|
80
80
|
|
|
81
81
|
### Universal verification
|
|
82
82
|
|
|
83
|
-
`aegis.verify` auto-detects JWT, JWS, and JWE compact serialisations. JWE inputs are decrypted first, then the inner payload is re-verified.
|
|
83
|
+
`aegis.verify` auto-detects JWT, JWS, and JWE compact serialisations. JWE inputs are decrypted first, then the inner payload is re-verified. A COSE token (base64url CBOR, no JOSE dot structure) is also auto-detected and its integrity verified — see [COSE / CWT](#cose--cwt).
|
|
84
84
|
|
|
85
85
|
```typescript
|
|
86
86
|
const result = await aegis.verify(anyToken, {
|
|
@@ -200,6 +200,59 @@ kit.assert(data, signature); // throws on mismatch
|
|
|
200
200
|
const formatted = kit.format(signature); // string
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
+
## COSE / CWT
|
|
204
|
+
|
|
205
|
+
Every token profile can be issued as a CBOR Web Token (CWT, RFC 8392) instead of a JWT by passing `format: "cose"` — the same profile, the same domain claims, the same validation floor, only the wire encoding differs. The token is returned as a base64url string.
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const { token } = await aegis.mint(
|
|
209
|
+
"access_token",
|
|
210
|
+
{ subject: "user-123", audience: ["https://api.example.com"], clientId: "app-1" },
|
|
211
|
+
{ format: "cose" },
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const verified = await aegis.verify("access_token", token, {
|
|
215
|
+
format: "cose",
|
|
216
|
+
audience: "https://api.example.com",
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// …or let aegis auto-detect it (no profile, no format flag — integrity only):
|
|
220
|
+
const smart = await aegis.verify(token);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Token structure
|
|
224
|
+
|
|
225
|
+
The COSE structure follows the key and the profile:
|
|
226
|
+
|
|
227
|
+
- **Signed** — an asymmetric key produces a `COSE_Sign1` (the default).
|
|
228
|
+
- **MAC'd** — a symmetric `oct` key produces a `COSE_Mac0` (HMAC is a MAC algorithm, never a `COSE_Sign1` signature). The same `algClass` policy applies as for JWTs.
|
|
229
|
+
- **Encrypted** — an encryptable profile minted with `encrypt` (or carrying `sensitive_identity`) is sign-then-encrypted into a `COSE_Encrypt0`. Direct AES-GCM and AES-CCM (all eight RFC 9053 variants) are supported.
|
|
230
|
+
|
|
231
|
+
### `typ` and proprietary encoding
|
|
232
|
+
|
|
233
|
+
The COSE `typ` header carries the CWT media type — `application/at+cwt`, `application/secevent+cwt`, etc. (the JWT path's `application/at+jwt` family with the `+jwt` suffix swapped for `+cwt`; bare `JWT` → `application/cwt`, the one IANA-registered CWT type).
|
|
234
|
+
|
|
235
|
+
By default the claims use lindorm-proprietary compact encodings (integer-keyed `act` / `sub_id`, private-use labels for lindorm-only claims). Pass `proprietary: false` to emit a fully interoperable, string-keyed payload that a stock COSE/CWT verifier reads, at the cost of larger tokens:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
await aegis.mint("access_token", content, { format: "cose", proprietary: false });
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Either way the signature itself is plain RFC 9052 — verified in interop tests against `@auth0/cose` and `cose-js`.
|
|
242
|
+
|
|
243
|
+
### CoseKit
|
|
244
|
+
|
|
245
|
+
`CoseKit` is the synchronous facade behind the COSE path (the COSE analogue of the JOSE kits). It also exposes the **COSE Key Thumbprint** (`ckt`, RFC 9679):
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { CoseKit } from "@lindorm/aegis";
|
|
249
|
+
|
|
250
|
+
const ckt = CoseKit.thumbprint(kryptos); // raw SHA-256 digest bytes
|
|
251
|
+
const uri = CoseKit.thumbprintUri(kryptos); // urn:ietf:params:oauth:ckt:sha-256:…
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
> The `ckt` is **not** the same value as `kryptos.thumbprint` (the RFC 7638 `jkt`): the `ckt` hashes the deterministic-CBOR COSE_Key, the `jkt` hashes the canonical JSON JWK, so the same key has two different fingerprints. They are not interchangeable in a key-binding check.
|
|
255
|
+
|
|
203
256
|
## Sign content shape
|
|
204
257
|
|
|
205
258
|
`SignJwtContent` accepts the standard, OIDC, OAuth, PoP, delegation, and Lindorm claim families plus:
|
|
@@ -217,6 +270,7 @@ const formatted = kit.format(signature); // string
|
|
|
217
270
|
roles?: string[];
|
|
218
271
|
groups?: string[];
|
|
219
272
|
entitlements?: string[];
|
|
273
|
+
authorizationDetails?: AuthorizationDetail[]; // RFC 9396 (RAR) — see below
|
|
220
274
|
clientId?: string;
|
|
221
275
|
grantType?: string;
|
|
222
276
|
tenantId?: string;
|
|
@@ -228,7 +282,6 @@ const formatted = kit.format(signature); // string
|
|
|
228
282
|
authFactor?: string[];
|
|
229
283
|
authMethods?: string[];
|
|
230
284
|
authorizedParty?: string;
|
|
231
|
-
adjustedAccessLevel?: number;
|
|
232
285
|
levelOfAssurance?: number;
|
|
233
286
|
sessionHint?: string;
|
|
234
287
|
subjectHint?: string;
|
|
@@ -236,6 +289,32 @@ const formatted = kit.format(signature); // string
|
|
|
236
289
|
}
|
|
237
290
|
```
|
|
238
291
|
|
|
292
|
+
### Rich Authorization Requests (RFC 9396)
|
|
293
|
+
|
|
294
|
+
`authorizationDetails` carries the RFC 9396 `authorization_details` claim. The
|
|
295
|
+
domain name (`authorizationDetails`) is translated to the registered wire name
|
|
296
|
+
(`authorization_details`) on sign and back on parse. The array **contents travel
|
|
297
|
+
verbatim** — type-specific inner fields (e.g. `instructedAmount`,
|
|
298
|
+
`creditorAccount`) are never key-converted, so camelCase fields defined by a
|
|
299
|
+
detail's own spec are preserved exactly. The claim also surfaces from
|
|
300
|
+
`parseIntrospection` (RFC 9396 §9).
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
kit.sign({
|
|
304
|
+
expires: "1h",
|
|
305
|
+
subject: "user-123",
|
|
306
|
+
tokenType: "access_token",
|
|
307
|
+
authorizationDetails: [
|
|
308
|
+
{
|
|
309
|
+
type: "payment_initiation",
|
|
310
|
+
actions: ["initiate"],
|
|
311
|
+
locations: ["https://api.bank.example.com/payments"],
|
|
312
|
+
instructedAmount: { currency: "EUR", amount: "123.50" }, // verbatim
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
239
318
|
## Verify options
|
|
240
319
|
|
|
241
320
|
`VerifyJwtOptions` extends the claim matcher set. Each field accepts either a literal value or a `PredicateOperator` for flexible matching:
|
|
@@ -284,7 +363,7 @@ import {
|
|
|
284
363
|
|
|
285
364
|
## Security notes
|
|
286
365
|
|
|
287
|
-
- Signature/decryption keys are always sourced from the supplied `IAmphora`. The `jku`, `jwk`, `x5u`, `x5c`, `x5t`, and `x5t#S256` JOSE header parameters are never trusted as key sources during verification — only `kid` is used as a lookup key into Amphora.
|
|
366
|
+
- Signature/decryption keys are always sourced from the supplied `IAmphora`. The `jku`, `jwk`, `x5u`, `x5c`, `x5t`, and `x5t#S256` JOSE header parameters are never trusted as key sources during verification — only `kid` is used as a lookup key into Amphora. The COSE verify path is the same: the signing/encryption key is resolved only by the COSE `kid` (unprotected header, label 4), never from anything embedded in the token.
|
|
288
367
|
- JWE payload compression (`zip` header) is rejected outright.
|
|
289
368
|
- Critical header parameters are enforced per RFC 7515 §4.1.11; unknown `crit` entries cause verification to fail.
|
|
290
369
|
- DPoP-bound tokens (`cnf.jkt`) require either a matching DPoP proof or `trustBoundThumbprint: true` on verify.
|
package/dist/classes/Aegis.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Dict } from "@lindorm/types";
|
|
2
2
|
import type { IAegis, IAegisAes, IAegisJwe, IAegisJws, IAegisJwt } from "../interfaces/index.js";
|
|
3
|
-
import type { AegisIntrospection, AegisOptions, AegisUserinfo, DecodedJwe, DecodedJws, DecodedJwt, ParsedJws, ParsedJwt, TokenHeaderClaims, ValidateJwtOptions, VerifyJwtOptions } from "../types/index.js";
|
|
3
|
+
import type { AegisIntrospection, AegisOptions, AegisUserinfo, DecodedJwe, DecodedJws, DecodedJwt, ParsedJws, ParsedJwt, ProfileContent, ProfileSignOptions, ProfileVerifyOptions, RawSignInput, SignContent, SignedJws, SignedJwt, TokenHeaderClaims, TokenProfile, ValidateJwtOptions, VerifyJwtOptions } from "../types/index.js";
|
|
4
4
|
import { type IntrospectClaimsInput } from "../internal/utils/parse-introspection.js";
|
|
5
5
|
import { type UserinfoClaimsInput } from "../internal/utils/parse-userinfo.js";
|
|
6
6
|
export declare class Aegis implements IAegis {
|
|
@@ -8,9 +8,11 @@ export declare class Aegis implements IAegis {
|
|
|
8
8
|
private readonly amphora;
|
|
9
9
|
private readonly certBindingMode;
|
|
10
10
|
private readonly clockTolerance;
|
|
11
|
+
private readonly coseKit;
|
|
11
12
|
private readonly dpopMaxSkew;
|
|
12
13
|
private readonly encAlgorithm;
|
|
13
14
|
private readonly encryption;
|
|
15
|
+
private readonly joseKit;
|
|
14
16
|
private readonly logger;
|
|
15
17
|
private readonly sigAlgorithm;
|
|
16
18
|
constructor(options: AegisOptions);
|
|
@@ -18,7 +20,15 @@ export declare class Aegis implements IAegis {
|
|
|
18
20
|
get jwe(): IAegisJwe;
|
|
19
21
|
get jws(): IAegisJws;
|
|
20
22
|
get jwt(): IAegisJwt;
|
|
21
|
-
|
|
23
|
+
registerProfile(profile: TokenProfile): void;
|
|
24
|
+
sign(input: RawSignInput): Promise<SignedJws>;
|
|
25
|
+
mint<P extends keyof ProfileContent>(profile: P, content: ProfileContent[P], options?: ProfileSignOptions): Promise<SignedJwt>;
|
|
26
|
+
mint(profile: string & {}, content: SignContent, options?: ProfileSignOptions): Promise<SignedJwt>;
|
|
27
|
+
verify(token: string): Promise<ParsedJwt | ParsedJws<any>>;
|
|
28
|
+
verify<T extends ParsedJws<any>>(token: string): Promise<T>;
|
|
29
|
+
verify<T extends ParsedJwt>(token: string, options?: VerifyJwtOptions): Promise<T>;
|
|
30
|
+
verify<T extends ParsedJwt>(profile: string, token: string, options: ProfileVerifyOptions): Promise<T>;
|
|
31
|
+
private verifySmart;
|
|
22
32
|
static header(token: string): TokenHeaderClaims;
|
|
23
33
|
static isJwe(jwe: string): boolean;
|
|
24
34
|
static isJws(jws: string): boolean;
|
|
@@ -31,14 +41,19 @@ export declare class Aegis implements IAegis {
|
|
|
31
41
|
private aesKit;
|
|
32
42
|
private aesEncrypt;
|
|
33
43
|
private aesDecrypt;
|
|
34
|
-
private jweKit;
|
|
35
44
|
private jweEncrypt;
|
|
36
45
|
private jweDecrypt;
|
|
37
|
-
private jwsKit;
|
|
38
46
|
private jwsSign;
|
|
39
47
|
private jwsVerify;
|
|
40
|
-
private jwtKit;
|
|
41
48
|
private jwtSign;
|
|
49
|
+
private signRaw;
|
|
50
|
+
private mintProfile;
|
|
51
|
+
private mintCose;
|
|
52
|
+
private verifyCose;
|
|
53
|
+
private coseVerifyCore;
|
|
54
|
+
private warnAlgAdvisory;
|
|
55
|
+
private resolveEncKey;
|
|
56
|
+
private verifyProfile;
|
|
42
57
|
private jwtVerify;
|
|
43
58
|
private kryptosEnc;
|
|
44
59
|
private kryptosSig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aegis.d.ts","sourceRoot":"","sources":["../../src/classes/Aegis.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Aegis.d.ts","sourceRoot":"","sources":["../../src/classes/Aegis.ts"],"names":[],"mappings":"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"}
|
package/dist/classes/Aegis.js
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { AesKit, } from "@lindorm/aes";
|
|
2
|
+
import { getUnixTime } from "@lindorm/date";
|
|
3
|
+
import { isBuffer, isDate, isString } from "@lindorm/is";
|
|
4
|
+
import { removeUndefined } from "@lindorm/utils";
|
|
2
5
|
import { AegisError } from "../errors/index.js";
|
|
6
|
+
import { CoseKit } from "./CoseKit.js";
|
|
7
|
+
import { assembleCommonClaims } from "../internal/utils/assemble-common-claims.js";
|
|
8
|
+
import { coseTyp } from "../internal/cose/cose-typ.js";
|
|
9
|
+
import { algAdvisory } from "../internal/utils/rules/alg-permitted.js";
|
|
10
|
+
import { buildProfileClaims } from "../internal/utils/build-profile-claims.js";
|
|
11
|
+
import { selectEncoder } from "../internal/utils/select-encoder.js";
|
|
12
|
+
import { validateProfileClaims } from "../internal/utils/validate-profile-claims.js";
|
|
13
|
+
import { enforceVerifyFloor } from "../internal/utils/enforce-verify-floor.js";
|
|
14
|
+
import { registerProfile as registerProfileFn, resolveProfile, } from "../internal/profiles/registry.js";
|
|
3
15
|
import { createJwtValidate } from "../internal/utils/jwt-validate.js";
|
|
4
16
|
import { validate as validateClaims } from "../internal/utils/validate.js";
|
|
5
17
|
import { decodeJoseHeader } from "../internal/utils/jose-header.js";
|
|
@@ -8,26 +20,38 @@ import { parseUserinfo, } from "../internal/utils/parse-userinfo.js";
|
|
|
8
20
|
import { JweKit } from "./JweKit.js";
|
|
9
21
|
import { JwsKit } from "./JwsKit.js";
|
|
10
22
|
import { JwtKit } from "./JwtKit.js";
|
|
23
|
+
import { JoseKit } from "./JoseKit.js";
|
|
11
24
|
export class Aegis {
|
|
12
25
|
issuer;
|
|
13
26
|
amphora;
|
|
14
27
|
certBindingMode;
|
|
15
28
|
clockTolerance;
|
|
29
|
+
coseKit;
|
|
16
30
|
dpopMaxSkew;
|
|
17
31
|
encAlgorithm;
|
|
18
32
|
encryption;
|
|
33
|
+
joseKit;
|
|
19
34
|
logger;
|
|
20
35
|
sigAlgorithm;
|
|
21
36
|
constructor(options) {
|
|
22
37
|
this.logger = options.logger.child(["AegisKit"]);
|
|
23
38
|
this.amphora = options.amphora;
|
|
24
39
|
this.issuer = options.issuer ?? this.amphora.domain;
|
|
40
|
+
this.coseKit = new CoseKit({ logger: this.logger });
|
|
25
41
|
this.certBindingMode = options.certBindingMode ?? "strict";
|
|
26
42
|
this.clockTolerance = options.clockTolerance ?? 0;
|
|
27
43
|
this.dpopMaxSkew = options.dpopMaxSkew;
|
|
28
44
|
this.encAlgorithm = options.encAlgorithm;
|
|
29
45
|
this.encryption = options.encryption ?? "A256GCM";
|
|
30
46
|
this.sigAlgorithm = options.sigAlgorithm;
|
|
47
|
+
this.joseKit = new JoseKit({
|
|
48
|
+
certBindingMode: this.certBindingMode,
|
|
49
|
+
clockTolerance: this.clockTolerance,
|
|
50
|
+
dpopMaxSkew: this.dpopMaxSkew,
|
|
51
|
+
encryption: this.encryption,
|
|
52
|
+
issuer: this.issuer ?? undefined,
|
|
53
|
+
logger: this.logger,
|
|
54
|
+
});
|
|
31
55
|
}
|
|
32
56
|
get aes() {
|
|
33
57
|
return {
|
|
@@ -53,18 +77,45 @@ export class Aegis {
|
|
|
53
77
|
verify: this.jwtVerify.bind(this),
|
|
54
78
|
};
|
|
55
79
|
}
|
|
56
|
-
|
|
80
|
+
registerProfile(profile) {
|
|
81
|
+
registerProfileFn(profile);
|
|
82
|
+
}
|
|
83
|
+
sign(input) {
|
|
84
|
+
return this.signRaw(input);
|
|
85
|
+
}
|
|
86
|
+
mint(profile, content, options = {}) {
|
|
87
|
+
return this.mintProfile(profile, content, options);
|
|
88
|
+
}
|
|
89
|
+
async verify(tokenOrProfile, optionsOrToken, profileOptions) {
|
|
90
|
+
if (isString(optionsOrToken)) {
|
|
91
|
+
return this.verifyProfile(tokenOrProfile, optionsOrToken, profileOptions ?? {});
|
|
92
|
+
}
|
|
93
|
+
return this.verifySmart(tokenOrProfile, optionsOrToken);
|
|
94
|
+
}
|
|
95
|
+
async verifySmart(token, options) {
|
|
57
96
|
if (Aegis.isJwt(token)) {
|
|
58
97
|
return (await this.jwtVerify(token, options));
|
|
59
98
|
}
|
|
60
99
|
if (Aegis.isJwe(token)) {
|
|
61
100
|
const decrypt = await this.jweDecrypt(token);
|
|
62
|
-
return await this.
|
|
101
|
+
return await this.verifySmart(decrypt.payload, options);
|
|
63
102
|
}
|
|
64
103
|
if (Aegis.isJws(token)) {
|
|
65
104
|
return (await this.jwsVerify(token));
|
|
66
105
|
}
|
|
67
|
-
|
|
106
|
+
if (!token.includes(".")) {
|
|
107
|
+
const bytes = Buffer.from(token, "base64url");
|
|
108
|
+
if (this.coseKit.isCose(bytes)) {
|
|
109
|
+
const { claims, decoded } = await this.coseVerifyCore(bytes);
|
|
110
|
+
return { claims, header: decoded };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
throw new AegisError("Invalid token type", {
|
|
114
|
+
code: "unsupported_token_type",
|
|
115
|
+
debug: { token },
|
|
116
|
+
title: "Unsupported Token Type",
|
|
117
|
+
details: "The token is not a recognised JWT, JWE, JWS, or COSE token, so Aegis cannot select a kit to verify it.",
|
|
118
|
+
});
|
|
68
119
|
}
|
|
69
120
|
static header(token) {
|
|
70
121
|
const [header] = token.split(".");
|
|
@@ -89,7 +140,12 @@ export class Aegis {
|
|
|
89
140
|
if (Aegis.isJwt(token)) {
|
|
90
141
|
return JwtKit.decode(token);
|
|
91
142
|
}
|
|
92
|
-
throw new AegisError("Invalid token type", {
|
|
143
|
+
throw new AegisError("Invalid token type", {
|
|
144
|
+
code: "unsupported_token_type",
|
|
145
|
+
debug: { token },
|
|
146
|
+
title: "Unsupported Token Type",
|
|
147
|
+
details: "The token is not a recognised JWT, JWE, or JWS, so Aegis cannot select a kit to decode it.",
|
|
148
|
+
});
|
|
93
149
|
}
|
|
94
150
|
static parse(token) {
|
|
95
151
|
if (Aegis.isJwt(token)) {
|
|
@@ -98,7 +154,12 @@ export class Aegis {
|
|
|
98
154
|
if (Aegis.isJws(token)) {
|
|
99
155
|
return JwsKit.parse(token);
|
|
100
156
|
}
|
|
101
|
-
throw new AegisError("Invalid token type", {
|
|
157
|
+
throw new AegisError("Invalid token type", {
|
|
158
|
+
code: "unsupported_token_type",
|
|
159
|
+
debug: { token },
|
|
160
|
+
title: "Unsupported Token Type",
|
|
161
|
+
details: "The token is not a recognised JWT or JWS, so Aegis cannot select a kit to parse it.",
|
|
162
|
+
});
|
|
102
163
|
}
|
|
103
164
|
static parseUserinfo(data) {
|
|
104
165
|
return parseUserinfo(data);
|
|
@@ -126,69 +187,222 @@ export class Aegis {
|
|
|
126
187
|
});
|
|
127
188
|
return kit.decrypt(data);
|
|
128
189
|
}
|
|
129
|
-
async jweKit(options = {}) {
|
|
130
|
-
const kryptos = await this.kryptosEnc(options);
|
|
131
|
-
return new JweKit({
|
|
132
|
-
certBindingMode: this.certBindingMode,
|
|
133
|
-
encryption: this.encryption,
|
|
134
|
-
kryptos,
|
|
135
|
-
logger: this.logger,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
190
|
async jweEncrypt(data, options = {}) {
|
|
139
|
-
const
|
|
140
|
-
return
|
|
191
|
+
const kryptos = await this.kryptosEnc({ encrypt: true });
|
|
192
|
+
return this.joseKit.encryptJwe(kryptos, data, options);
|
|
141
193
|
}
|
|
142
194
|
async jweDecrypt(jwe) {
|
|
143
195
|
const decode = JweKit.decode(jwe);
|
|
144
|
-
const
|
|
196
|
+
const kryptos = await this.kryptosEnc({
|
|
145
197
|
id: decode.header.kid,
|
|
146
198
|
algorithm: decode.header.alg,
|
|
147
199
|
});
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
async jwsKit(options = {}) {
|
|
151
|
-
const kryptos = await this.kryptosSig(options);
|
|
152
|
-
return new JwsKit({
|
|
153
|
-
certBindingMode: this.certBindingMode,
|
|
154
|
-
kryptos,
|
|
155
|
-
logger: this.logger,
|
|
156
|
-
});
|
|
200
|
+
return this.joseKit.decryptJwe(kryptos, jwe);
|
|
157
201
|
}
|
|
158
202
|
async jwsSign(data, options = {}) {
|
|
159
|
-
const
|
|
160
|
-
return
|
|
203
|
+
const kryptos = await this.kryptosSig({ sign: true });
|
|
204
|
+
return this.joseKit.signJws(kryptos, data, options);
|
|
161
205
|
}
|
|
162
206
|
async jwsVerify(jws) {
|
|
163
207
|
const decode = JwsKit.decode(jws);
|
|
164
|
-
const
|
|
208
|
+
const kryptos = await this.kryptosSig({
|
|
165
209
|
id: decode.header.kid,
|
|
166
210
|
algorithm: decode.header.alg,
|
|
167
211
|
});
|
|
168
|
-
return
|
|
212
|
+
return this.joseKit.verifyJws(kryptos, jws);
|
|
169
213
|
}
|
|
170
|
-
async
|
|
171
|
-
const kryptos = await this.kryptosSig(
|
|
172
|
-
return
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
214
|
+
async jwtSign(content, options = {}) {
|
|
215
|
+
const kryptos = await this.kryptosSig({ sign: true });
|
|
216
|
+
return this.joseKit.signJwt(kryptos, content, options);
|
|
217
|
+
}
|
|
218
|
+
async signRaw(input) {
|
|
219
|
+
const payload = isString(input.payload) || isBuffer(input.payload)
|
|
220
|
+
? input.payload
|
|
221
|
+
: JSON.stringify(input.payload);
|
|
222
|
+
return this.jwsSign(payload, {
|
|
223
|
+
bindCertificate: input.bindCertificate,
|
|
224
|
+
contentType: input.contentType,
|
|
225
|
+
header: input.header,
|
|
226
|
+
objectId: input.objectId,
|
|
227
|
+
tokenType: input.tokenType,
|
|
179
228
|
});
|
|
180
229
|
}
|
|
181
|
-
async
|
|
182
|
-
|
|
183
|
-
|
|
230
|
+
async mintProfile(name, content, options) {
|
|
231
|
+
if (selectEncoder(options.format).format === "cose") {
|
|
232
|
+
return this.mintCose(name, content, options);
|
|
233
|
+
}
|
|
234
|
+
const profile = resolveProfile(name);
|
|
235
|
+
if (options.encrypt !== undefined && !profile.encryptable) {
|
|
236
|
+
throw new AegisError("Encryption is not allowed for this profile", {
|
|
237
|
+
code: "encryption_not_allowed",
|
|
238
|
+
data: { profile: profile.name },
|
|
239
|
+
title: "Encryption Not Allowed",
|
|
240
|
+
details: "This token profile is not encryptable, so an encrypt option cannot be supplied; remove it or use an encryptable profile.",
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
const kryptos = await this.kryptosSig({ sign: true });
|
|
244
|
+
const hasSensitiveIdentity = content.sensitiveIdentity != null;
|
|
245
|
+
const explicitEncrypt = options.encrypt !== undefined;
|
|
246
|
+
const wantsEncryption = profile.encryptable && (explicitEncrypt || hasSensitiveIdentity);
|
|
247
|
+
const encKryptos = wantsEncryption
|
|
248
|
+
? await this.resolveEncKey({
|
|
249
|
+
id: options.encrypt?.kid,
|
|
250
|
+
algorithm: options.encrypt?.algorithm,
|
|
251
|
+
predicate: options.encrypt?.predicate,
|
|
252
|
+
}, explicitEncrypt)
|
|
253
|
+
: undefined;
|
|
254
|
+
const signContent = hasSensitiveIdentity && !encKryptos
|
|
255
|
+
? removeUndefined({ ...content, sensitiveIdentity: undefined })
|
|
256
|
+
: content;
|
|
257
|
+
const common = assembleCommonClaims({ algorithm: kryptos.algorithm, issuer: this.issuer }, profile, signContent, options);
|
|
258
|
+
validateProfileClaims(profile, common, {
|
|
259
|
+
...(options.context ?? {}),
|
|
260
|
+
algorithm: kryptos.algorithm,
|
|
261
|
+
});
|
|
262
|
+
this.warnAlgAdvisory(profile, kryptos.algorithm);
|
|
263
|
+
const claims = buildProfileClaims({ algorithm: kryptos.algorithm, issuer: this.issuer }, profile, {
|
|
264
|
+
...signContent,
|
|
265
|
+
notBefore: common.notBefore,
|
|
266
|
+
issuer: common.issuer,
|
|
267
|
+
expires: common.expiresAt,
|
|
268
|
+
}, {
|
|
269
|
+
...options,
|
|
270
|
+
issuedAt: common.issuedAt,
|
|
271
|
+
tokenId: common.tokenId,
|
|
272
|
+
});
|
|
273
|
+
const signed = this.joseKit.signClaims(kryptos, claims, signContent, {
|
|
274
|
+
...options,
|
|
275
|
+
...(profile.typ !== null ? { typ: profile.typ } : {}),
|
|
276
|
+
});
|
|
277
|
+
if (!encKryptos) {
|
|
278
|
+
return signed;
|
|
279
|
+
}
|
|
280
|
+
const { token } = this.joseKit.encryptJwe(encKryptos, signed.token);
|
|
281
|
+
return { ...signed, token };
|
|
282
|
+
}
|
|
283
|
+
async mintCose(name, content, options) {
|
|
284
|
+
const profile = resolveProfile(name);
|
|
285
|
+
if (options.encrypt !== undefined && !profile.encryptable) {
|
|
286
|
+
throw new AegisError("Encryption is not allowed for this profile", {
|
|
287
|
+
code: "encryption_not_allowed",
|
|
288
|
+
data: { profile: profile.name },
|
|
289
|
+
title: "Encryption Not Allowed",
|
|
290
|
+
details: "This token profile is not encryptable, so an encrypt option cannot be supplied; remove it or use an encryptable profile.",
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
const hasSensitiveIdentity = content.sensitiveIdentity != null;
|
|
294
|
+
const explicitEncrypt = options.encrypt !== undefined;
|
|
295
|
+
const wantsEncryption = profile.encryptable && (explicitEncrypt || hasSensitiveIdentity);
|
|
296
|
+
const encKryptos = wantsEncryption
|
|
297
|
+
? await this.resolveEncKey({
|
|
298
|
+
id: options.encrypt?.kid,
|
|
299
|
+
algorithm: options.encrypt?.algorithm,
|
|
300
|
+
predicate: options.encrypt?.predicate,
|
|
301
|
+
}, explicitEncrypt)
|
|
302
|
+
: undefined;
|
|
303
|
+
const signContent = hasSensitiveIdentity && !encKryptos
|
|
304
|
+
? removeUndefined({ ...content, sensitiveIdentity: undefined })
|
|
305
|
+
: content;
|
|
306
|
+
const kryptos = await this.kryptosSig({ sign: true });
|
|
307
|
+
const common = assembleCommonClaims({ algorithm: kryptos.algorithm, issuer: this.issuer }, profile, signContent, options);
|
|
308
|
+
validateProfileClaims(profile, common, {
|
|
309
|
+
...(options.context ?? {}),
|
|
310
|
+
algorithm: kryptos.algorithm,
|
|
311
|
+
});
|
|
312
|
+
this.warnAlgAdvisory(profile, kryptos.algorithm);
|
|
313
|
+
let token = this.coseKit.sign(kryptos, common, {
|
|
314
|
+
typ: coseTyp(profile.typ),
|
|
315
|
+
proprietary: options.proprietary,
|
|
316
|
+
});
|
|
317
|
+
if (encKryptos) {
|
|
318
|
+
token = this.coseKit.encrypt(encKryptos, token, {
|
|
319
|
+
typ: coseTyp(profile.typ),
|
|
320
|
+
encryption: this.encryption,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
const expiresAt = isDate(common.expiresAt) ? common.expiresAt : undefined;
|
|
324
|
+
const expiresOn = expiresAt ? getUnixTime(expiresAt) : undefined;
|
|
325
|
+
return {
|
|
326
|
+
token: token.toString("base64url"),
|
|
327
|
+
expiresAt,
|
|
328
|
+
expiresIn: expiresOn ? expiresOn - getUnixTime(new Date()) : undefined,
|
|
329
|
+
expiresOn,
|
|
330
|
+
objectId: undefined,
|
|
331
|
+
tokenId: isString(common.tokenId) ? common.tokenId : undefined,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
async verifyCose(name, token, options) {
|
|
335
|
+
const profile = resolveProfile(name);
|
|
336
|
+
const { claims, decoded, typ } = await this.coseVerifyCore(Buffer.from(token, "base64url"));
|
|
337
|
+
const expectedIssuer = options.issuer ??
|
|
338
|
+
(profile.issuer === "platform" ? (this.issuer ?? undefined) : undefined);
|
|
339
|
+
enforceVerifyFloor({
|
|
340
|
+
audience: options.audience,
|
|
341
|
+
decodedTyp: typ,
|
|
342
|
+
expectedTyp: coseTyp(profile.typ),
|
|
343
|
+
expectedIssuer,
|
|
344
|
+
payload: claims,
|
|
345
|
+
profile,
|
|
346
|
+
});
|
|
347
|
+
return { claims, header: decoded };
|
|
348
|
+
}
|
|
349
|
+
async coseVerifyCore(input) {
|
|
350
|
+
let bytes = input;
|
|
351
|
+
if (this.coseKit.isEncrypted(bytes)) {
|
|
352
|
+
const encKryptos = await this.kryptosEnc({
|
|
353
|
+
id: this.coseKit.decodeEncryptedKid(bytes),
|
|
354
|
+
});
|
|
355
|
+
bytes = this.coseKit.decrypt(encKryptos, bytes);
|
|
356
|
+
}
|
|
357
|
+
const decoded = this.coseKit.decode(bytes);
|
|
358
|
+
const kryptos = await this.kryptosSig({ id: decoded.kid });
|
|
359
|
+
const { claims, typ } = this.coseKit.verify(kryptos, bytes);
|
|
360
|
+
return { claims, decoded, typ };
|
|
361
|
+
}
|
|
362
|
+
warnAlgAdvisory(profile, algorithm) {
|
|
363
|
+
const advisory = profile.algClass
|
|
364
|
+
? algAdvisory(algorithm, profile.algClass)
|
|
365
|
+
: undefined;
|
|
366
|
+
if (advisory) {
|
|
367
|
+
this.logger.warn(advisory, { profile: profile.name, algorithm });
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
async resolveEncKey(options, required) {
|
|
371
|
+
try {
|
|
372
|
+
return await this.kryptosEnc({ encrypt: true, ...options });
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
if (required) {
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
return undefined;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async verifyProfile(name, token, options) {
|
|
382
|
+
if (selectEncoder(options.format).format === "cose") {
|
|
383
|
+
return this.verifyCose(name, token, options);
|
|
384
|
+
}
|
|
385
|
+
const profile = resolveProfile(name);
|
|
386
|
+
const { audience: _audience, issuer: _issuer, clockTolerance: _ct, format: _format, ...rest } = options;
|
|
387
|
+
const parsed = await this.verifySmart(token, rest);
|
|
388
|
+
const expectedIssuer = options.issuer ??
|
|
389
|
+
(profile.issuer === "platform" ? (this.issuer ?? undefined) : undefined);
|
|
390
|
+
enforceVerifyFloor({
|
|
391
|
+
audience: options.audience,
|
|
392
|
+
decodedTyp: parsed.decoded.header.typ,
|
|
393
|
+
expectedIssuer,
|
|
394
|
+
payload: parsed.payload,
|
|
395
|
+
profile,
|
|
396
|
+
});
|
|
397
|
+
return parsed;
|
|
184
398
|
}
|
|
185
399
|
async jwtVerify(jwt, verify = {}) {
|
|
186
400
|
const decode = JwtKit.decode(jwt);
|
|
187
|
-
const
|
|
401
|
+
const kryptos = await this.kryptosSig({
|
|
188
402
|
id: decode.header.kid,
|
|
189
403
|
algorithm: decode.header.alg,
|
|
190
404
|
});
|
|
191
|
-
return
|
|
405
|
+
return this.joseKit.verifyJwt(kryptos, jwt, verify);
|
|
192
406
|
}
|
|
193
407
|
async kryptosEnc(options = {}) {
|
|
194
408
|
const query = options.encrypt
|
|
@@ -198,7 +412,7 @@ export class Aegis {
|
|
|
198
412
|
{ operations: ["deriveKey"] },
|
|
199
413
|
{ operations: ["wrapKey"] },
|
|
200
414
|
],
|
|
201
|
-
algorithm: this.encAlgorithm,
|
|
415
|
+
algorithm: options.algorithm ?? this.encAlgorithm,
|
|
202
416
|
issuer: this.issuer ?? undefined,
|
|
203
417
|
...(options.predicate ?? {}),
|
|
204
418
|
}
|