@aporthq/aport-agent-guardrails 1.0.19 → 1.0.21
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 +16 -15
- package/bin/agent-guardrails +57 -17
- package/bin/aport-create-passport.sh +1 -1
- package/bin/aport-guardrail-api.sh +8 -35
- package/bin/aport-guardrail-bash.sh +18 -53
- package/bin/aport-resolve-paths.sh +2 -2
- package/bin/frameworks/generic.sh +59 -3
- package/bin/frameworks/next-steps.d/crewai-native.txt +21 -0
- package/bin/frameworks/next-steps.d/crewai.txt +7 -2
- package/bin/lib/error.sh +3 -3
- package/bin/lib/runtime-manifest.txt +17 -0
- package/bin/lib/runtime.sh +81 -0
- package/bin/lib/tool-mapping.sh +52 -0
- package/bin/lib/validation.sh +25 -15
- package/docs/FRAMEWORK_ROADMAP.md +1 -1
- package/docs/PROVIDER.md +90 -0
- package/docs/RELEASE.md +3 -3
- package/docs/development/ERROR_CODES.md +3 -3
- package/docs/frameworks/crewai.md +102 -68
- package/docs/frameworks/deerflow.md +1 -1
- package/docs/frameworks/openclaw.md +51 -22
- package/extensions/openclaw-aport/CHANGELOG.md +5 -1
- package/extensions/openclaw-aport/openclaw.plugin.json +1 -1
- package/extensions/openclaw-aport/package-lock.json +2 -2
- package/extensions/openclaw-aport/package.json +1 -1
- package/external/aport-spec/LICENSE +1 -1
- package/external/aport-spec/README.md +1 -0
- package/external/aport-spec/conformance/src/ed25519.ts +1 -1
- package/external/aport-spec/oap/CHANGELOG.md +1 -1
- package/external/aport-spec/oap/conformance.md +2 -2
- package/external/aport-spec/oap/oap-spec.md +2 -2
- package/external/aport-spec/oap/security.md +4 -4
- package/external/aport-spec/oap/vc/examples/oap-decision-vc.json +1 -1
- package/external/aport-spec/oap/vc/examples/oap-passport-vc.json +1 -1
- package/external/aport-spec/oap/vc/tools/examples/vc-to-decision.js +1 -1
- package/external/aport-spec/oap/vc/tools/examples/vc-to-passport.js +1 -1
- package/external/aport-spec/oap/vc/tools/src/index.ts +2 -2
- package/external/aport-spec/oap/vc/tools/test-simple.js +2 -2
- package/external/aport-spec/oap/vc/vc-mapping.md +4 -4
- package/external/aport-spec/oap/well-known-schema.json +85 -0
- package/external/aport-spec/well-known.md +203 -0
- package/package.json +3 -2
|
@@ -1,40 +1,69 @@
|
|
|
1
1
|
# APort Guardrails — OpenClaw
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
OpenClaw is an open-source AI agent platform with a plugin system and built-in `before_tool_call` hooks. APort integrates via two paths:
|
|
4
4
|
|
|
5
|
-
- **
|
|
6
|
-
- **
|
|
5
|
+
- **Native `guardrails:` config** (recommended) — OpenClaw's built-in `GuardrailProvider` interface loads `OAPGuardrailProvider` directly. No plugin needed.
|
|
6
|
+
- **Plugin** (legacy, still works) — The `openclaw-aport` plugin registers a `before_tool_call` hook.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Both paths use the same evaluator, passport, and policies.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|----------|------------|----------------|
|
|
12
|
-
| **Guardrails (CLI/setup)** | Full installer: runs the **passport wizard**, writes config, installs the **OpenClaw plugin** so every tool call goes through the evaluator. | Getting started: one command sets up config, passport, and the plugin. |
|
|
13
|
-
| **Core (runtime)** | The **evaluator** (bash script or API) that the plugin calls before each tool run. Same policy + passport as other frameworks. For **programmatic** use (e.g. custom scripts), you can use the **Python** (`aport_guardrails`) or **Node** (`@aporthq/aport-agent-guardrails-core`) library. | Guardrails = the plugin uses the evaluator automatically. Use the library only if you're building custom tooling. |
|
|
10
|
+
## Quick start
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
```bash
|
|
13
|
+
npm install @aporthq/aport-agent-guardrails-core
|
|
14
|
+
npx @aporthq/aport-agent-guardrails openclaw
|
|
15
|
+
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
The first command installs the provider. The second runs the passport wizard.
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## Config (native — recommended)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
Add to your OpenClaw `config.yaml`:
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
guardrails:
|
|
25
|
+
enabled: true
|
|
26
|
+
provider:
|
|
27
|
+
use: "@aporthq/aport-agent-guardrails-core"
|
|
28
|
+
config:
|
|
29
|
+
framework: "openclaw"
|
|
26
30
|
```
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
This loads `OAPGuardrailProvider` as a core guardrail service — runs before plugin hooks, cannot be bypassed by disabling a plugin.
|
|
33
|
+
|
|
34
|
+
## Config (plugin — legacy)
|
|
35
|
+
|
|
36
|
+
The setup wizard (`npx @aporthq/aport-agent-guardrails openclaw`) installs the `openclaw-aport` plugin automatically. This registers a `before_tool_call` hook that calls the same evaluator.
|
|
37
|
+
|
|
38
|
+
Both approaches are supported. The native config is recommended for new deployments.
|
|
39
|
+
|
|
40
|
+
## How it works
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Agent decides to use a tool
|
|
44
|
+
│
|
|
45
|
+
▼
|
|
46
|
+
GuardrailService (native) or Plugin hook (legacy)
|
|
47
|
+
│ │
|
|
48
|
+
▼ ▼
|
|
49
|
+
OAPGuardrailProvider ──────────────── same Evaluator
|
|
50
|
+
│
|
|
51
|
+
┌─────┴─────┐
|
|
52
|
+
│ │
|
|
53
|
+
ALLOW DENY
|
|
54
|
+
│ │
|
|
55
|
+
Tool runs Agent sees denial reason
|
|
56
|
+
```
|
|
29
57
|
|
|
30
|
-
- **
|
|
31
|
-
- **Passport:**
|
|
32
|
-
- **
|
|
58
|
+
- **Provider class:** `OAPGuardrailProvider` from `@aporthq/aport-agent-guardrails-core`
|
|
59
|
+
- **Passport:** `~/.openclaw/aport/passport.json` (created by wizard)
|
|
60
|
+
- **Config:** `~/.openclaw/aport/config.yaml`
|
|
61
|
+
- **Audit log:** `~/.openclaw/aport/audit.log`
|
|
33
62
|
|
|
34
63
|
## Suspend (kill switch)
|
|
35
64
|
|
|
36
|
-
|
|
65
|
+
Local: set passport `status` to `suspended`. Remote: use API mode and suspend at [aport.io](https://aport.io).
|
|
37
66
|
|
|
38
67
|
## Status
|
|
39
68
|
|
|
40
|
-
Shipped; in production.
|
|
69
|
+
Shipped; in production. Native `guardrails:` config available when [OpenClaw #46441](https://github.com/openclaw/openclaw/issues/46441) merges.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Changelog - APort OpenClaw Plugin
|
|
2
2
|
|
|
3
|
+
## 1.0.21
|
|
4
|
+
|
|
3
5
|
All notable changes to the APort OpenClaw plugin will be documented in this file.
|
|
4
6
|
|
|
5
|
-
## [1.
|
|
7
|
+
## [1.0.21] - 2026-02-19
|
|
6
8
|
|
|
7
9
|
### Changed - OpenClaw 2026.2 Compatibility
|
|
8
10
|
|
|
@@ -24,6 +26,7 @@ All notable changes to the APort OpenClaw plugin will be documented in this file
|
|
|
24
26
|
### Technical Details
|
|
25
27
|
|
|
26
28
|
**Old Architecture (< 2026.2):**
|
|
29
|
+
|
|
27
30
|
```javascript
|
|
28
31
|
export default function (api) {
|
|
29
32
|
api.on("before_tool_call", async (event, ctx) => { ... });
|
|
@@ -31,6 +34,7 @@ export default function (api) {
|
|
|
31
34
|
```
|
|
32
35
|
|
|
33
36
|
**New Architecture (>= 2026.2):**
|
|
37
|
+
|
|
34
38
|
```typescript
|
|
35
39
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
36
40
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-aport",
|
|
3
3
|
"name": "APort Guardrails",
|
|
4
4
|
"description": "Deterministic pre-action authorization via APort policy enforcement. Registers before_tool_call to block disallowed tools.",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.21",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aporthq/openclaw-aport",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@aporthq/openclaw-aport",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.21",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@types/node": "^18.0.0",
|
|
@@ -39,6 +39,7 @@ OAP provides the **runtime trust layer** that makes agentic commerce safe and sc
|
|
|
39
39
|
- **[Passport Schema](./oap/passport-schema.json)** — Agent identity and capabilities
|
|
40
40
|
- **[Decision Schema](./oap/decision-schema.json)** — Authorization decisions
|
|
41
41
|
- **[Security Model](./oap/security.md)** — Cryptographic verification
|
|
42
|
+
- **[Service Discovery](./well-known.md)** — `.well-known/oap/` endpoint specification
|
|
42
43
|
|
|
43
44
|
### 🎯 Policy Framework
|
|
44
45
|
- **[Capability Registry](./oap/capability-registry.md)** — Standardized capabilities and limits
|
|
@@ -144,7 +144,7 @@ export class Ed25519 {
|
|
|
144
144
|
async resolveKey(kid: string): Promise<string | null> {
|
|
145
145
|
try {
|
|
146
146
|
// For conformance testing, we'll use test keys
|
|
147
|
-
// In production, this would resolve keys from /.well-known/oap/
|
|
147
|
+
// In production, this would resolve keys from /.well-known/oap/jwks.json
|
|
148
148
|
|
|
149
149
|
if (kid.startsWith("oap:registry:test-key")) {
|
|
150
150
|
const { publicKey } = await this.generateTestKeyPair();
|
|
@@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
26
26
|
|
|
27
27
|
- Ed25519 signature scheme for decision signing
|
|
28
28
|
- JCS (RFC 8785) canonicalization for deterministic hashing
|
|
29
|
-
- Key resolution via `/.well-known/oap/
|
|
29
|
+
- Key resolution via `/.well-known/oap/jwks.json`
|
|
30
30
|
- Suspend semantics with 30-second global invalidation
|
|
31
31
|
- Passport digest verification for decision integrity
|
|
32
32
|
|
|
@@ -21,7 +21,7 @@ Full conformance requires all basic conformance requirements plus:
|
|
|
21
21
|
|
|
22
22
|
1. **Policy evaluation**: Implement policy pack evaluation logic
|
|
23
23
|
2. **JCS canonicalization**: Use RFC 8785 for canonicalization
|
|
24
|
-
3. **Key resolution**: Resolve keys via `/.well-known/oap/
|
|
24
|
+
3. **Key resolution**: Resolve keys via `/.well-known/oap/jwks.json`
|
|
25
25
|
4. **Suspend semantics**: Implement 30-second global invalidation
|
|
26
26
|
5. **Performance**: Meet performance requirements (see below)
|
|
27
27
|
|
|
@@ -73,7 +73,7 @@ Implementations MUST:
|
|
|
73
73
|
Implementations MUST:
|
|
74
74
|
|
|
75
75
|
1. **Parse signature**: Extract Ed25519 signature from decision
|
|
76
|
-
2. **Resolve key**: Fetch public key using `kid` and `/.well-known/oap/
|
|
76
|
+
2. **Resolve key**: Fetch public key using `kid` and `/.well-known/oap/jwks.json`
|
|
77
77
|
3. **Canonicalize**: Apply JCS canonicalization to decision payload
|
|
78
78
|
4. **Verify signature**: Use Ed25519 to verify signature
|
|
79
79
|
5. **Check expiration**: Ensure decision hasn't expired
|
|
@@ -207,7 +207,7 @@ All objects MUST be canonicalized using [RFC 8785 JCS](https://tools.ietf.org/ht
|
|
|
207
207
|
|
|
208
208
|
- All decisions MUST be signed with Ed25519
|
|
209
209
|
- Signatures are computed over JCS-canonicalized decision payloads
|
|
210
|
-
- Key identifiers (kid) MUST be resolvable via `/.well-known/oap/
|
|
210
|
+
- Key identifiers (kid) MUST be resolvable via `/.well-known/oap/jwks.json`
|
|
211
211
|
|
|
212
212
|
### Key Resolution
|
|
213
213
|
|
|
@@ -391,7 +391,7 @@ Custom validators MUST be:
|
|
|
391
391
|
### Key Management
|
|
392
392
|
|
|
393
393
|
- Ed25519 keys for all signatures
|
|
394
|
-
- Registry keys published at `https://api.yourdomain/.well-known/oap/
|
|
394
|
+
- Registry keys published at `https://api.yourdomain/.well-known/oap/jwks.json`
|
|
395
395
|
- Owner keys MAY be published at their domain
|
|
396
396
|
|
|
397
397
|
### Receipt Verification
|
|
@@ -42,7 +42,7 @@ All objects are canonicalized using RFC 8785 JCS before signing:
|
|
|
42
42
|
Registry keys are used by the OAP registry to sign decisions:
|
|
43
43
|
|
|
44
44
|
- **Format**: `oap:registry:<keyid>`
|
|
45
|
-
- **Location**: `https://api.yourdomain/.well-known/oap/
|
|
45
|
+
- **Location**: `https://api.yourdomain/.well-known/oap/jwks.json`
|
|
46
46
|
- **Rotation**: Regular rotation schedule (e.g., quarterly)
|
|
47
47
|
- **Backup**: Multiple keys for high availability
|
|
48
48
|
|
|
@@ -51,7 +51,7 @@ Registry keys are used by the OAP registry to sign decisions:
|
|
|
51
51
|
Owner keys are used by passport owners for additional verification:
|
|
52
52
|
|
|
53
53
|
- **Format**: `oap:owner:<domain>:<keyid>`
|
|
54
|
-
- **Location**: `https://<domain>/.well-known/oap/
|
|
54
|
+
- **Location**: `https://<domain>/.well-known/oap/jwks.json`
|
|
55
55
|
- **Optional**: Not required for basic OAP compliance
|
|
56
56
|
- **Use Case**: Additional verification layers
|
|
57
57
|
|
|
@@ -68,8 +68,8 @@ Keys are resolved using the following process:
|
|
|
68
68
|
#### Key Resolution URLs
|
|
69
69
|
|
|
70
70
|
```
|
|
71
|
-
Registry keys: https://api.yourdomain/.well-known/oap/
|
|
72
|
-
Owner keys: https://<domain>/.well-known/oap/
|
|
71
|
+
Registry keys: https://api.yourdomain/.well-known/oap/jwks.json
|
|
72
|
+
Owner keys: https://<domain>/.well-known/oap/jwks.json
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
#### Key Format
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"proof": {
|
|
31
31
|
"type": "Ed25519Signature2020",
|
|
32
32
|
"created": "2024-01-15T10:30:00Z",
|
|
33
|
-
"verificationMethod": "https://aport.io/.well-known/oap/
|
|
33
|
+
"verificationMethod": "https://aport.io/.well-known/oap/jwks.json#ap_registry_ed25519_2024",
|
|
34
34
|
"proofPurpose": "assertionMethod",
|
|
35
35
|
"jws": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWNpc2lvbl9pZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMiIsInBvbGljeV9pZCI6InBheW1lbnRzLnJlZnVuZC52MSIsInBhc3Nwb3J0X2lkIjoiNTUwZTg0MDAtZTI5Yi00MWQ0LWE3MTYtNDQ2NjU1NDQwMDAwIiwib3duZXJfaWQiOiJvcmdfMTIzNDU2NzgiLCJhc3N1cmFuY2VfbGV2ZWwiOiJMMiIsImFsbG93Ijp0cnVlLCJyZWFzb25zIjpbeyJjb2RlIjoib2FwLmFsbG93ZWQiLCJtZXNzYWdlIjoiVHJhbnNhY3Rpb24gd2l0aGluIGxpbWl0cyBhbmQgcG9saWN5IHJlcXVpcmVtZW50cyJ9XSwiaXNzdWVkX2F0IjoiMjAyNC0wMS0xNVQxMDozMDowMFoiLCJleHBpcmVzX2F0IjoiMjAyNC0wMS0xNVQxMTozMDowMFoiLCJwYXNzcG9ydF9kaWdlc3QiOiJzaGEyNTY6YWJjZDEyMzRlZmdoNTY3OGlqa2w5MDEybW5vcDM0NTZxcnN0Nzg5MHV2d3gxMjM0eXphYjU2NzhjZGVmIn0sImlzc3VlciI6Imh0dHBzOi8vYXBpLmFwb3J0LmRldiIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDEtMTVUMTA6MzA6MDBaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDI0LTAxLTE1VDExOjMwOjAwWiJ9.signature"
|
|
36
36
|
}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"proof": {
|
|
62
62
|
"type": "Ed25519Signature2020",
|
|
63
63
|
"created": "2024-01-01T00:00:00Z",
|
|
64
|
-
"verificationMethod": "https://aport.io/.well-known/oap/
|
|
64
|
+
"verificationMethod": "https://aport.io/.well-known/oap/jwks.json#ap_registry_ed25519_2024",
|
|
65
65
|
"proofPurpose": "assertionMethod",
|
|
66
66
|
"jws": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVkZW50aWFsU3ViamVjdCI6eyJwYXNzcG9ydF9pZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCIsImtpbmQiOiJ0ZW1wbGF0ZSIsInNwZWNfdmVyc2lvbiI6Im9hcC8xLjAiLCJvd25lcl9pZCI6Im9yZ18xMjM0NTY3OCIsIm93bmVyX3R5cGUiOiJvcmciLCJhc3N1cmFuY2VfbGV2ZWwiOiJMMiIsInN0YXR1cyI6ImFjdGl2ZSIsImNhcGFiaWxpdGllcyI6WyJwYXltZW50cy5yZWZ1bmQiLCJkYXRhLmV4cG9ydCIsInJlcG8ucmVsZWFzZS5wdWJsaXNoIl0sImxpbWl0cyI6eyJwYXltZW50cy5yZWZ1bmQiOnsiY3VycmVuY3lfbGltaXRzIjp7IlVTRCI6eyJtYXhfcGVyX3R4Ijo1MDAwLCJkYWlseV9jYXAiOjUwMDAwfSwiRVVSIjp7Im1heF9wZXJfdHgiOjQ1MDAsImRhaWx5X2NhcCI6NDUwMDB9fSwicmVhc29uX2NvZGVzIjpbImN1c3RvbWVyX3JlcXVlc3QiLCJkZWZlY3RpdmVfcHJvZHVjdCIsImZyYXVkIl0sImlkZW1wb3RlbmN5X3JlcXVpcmVkIjp0cnVlfSwiZGF0YS5leHBvcnQiOnsibWF4X3Jvd3MiOjEwMDAwMCwiYWxsb3dfcGlpIjpmYWxzZSwiYWxsb3dlZF9jb2xsZWN0aW9ucyI6WyJ1c2VycyIsIm9yZGVycyIsInByb2R1Y3RzIl19LCJyZXBvLnJlbGVhc2UucHVibGlzaCI6eyJhbGxvd2VkX2JyYW5jaGVzIjpbIm1haW4iLCJkZXZlbG9wIl0sIm1heF9yZWxlYXNlc19wZXJfZGF5IjoxMCwicmVxdWlyZV9zaWduZWRfYXJ0aWZhY3RzIjp0cnVlfX0sInJlZ2lvbnMiOlsiVVMiLCJDQSIsIkVVIl0sIm1ldGFkYXRhIjp7Im5hbWUiOiJDdXN0b21lciBTdXBwb3J0IEFJIiwiZGVzY3JpcHRpb24iOiJBSSBhZ2VudCBmb3IgY3VzdG9tZXIgc3VwcG9ydCBvcGVyYXRpb25zIiwidmVyc2lvbiI6IjEuMC4wIiwiY29udGFjdCI6InN1cHBvcnRAZXhhbXBsZS5jb20iLCJob21lcGFnZSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWkvc3VwcG9ydCJ9LCJjcmVhdGVkX2F0IjoiMjAyNC0wMS0wMVQwMDowMDowMFoiLCJ1cGRhdGVkX2F0IjoiMjAyNC0wMS0xNVQxMDozMDowMFoiLCJ2ZXJzaW9uIjoxfX0sImlzc3VlciI6Imh0dHBzOi8vYXBpLmFwb3J0LmRldiIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDEtMDFUMDA6MDA6MDBaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDI1LTAxLTAxVDAwOjAwOjAwWiJ9.signature"
|
|
67
67
|
}
|
|
@@ -42,7 +42,7 @@ const vc = {
|
|
|
42
42
|
type: "Ed25519Signature2020",
|
|
43
43
|
created: "2024-01-15T10:30:00Z",
|
|
44
44
|
verificationMethod:
|
|
45
|
-
"https://aport.io/.well-known/oap/
|
|
45
|
+
"https://aport.io/.well-known/oap/jwks.json#ap_registry_ed25519_2024",
|
|
46
46
|
proofPurpose: "assertionMethod",
|
|
47
47
|
jws: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWNpc2lvbl9pZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMiIsInBvbGljeV9pZCI6InBheW1lbnRzLnJlZnVuZC52MSIsImFnZW50X2lkIjoiNTUwZTg0MDAtZTI5Yi00MWQ0LWE3MTYtNDQ2NjU1NDQwMDAwIiwib3duZXJfaWQiOiJvcmdfMTIzNDU2NzgiLCJhc3N1cmFuY2VfbGV2ZWwiOiJMMiIsImFsbG93Ijp0cnVlLCJyZWFzb25zIjpbeyJjb2RlIjoib2FwLmFsbG93ZWQiLCJtZXNzYWdlIjoiVHJhbnNhY3Rpb24gd2l0aGluIGxpbWl0cyJ9XSwicGFzc3BvcnRfZGlnZXN0Ijoic2hhMjU2OmFiY2QxMjM0ZWZnaDU2NzhpamtsOTAxMm1ub3AzNDU2cXJzdDc4OTB1dnd4MTIzNHl6YWI1Njc4Y2RlZiIsInNpZ25hdHVyZSI6ImV5SmhiR2NpT2lKU1V6STFOaUlzSW5SNWNDSTZJa3BYVkNKOS5leUpoYkdjaU9pSlNVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkucGxhY2Vob2xkZXIifQ.signature",
|
|
48
48
|
},
|
|
@@ -59,7 +59,7 @@ const vc = {
|
|
|
59
59
|
type: "Ed25519Signature2020",
|
|
60
60
|
created: "2024-01-01T00:00:00Z",
|
|
61
61
|
verificationMethod:
|
|
62
|
-
"https://aport.io/.well-known/oap/
|
|
62
|
+
"https://aport.io/.well-known/oap/jwks.json#ap_registry_ed25519_2024",
|
|
63
63
|
proofPurpose: "assertionMethod",
|
|
64
64
|
jws: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJjcmVkZW50aWFsU3ViamVjdCI6eyJhZ2VudF9pZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMCIsImtpbmQiOiJ0ZW1wbGF0ZSIsInNwZWNfdmVyc2lvbiI6Im9hcC8xLjAiLCJvd25lcl9pZCI6Im9yZ18xMjM0NTY3OCIsIm93bmVyX3R5cGUiOiJvcmciLCJhc3N1cmFuY2VfbGV2ZWwiOiJMMiIsInN0YXR1cyI6ImFjdGl2ZSIsImNhcGFiaWxpdGllcyI6W3siaWQiOiJwYXltZW50cy5yZWZ1bmQiLCJwYXJhbXMiOnsiY3VycmVuY3lfbGltaXRzIjp7IlVTRCI6eyJtYXhfcGVyX3R4Ijo1MDAwfX19fSx7ImlkIjoiZGF0YS5leHBvcnQiLCJwYXJhbXMiOnsibWF4X3Jvd3MiOjEwMDAwMH19XSwibGltaXRzIjp7InBheW1lbnRzLnJlZnVuZCI6eyJjdXJyZW5jeV9saW1pdHMiOnsiVVNEIjp7Im1heF9wZXJfdHgiOjUwMDAsImRhaWx5X2NhcCI6NTAwMDB9fSwicmVhc29uX2NvZGVzIjpbImN1c3RvbWVyX3JlcXVlc3QiLCJkZWZlY3RpdmVfcHJvZHVjdCJdLCJpZGVtcG90ZW5jeV9yZXF1aXJlZCI6dHJ1ZX19LCJyZWdpb25zIjpbIlVTIiwiQ0EiXSwibWV0YWRhdGEiOnsibmFtZSI6IkN1c3RvbWVyIFN1cHBvcnQgQUkiLCJkZXNjcmlwdGlvbiI6IkFJIGFnZW50IGZvciBjdXN0b21lciBzdXBwb3J0IG9wZXJhdGlvbnMifSwiY3JlYXRlZF9hdCI6IjIwMjQtMDEtMDFUMDA6MDA6MDBaIiwidXBkYXRlZF9hdCI6IjIwMjQtMDEtMTVUMTA6MzA6MDBaIiwidmVyc2lvbiI6IjEuMC4wIn0sImlzc3VlciI6Imh0dHBzOi8vYXBpLmFwb3J0LmRldiIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDEtMDFUMDA6MDA6MDBaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDI1LTAxLTAxVDAwOjAwOjAwWiJ9.signature",
|
|
65
65
|
},
|
|
@@ -285,8 +285,8 @@ export async function exportDecisionToVC(
|
|
|
285
285
|
type: "Ed25519Signature2020",
|
|
286
286
|
created: decision.created_at,
|
|
287
287
|
// For decisions, use registry's well-known endpoint
|
|
288
|
-
// This should resolve to: https://aport.io/.well-known/oap/
|
|
289
|
-
verificationMethod: `${registryKey.issuer}/.well-known/oap/
|
|
288
|
+
// This should resolve to: https://aport.io/.well-known/oap/jwks.json
|
|
289
|
+
verificationMethod: `${registryKey.issuer}/.well-known/oap/jwks.json#${registryKey.kid}`,
|
|
290
290
|
proofPurpose: "assertionMethod",
|
|
291
291
|
jws: jws,
|
|
292
292
|
},
|
|
@@ -21,7 +21,7 @@ function exportPassportToVC(passport, registryKey) {
|
|
|
21
21
|
proof: {
|
|
22
22
|
type: "Ed25519Signature2020",
|
|
23
23
|
created: passport.created_at,
|
|
24
|
-
verificationMethod: `${registryKey.issuer}/.well-known/oap/
|
|
24
|
+
verificationMethod: `${registryKey.issuer}/.well-known/oap/jwks.json#${registryKey.kid}`,
|
|
25
25
|
proofPurpose: "assertionMethod",
|
|
26
26
|
jws: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
27
27
|
},
|
|
@@ -44,7 +44,7 @@ function exportDecisionToVC(decision, registryKey) {
|
|
|
44
44
|
proof: {
|
|
45
45
|
type: "Ed25519Signature2020",
|
|
46
46
|
created: decision.created_at,
|
|
47
|
-
verificationMethod: `${registryKey.issuer}/.well-known/oap/
|
|
47
|
+
verificationMethod: `${registryKey.issuer}/.well-known/oap/jwks.json#${registryKey.kid}`,
|
|
48
48
|
proofPurpose: "assertionMethod",
|
|
49
49
|
jws: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
50
50
|
},
|
|
@@ -60,7 +60,7 @@ An OAP passport can be exported as a Verifiable Credential with the following st
|
|
|
60
60
|
"proof": {
|
|
61
61
|
"type": "Ed25519Signature2020",
|
|
62
62
|
"created": "2024-01-01T00:00:00Z",
|
|
63
|
-
"verificationMethod": "https://aport.io/.well-known/oap/
|
|
63
|
+
"verificationMethod": "https://aport.io/.well-known/oap/jwks.json#key-2025-01",
|
|
64
64
|
"proofPurpose": "assertionMethod",
|
|
65
65
|
"jws": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
66
66
|
}
|
|
@@ -112,7 +112,7 @@ An OAP decision can be exported as a Verifiable Credential receipt:
|
|
|
112
112
|
"proof": {
|
|
113
113
|
"type": "Ed25519Signature2020",
|
|
114
114
|
"created": "2024-01-15T10:30:00Z",
|
|
115
|
-
"verificationMethod": "https://aport.io/.well-known/oap/
|
|
115
|
+
"verificationMethod": "https://aport.io/.well-known/oap/jwks.json#key-2025-01",
|
|
116
116
|
"proofPurpose": "assertionMethod",
|
|
117
117
|
"jws": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
118
118
|
}
|
|
@@ -280,7 +280,7 @@ function exportPassportToVC(passport, registryKey) {
|
|
|
280
280
|
"proof": {
|
|
281
281
|
"type": "Ed25519Signature2020",
|
|
282
282
|
"created": passport.created_at,
|
|
283
|
-
"verificationMethod": `${registryKey.issuer}/.well-known/oap/
|
|
283
|
+
"verificationMethod": `${registryKey.issuer}/.well-known/oap/jwks.json#${registryKey.kid}`,
|
|
284
284
|
"proofPurpose": "assertionMethod",
|
|
285
285
|
"jws": signCredential(passport, registryKey)
|
|
286
286
|
}
|
|
@@ -329,7 +329,7 @@ function exportDecisionToVC(decision, registryKey) {
|
|
|
329
329
|
"proof": {
|
|
330
330
|
"type": "Ed25519Signature2020",
|
|
331
331
|
"created": decision.created_at,
|
|
332
|
-
"verificationMethod": `${registryKey.issuer}/.well-known/oap/
|
|
332
|
+
"verificationMethod": `${registryKey.issuer}/.well-known/oap/jwks.json#${registryKey.kid}`,
|
|
333
333
|
"proofPurpose": "assertionMethod",
|
|
334
334
|
"jws": signCredential(decision, registryKey)
|
|
335
335
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://aport.io/oap/well-known-schema.json",
|
|
4
|
+
"title": "OAP Service Discovery Response",
|
|
5
|
+
"description": "JSON Schema for the /.well-known/oap/ discovery endpoint response. Conforms to RFC 8615 and mirrors OAuth 2.0 Authorization Server Metadata (RFC 8414).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"oap_version",
|
|
9
|
+
"authorization_endpoint",
|
|
10
|
+
"passport_endpoint",
|
|
11
|
+
"policy_endpoint"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"oap_version": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "OAP specification version implemented.",
|
|
17
|
+
"pattern": "^\\d+\\.\\d+$",
|
|
18
|
+
"examples": ["1.0"]
|
|
19
|
+
},
|
|
20
|
+
"authorization_endpoint": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"format": "uri-template",
|
|
23
|
+
"description": "Passport verification endpoint. Accepts GET with an {agent_id} path parameter.",
|
|
24
|
+
"examples": ["https://api.example.com/api/verify/{agent_id}"]
|
|
25
|
+
},
|
|
26
|
+
"passport_endpoint": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"format": "uri-template",
|
|
29
|
+
"description": "Endpoint for retrieving and managing OAP passports.",
|
|
30
|
+
"examples": ["https://api.example.com/api/passports/{agent_id}"]
|
|
31
|
+
},
|
|
32
|
+
"policy_endpoint": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"format": "uri-template",
|
|
35
|
+
"description": "Endpoint for retrieving policy packs by name. Accepts {policy_name} in dot-separated format.",
|
|
36
|
+
"examples": ["https://api.example.com/api/policies/{policy_name}"]
|
|
37
|
+
},
|
|
38
|
+
"decision_endpoint": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"format": "uri-template",
|
|
41
|
+
"description": "Endpoint for retrieving individual authorization decisions by {decision_id}.",
|
|
42
|
+
"examples": ["https://api.example.com/api/verify/decisions/get/{decision_id}"]
|
|
43
|
+
},
|
|
44
|
+
"jwks_uri": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"format": "uri",
|
|
47
|
+
"description": "JWKS endpoint (RFC 7517) for verifying OAP decision and VC signatures.",
|
|
48
|
+
"examples": ["https://api.example.com/.well-known/oap/jwks.json"]
|
|
49
|
+
},
|
|
50
|
+
"supported_capabilities": {
|
|
51
|
+
"type": "array",
|
|
52
|
+
"items": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"pattern": "^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
|
|
55
|
+
},
|
|
56
|
+
"description": "Dot-separated capability identifiers this server can enforce. Format: category.subcategory.action.",
|
|
57
|
+
"examples": [
|
|
58
|
+
["finance.payment.refund", "finance.payment.charge", "data.export.create", "messaging.message.send"]
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"supported_assurance_levels": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"enum": ["L0", "L1", "L2", "L3", "L4KYC", "L4FIN"]
|
|
66
|
+
},
|
|
67
|
+
"description": "Assurance levels the issuer can credential and enforce."
|
|
68
|
+
},
|
|
69
|
+
"agent_manifest_endpoint": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"format": "uri",
|
|
72
|
+
"description": "Public agent registry scoped to this domain."
|
|
73
|
+
},
|
|
74
|
+
"spec_uri": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"format": "uri",
|
|
77
|
+
"description": "Link to the OAP specification document."
|
|
78
|
+
},
|
|
79
|
+
"contact": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Security or operations contact (email or URL)."
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
}
|