@aep-foundation/service 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # @aep-foundation/service
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1](https://github.com/aep-foundation/aep-node/pull/1) [`3d4713e`](https://github.com/aep-foundation/aep-node/commit/3d4713e2a9cf85478a415192c7c0abc90c374073) Thanks [@nkavian](https://github.com/nkavian)! - Add the initial AEP Node SDK packages, framework adapters, and conformance helpers.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`3d4713e`](https://github.com/aep-foundation/aep-node/commit/3d4713e2a9cf85478a415192c7c0abc90c374073)]:
12
+ - @aep-foundation/core@0.1.0
13
+
14
+ ## 0.0.0
15
+
16
+ Initial development version.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AEP Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # @aep-foundation/service
2
+
3
+ Service-side workflows for AEP.
4
+
5
+ For production storage, idempotency, replay, and key-custody guidance, see the
6
+ repository [Integration Guide](../../INTEGRATION.md).
7
+
8
+ Initial responsibilities:
9
+
10
+ - construct Inspect documents
11
+ - explicitly enable supported identity methods and grant types
12
+ - validate baseline AEP client assertions
13
+ - verify Platform-hosted client assertions through hosted verification endpoints
14
+ - handle Enroll and Status with pluggable enrollment persistence
15
+ - enforce POST command idempotency through pluggable command idempotency storage
16
+ - prevent client assertion replay through pluggable replay storage
17
+ - apply pluggable enrollment lifecycle policy
18
+ - dispatch Grant and Revoke requests to explicit grant type handlers
19
+ - produce AEP Problem Details responses
20
+ - provide built-in helpers for issuing and revoking standard session
21
+ credentials through user-provided persistence
22
+
23
+ ## Initial API
24
+
25
+ ```ts
26
+ import {
27
+ apiKeyGrantType,
28
+ authenticateProtectedResource,
29
+ basicGrantType,
30
+ createAepService,
31
+ createDidWebClientAssertionVerifier,
32
+ createHostedPlatformClientAssertionVerifier,
33
+ createInMemoryCommandIdempotencyStore,
34
+ createInMemoryEnrollmentStore,
35
+ createInMemoryServiceCredentialStore,
36
+ createStaticEnrollmentPolicy,
37
+ createJwtClientAssertionVerifier,
38
+ didWebIdentityMethod,
39
+ storedOAuthBearerGrantType
40
+ } from "@aep-foundation/service";
41
+
42
+ const credentialStore = createInMemoryServiceCredentialStore();
43
+ const service = createAepService({
44
+ serviceDid: "did:web:api.example.com",
45
+ commandIdempotencyStore: createInMemoryCommandIdempotencyStore(),
46
+ clientAssertionVerifier: createJwtClientAssertionVerifier({
47
+ algorithms: ["ES256"],
48
+ key: {
49
+ format: "spki",
50
+ pem: process.env.AEP_AGENT_PUBLIC_KEY_PEM!
51
+ }
52
+ }),
53
+ enrollmentPolicy: createStaticEnrollmentPolicy({
54
+ status: "active"
55
+ }),
56
+ enrollmentStore: createInMemoryEnrollmentStore(),
57
+ identityMethods: [didWebIdentityMethod()],
58
+ grantTypes: [
59
+ storedOAuthBearerGrantType({
60
+ store: credentialStore,
61
+ issue: async (request) => ({
62
+ access_token: await mintAccessToken(request),
63
+ credential_id: crypto.randomUUID(),
64
+ expires_at: new Date(Date.now() + 3600_000).toISOString(),
65
+ scopes: request.requested_scopes ?? [],
66
+ token_type: "Bearer"
67
+ })
68
+ }),
69
+ apiKeyGrantType(),
70
+ basicGrantType()
71
+ ],
72
+ claims: {
73
+ required: ["contact.email"]
74
+ }
75
+ });
76
+
77
+ const inspect = service.inspectDocument();
78
+
79
+ const enroll = await service.enroll(
80
+ {
81
+ agent_did: "did:web:agent.example.com:agents:123",
82
+ claims: {
83
+ "contact.email": "ops@example.com"
84
+ },
85
+ idempotency_key: "9f8a4d2e-1c3b-4f5e-8b7a-000000000000"
86
+ },
87
+ {
88
+ clientAssertion: "signed.jwt",
89
+ idempotencyKey: "9f8a4d2e-1c3b-4f5e-8b7a-000000000000"
90
+ }
91
+ );
92
+
93
+ const status = await service.status({
94
+ clientAssertion: "signed.jwt"
95
+ });
96
+
97
+ const grant = await service.grant(
98
+ {
99
+ grant_type: "oauth-bearer"
100
+ },
101
+ {
102
+ clientAssertion: "signed.jwt",
103
+ idempotencyKey: "9f8a4d2e-1c3b-4f5e-8b7a-grant0000000"
104
+ }
105
+ );
106
+
107
+ const revoke = await service.revoke(
108
+ {
109
+ grant_type: "oauth-bearer"
110
+ },
111
+ {
112
+ clientAssertion: "signed.jwt",
113
+ idempotencyKey: "9f8a4d2e-1c3b-4f5e-8b7a-revoke000000"
114
+ }
115
+ );
116
+ ```
117
+
118
+ For Platform-hosted Agent identities, use hosted verification instead of local
119
+ DID resolution:
120
+
121
+ ```ts
122
+ const hostedService = createAepService({
123
+ serviceDid: "did:web:api.example.com",
124
+ clientAssertionVerifier: createHostedPlatformClientAssertionVerifier({
125
+ authorization: "Bearer service-platform-token",
126
+ endpoint: "https://platform.example.com/v1/aep/verifications"
127
+ }),
128
+ identityMethods: [didWebIdentityMethod()]
129
+ });
130
+ ```
131
+
132
+ Only explicitly enabled identity methods are advertised in `identity.methods`.
133
+ Only explicitly enabled grant types are advertised in `commands.grant_types` and
134
+ `commands.grant_types_config`. If no grant types are enabled, Grant and Revoke
135
+ are not listed in `commands.supported`.
136
+
137
+ `createAepService` accepts explicit implementation ports:
138
+
139
+ - `enrollmentStore` persists current Agent enrollment state.
140
+ - `commandIdempotencyStore` persists Enroll, Grant, and Revoke idempotency
141
+ records and coordinates atomic command execution for each idempotency key.
142
+ - `replayStore` prevents client assertion `jti` replay.
143
+ - `enrollmentPolicy` decides the lifecycle state returned by Enroll.
144
+
145
+ In-memory implementations are provided for examples and tests. Production
146
+ Services should provide durable stores for enrollment state and command
147
+ idempotency, and an atomic replay store appropriate for the Service's
148
+ deployment.
149
+
150
+ Authenticated command methods require `clientAssertion`. Services pass the
151
+ assertion to `clientAssertionVerifier`, then enforce baseline AEP claims for
152
+ audience, command, Agent identity, time window, TTL, and replay before invoking
153
+ command handlers.
154
+
155
+ `createJwtClientAssertionVerifier()` is the built-in `jose` verifier adapter for
156
+ PEM, JWK, `CryptoKey`, `KeyObject`, and raw key material supported by `jose`.
157
+ `createDidWebClientAssertionVerifier()` resolves DID-web public keys over HTTP
158
+ and verifies baseline AEP client assertion JWTs against the Service DID.
159
+ `createHostedPlatformClientAssertionVerifier()` posts the assertion to a
160
+ Platform hosted verification endpoint and lets the existing Service command
161
+ path enforce AEP audience, command, time window, TTL, and replay checks against
162
+ the returned claims.
163
+ `authenticateProtectedResource()` applies the same Status authentication path to
164
+ non-AEP resource endpoints that use AEP JWT Authorization.
165
+
166
+ `storedOAuthBearerGrantType()`, `storedApiKeyGrantType()`, and
167
+ `storedBasicGrantType()` wrap issuer callbacks with built-in credential response
168
+ validation and persistence. Their Revoke handlers mark credentials revoked in
169
+ the configured `AepServiceCredentialStore`; `createInMemoryServiceCredentialStore()`
170
+ is provided for examples and tests.