@suveren/gateway 0.5.0 → 0.6.1
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/bin/suveren-gateway.js +107 -12
- package/content/integrations/deploy-github.json +164 -0
- package/content/integrations/gmail.json +10 -4
- package/content/integrations/index.json +2 -1
- package/dist/control-plane/index.mjs +31 -7
- package/dist/mcp-server/http.mjs +49 -4
- package/dist/ui/assets/index-DecSrutK.js +105 -0
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +21 -0
- package/node_modules/@hap/core/dist/index.d.ts +21 -0
- package/node_modules/@hap/core/dist/index.js +17 -0
- package/node_modules/@hap/core/dist/index.mjs +17 -0
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +28 -0
- package/node_modules/@hap/core/src/types.ts +21 -0
- package/node_modules/fast-uri/index.js +37 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +136 -0
- package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/cjs/jsx/base.js +1 -9
- package/node_modules/hono/dist/cjs/jsx/hooks/index.js +14 -11
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/cjs/utils/cookie.js +2 -1
- package/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/jsx/base.js +1 -9
- package/node_modules/hono/dist/jsx/hooks/index.js +14 -11
- package/node_modules/hono/dist/middleware/cors/index.js +1 -1
- package/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/utils/cookie.js +2 -1
- package/node_modules/hono/package.json +2 -3
- package/node_modules/ip-address/README.md +142 -128
- package/node_modules/ip-address/dist/common.d.ts +6 -0
- package/node_modules/ip-address/dist/common.js +17 -1
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.js +3 -12
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +9 -2
- package/node_modules/ip-address/dist/ipv6.js +35 -16
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/package.json +5 -3
- package/node_modules/jose/dist/types/types.d.ts +7 -9
- package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +2 -2
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +12 -12
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +50 -51
- package/node_modules/jose/dist/webapi/jwks/local.js +10 -31
- package/node_modules/jose/dist/webapi/jwks/remote.js +17 -26
- package/node_modules/jose/dist/webapi/jws/compact/verify.js +2 -2
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +1 -9
- package/node_modules/jose/dist/webapi/jws/general/sign.js +12 -21
- package/node_modules/jose/dist/webapi/jws/general/verify.js +13 -11
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +3 -3
- package/node_modules/jose/dist/webapi/jwt/verify.js +4 -4
- package/node_modules/jose/dist/webapi/key/export.js +3 -3
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +7 -6
- package/node_modules/jose/dist/webapi/lib/asn1.js +29 -62
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +16 -34
- package/node_modules/jose/dist/webapi/lib/crypto_key.js +6 -0
- package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +0 -1
- package/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +44 -71
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +46 -41
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +14 -13
- package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +5 -10
- package/node_modules/jose/dist/webapi/lib/jws_algorithms.js +20 -18
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +12 -6
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +26 -27
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +60 -102
- package/node_modules/jose/dist/webapi/lib/key.js +61 -99
- package/node_modules/jose/dist/webapi/lib/key_algorithm.js +2 -8
- package/node_modules/jose/dist/webapi/lib/key_descriptor.js +1 -1
- package/node_modules/jose/dist/webapi/lib/key_management.js +74 -161
- package/node_modules/jose/dist/webapi/lib/options.js +11 -14
- package/node_modules/jose/dist/webapi/lib/signing.js +6 -16
- package/node_modules/jose/dist/webapi/lib/type_checks.js +13 -18
- package/node_modules/jose/dist/webapi/util/base64url.js +4 -3
- package/node_modules/jose/package.json +1 -1
- package/package.json +2 -2
- package/profiles/deploy/0.6.profile.json +168 -0
- package/profiles/deploy/0.7.profile.json +168 -0
- package/profiles/email/0.4.profile.json +7 -1
- package/profiles/index.json +3 -1
- package/dist/ui/assets/index-DedRWpBs.js +0 -105
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JOSENotSupported, JWEInvalid, JWSInvalid } from '../util/errors.js';
|
|
2
|
-
export const JWS_RECOGNIZED =
|
|
3
|
-
export const JWE_RECOGNIZED =
|
|
2
|
+
export const JWS_RECOGNIZED = { __proto__: null, b64: true };
|
|
3
|
+
export const JWE_RECOGNIZED = { __proto__: null };
|
|
4
4
|
export function validateAlgorithms(option, algorithms) {
|
|
5
5
|
if (algorithms !== undefined &&
|
|
6
6
|
(!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== 'string'))) {
|
|
@@ -22,30 +22,27 @@ export function validateCrit(Err, recognizedDefault, recognizedOption, protected
|
|
|
22
22
|
throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
|
|
23
23
|
}
|
|
24
24
|
if (!protectedHeader || protectedHeader.crit === undefined) {
|
|
25
|
-
return
|
|
25
|
+
return [];
|
|
26
26
|
}
|
|
27
27
|
if (!Array.isArray(protectedHeader.crit) ||
|
|
28
28
|
protectedHeader.crit.length === 0 ||
|
|
29
29
|
protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {
|
|
30
30
|
throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
recognized = recognizedDefault;
|
|
38
|
-
}
|
|
32
|
+
const recognized = recognizedOption === undefined
|
|
33
|
+
? recognizedDefault
|
|
34
|
+
: { __proto__: null, ...recognizedOption, ...recognizedDefault };
|
|
39
35
|
for (const parameter of protectedHeader.crit) {
|
|
40
|
-
if (!
|
|
36
|
+
if (!(parameter in recognized)) {
|
|
41
37
|
throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
|
|
42
38
|
}
|
|
43
|
-
if (joseHeader[parameter] === undefined) {
|
|
39
|
+
if (!Object.hasOwn(joseHeader, parameter) || joseHeader[parameter] === undefined) {
|
|
44
40
|
throw new Err(`Extension Header Parameter "${parameter}" is missing`);
|
|
45
41
|
}
|
|
46
|
-
if (recognized
|
|
42
|
+
if (recognized[parameter] &&
|
|
43
|
+
(!Object.hasOwn(protectedHeader, parameter) || protectedHeader[parameter] === undefined)) {
|
|
47
44
|
throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
|
-
return
|
|
47
|
+
return protectedHeader.crit;
|
|
51
48
|
}
|
|
@@ -1,34 +1,24 @@
|
|
|
1
|
-
import { checkCryptoKey } from './crypto_key.js';
|
|
2
|
-
export function checkModulusLength(alg, key) {
|
|
3
|
-
const { modulusLength } = key.algorithm;
|
|
4
|
-
if (typeof modulusLength !== 'number' || modulusLength < 2048) {
|
|
5
|
-
throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
function checkSigCryptoKey(entry, key, usage) {
|
|
9
|
-
checkCryptoKey(key, entry.subtle, usage);
|
|
10
|
-
if (entry.minModulusLength) {
|
|
11
|
-
checkModulusLength(entry.alg, key);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
import { checkCryptoKey, checkModulusLength } from './crypto_key.js';
|
|
14
2
|
async function getSigKey(entry, key, usage) {
|
|
15
3
|
if (key instanceof Uint8Array) {
|
|
16
4
|
return crypto.subtle.importKey('raw', key, entry.subtle, false, [
|
|
17
5
|
usage,
|
|
18
6
|
]);
|
|
19
7
|
}
|
|
20
|
-
|
|
8
|
+
checkCryptoKey(key, entry.subtle, usage);
|
|
9
|
+
if (entry.minRsaBits)
|
|
10
|
+
checkModulusLength(entry.alg, key);
|
|
21
11
|
return key;
|
|
22
12
|
}
|
|
23
13
|
export async function sign(entry, key, data) {
|
|
24
14
|
const cryptoKey = await getSigKey(entry, key, 'sign');
|
|
25
|
-
const signature = await crypto.subtle.sign(entry.
|
|
15
|
+
const signature = await crypto.subtle.sign(entry.signing, cryptoKey, data);
|
|
26
16
|
return new Uint8Array(signature);
|
|
27
17
|
}
|
|
28
18
|
export async function verify(entry, key, signature, data) {
|
|
29
19
|
const cryptoKey = await getSigKey(entry, key, 'verify');
|
|
30
20
|
try {
|
|
31
|
-
return await crypto.subtle.verify(entry.
|
|
21
|
+
return await crypto.subtle.verify(entry.signing, cryptoKey, signature, data);
|
|
32
22
|
}
|
|
33
23
|
catch {
|
|
34
24
|
return false;
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
const isObjectLike = (value) => typeof value === 'object' && value !== null;
|
|
2
1
|
export function isObject(input) {
|
|
3
|
-
if (
|
|
2
|
+
if (typeof input !== 'object' ||
|
|
3
|
+
input === null ||
|
|
4
|
+
Object.prototype.toString.call(input) !== '[object Object]') {
|
|
4
5
|
return false;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
+
const prototype = Object.getPrototypeOf(input);
|
|
8
|
+
if (prototype === null) {
|
|
7
9
|
return true;
|
|
8
10
|
}
|
|
9
|
-
let proto =
|
|
11
|
+
let proto = prototype;
|
|
10
12
|
while (Object.getPrototypeOf(proto) !== null) {
|
|
11
13
|
proto = Object.getPrototypeOf(proto);
|
|
12
14
|
}
|
|
13
|
-
return
|
|
15
|
+
return prototype === proto;
|
|
14
16
|
}
|
|
15
17
|
export function isDisjoint(...headers) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
let acc;
|
|
21
|
-
for (const header of sources) {
|
|
22
|
-
const parameters = Object.keys(header);
|
|
23
|
-
if (!acc || acc.size === 0) {
|
|
24
|
-
acc = new Set(parameters);
|
|
18
|
+
const parameters = new Set();
|
|
19
|
+
for (const header of headers) {
|
|
20
|
+
if (!header)
|
|
25
21
|
continue;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (acc.has(parameter)) {
|
|
22
|
+
for (const parameter of Object.keys(header)) {
|
|
23
|
+
if (parameters.has(parameter)) {
|
|
29
24
|
return false;
|
|
30
25
|
}
|
|
31
|
-
|
|
26
|
+
parameters.add(parameter);
|
|
32
27
|
}
|
|
33
28
|
}
|
|
34
29
|
return true;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { encoder, decoder } from '../lib/buffer_utils.js';
|
|
2
2
|
import { encodeBase64, decodeBase64 } from '../lib/base64.js';
|
|
3
|
+
const invalid = 'The input to be decoded is not correctly encoded.';
|
|
3
4
|
export function decode(input) {
|
|
4
5
|
if (Uint8Array.fromBase64) {
|
|
5
6
|
try {
|
|
@@ -8,7 +9,7 @@ export function decode(input) {
|
|
|
8
9
|
});
|
|
9
10
|
}
|
|
10
11
|
catch (cause) {
|
|
11
|
-
throw new TypeError(
|
|
12
|
+
throw new TypeError(invalid, { cause });
|
|
12
13
|
}
|
|
13
14
|
}
|
|
14
15
|
let encoded = input;
|
|
@@ -16,14 +17,14 @@ export function decode(input) {
|
|
|
16
17
|
encoded = decoder.decode(encoded);
|
|
17
18
|
}
|
|
18
19
|
if (encoded.includes('+') || encoded.includes('/')) {
|
|
19
|
-
throw new TypeError(
|
|
20
|
+
throw new TypeError(invalid);
|
|
20
21
|
}
|
|
21
22
|
encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');
|
|
22
23
|
try {
|
|
23
24
|
return decodeBase64(encoded);
|
|
24
25
|
}
|
|
25
26
|
catch {
|
|
26
|
-
throw new TypeError(
|
|
27
|
+
throw new TypeError(invalid);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
export function encode(input) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suveren/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node": ">=20"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@hap/core": "npm:@humanagencyp/hap-core@^0.
|
|
27
|
+
"@hap/core": "npm:@humanagencyp/hap-core@^0.8.0",
|
|
28
28
|
"@hpke/core": "^1.9.0",
|
|
29
29
|
"express": "^4.18.0",
|
|
30
30
|
"http-proxy-middleware": "^3.0.0",
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "github.com/humanagencyprotocol/hap-profiles/deploy@0.6",
|
|
3
|
+
"name": "Deploy",
|
|
4
|
+
"version": "0.6",
|
|
5
|
+
"description": "Authority to put software live. Successor to deploy-gate@0.2, HAP's first profile \u2014 renamed because the old id is bound to a structure (flat frame, disclosure_hash) that no longer exists. Deliberately host-agnostic: every deployment system has something to deploy, somewhere to put it, a rate worth capping and a notion of undo. Provider vocabulary (GitHub 'environment', Vercel 'target', Netlify 'context') lives in the connector manifest, never here.",
|
|
6
|
+
"boundsSchema": {
|
|
7
|
+
"keyOrder": [
|
|
8
|
+
"profile",
|
|
9
|
+
"deploy_daily_max",
|
|
10
|
+
"rollback_allowed"
|
|
11
|
+
],
|
|
12
|
+
"fields": {
|
|
13
|
+
"profile": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
"deploy_daily_max": {
|
|
18
|
+
"type": "number",
|
|
19
|
+
"required": true,
|
|
20
|
+
"displayName": "Daily deploy limit",
|
|
21
|
+
"description": "Maximum deployments per day. Counted by the Authority Server, so a compromised gateway cannot exceed it.",
|
|
22
|
+
"unit": "count",
|
|
23
|
+
"boundType": {
|
|
24
|
+
"kind": "cumulative_count",
|
|
25
|
+
"window": "daily"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"rollback_allowed": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"required": true,
|
|
31
|
+
"displayName": "Rollback",
|
|
32
|
+
"description": "Whether the agent may revert to a previous release. Rollback is a separate action type from deploy: undoing a release carries different risk from making one.",
|
|
33
|
+
"enum": [
|
|
34
|
+
"yes",
|
|
35
|
+
"no"
|
|
36
|
+
],
|
|
37
|
+
"boundType": {
|
|
38
|
+
"kind": "enum",
|
|
39
|
+
"values": [
|
|
40
|
+
"yes",
|
|
41
|
+
"no"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"contextSchema": {
|
|
48
|
+
"keyOrder": [
|
|
49
|
+
"allowed_repos",
|
|
50
|
+
"allowed_environments",
|
|
51
|
+
"allowed_workflows",
|
|
52
|
+
"allowed_branches"
|
|
53
|
+
],
|
|
54
|
+
"fields": {
|
|
55
|
+
"allowed_repos": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"required": true,
|
|
58
|
+
"displayName": "Allowed repositories",
|
|
59
|
+
"description": "Repositories the agent may deploy from, e.g. humanagencyprotocol/hap",
|
|
60
|
+
"constraint": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"enforceable": [
|
|
63
|
+
"subset"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"allowed_environments": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"required": true,
|
|
70
|
+
"displayName": "Allowed environments",
|
|
71
|
+
"description": "Deployment targets the agent may reach. Deliberately NOT an enum: hosts disagree \u2014 GitHub uses names you define, Vercel has production and preview, Netlify has deploy-preview and branch-deploy. The connector discovers the real list.",
|
|
72
|
+
"constraint": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enforceable": [
|
|
75
|
+
"subset"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"allowed_workflows": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"required": true,
|
|
82
|
+
"displayName": "Allowed pipelines",
|
|
83
|
+
"description": "Named pipelines the agent may run, e.g. deploy.yml. Scoping by pipeline rather than by 'deploy' means adding CI later \u2014 a migration, an infrastructure apply \u2014 is an edit to this list, not a new profile. The limit of this approach: the grant knows a pipeline is permitted, not what it does. The name has to carry that meaning to the human signing.",
|
|
84
|
+
"constraint": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"enforceable": [
|
|
87
|
+
"subset"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"allowed_branches": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"required": false,
|
|
94
|
+
"displayName": "Allowed branches",
|
|
95
|
+
"description": "Branches a deployable commit may come from. Optional: a host with no branch concept leaves it empty.",
|
|
96
|
+
"constraint": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"enforceable": [
|
|
99
|
+
"subset"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"executionContextSchema": {
|
|
106
|
+
"fields": {
|
|
107
|
+
"action_type": {
|
|
108
|
+
"source": "static",
|
|
109
|
+
"description": "deploy or rollback \u2014 declared by the manifest, never taken from an agent argument",
|
|
110
|
+
"required": true,
|
|
111
|
+
"constraint": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"enforceable": [
|
|
114
|
+
"equals"
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"allowed_repos": {
|
|
119
|
+
"source": "declared",
|
|
120
|
+
"description": "Repository this action targets, checked against the authorized set",
|
|
121
|
+
"required": true,
|
|
122
|
+
"constraint": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"enforceable": [
|
|
125
|
+
"subset"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"allowed_environments": {
|
|
130
|
+
"source": "declared",
|
|
131
|
+
"description": "Environment this action targets, checked against the authorized set. Recorded in the receipt, so the proof names where the release went.",
|
|
132
|
+
"required": true,
|
|
133
|
+
"constraint": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"enforceable": [
|
|
136
|
+
"subset"
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"allowed_workflows": {
|
|
141
|
+
"source": "declared",
|
|
142
|
+
"description": "Pipeline this action runs, checked against the authorized set. Recorded in the receipt, so the proof names what ran.",
|
|
143
|
+
"required": true,
|
|
144
|
+
"constraint": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"enforceable": [
|
|
147
|
+
"subset"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"requiredGates": [
|
|
154
|
+
"bounds",
|
|
155
|
+
"intent",
|
|
156
|
+
"commitment",
|
|
157
|
+
"decision_owner"
|
|
158
|
+
],
|
|
159
|
+
"ttl": {
|
|
160
|
+
"default": 2592000,
|
|
161
|
+
"max": 31536000
|
|
162
|
+
},
|
|
163
|
+
"retention_minimum": 7776000,
|
|
164
|
+
"content_binding": {
|
|
165
|
+
"version": "1",
|
|
166
|
+
"kind": "text"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "github.com/humanagencyprotocol/hap-profiles/deploy@0.7",
|
|
3
|
+
"name": "Deploy",
|
|
4
|
+
"version": "0.7",
|
|
5
|
+
"description": "Authority to make an already-built version live. Successor to deploy@0.6, which gated 'build and deploy this commit'; this gates the act of putting something in front of real users, because building is not consequential and going live is. The action is a RELEASE: it activates bytes that already exist, so the human can look at the artifact before approving and no rebuild can diverge from what was approved. Host-agnostic — the artifact identifier is a Vercel deployment id, a container image digest, an Azure slot — named by the connector manifest, never here.",
|
|
6
|
+
"boundsSchema": {
|
|
7
|
+
"keyOrder": [
|
|
8
|
+
"profile",
|
|
9
|
+
"release_daily_max",
|
|
10
|
+
"rollback_allowed"
|
|
11
|
+
],
|
|
12
|
+
"fields": {
|
|
13
|
+
"profile": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
"release_daily_max": {
|
|
18
|
+
"type": "number",
|
|
19
|
+
"required": true,
|
|
20
|
+
"displayName": "Times per day something may go live",
|
|
21
|
+
"description": "How often the agent may make a build live for real users. Counted by the Authority Server, so a compromised gateway cannot exceed it. Building a preview is NOT counted: previews harm nobody, and charging them against this limit would exhaust it before anything reached anyone.",
|
|
22
|
+
"unit": "count",
|
|
23
|
+
"boundType": {
|
|
24
|
+
"kind": "cumulative_count",
|
|
25
|
+
"window": "daily"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"rollback_allowed": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"required": true,
|
|
31
|
+
"displayName": "May put a previous version back live",
|
|
32
|
+
"description": "Whether the agent may promote a PREVIOUS artifact back to live. Its own action type: reverting carries different risk from releasing, and the artifact being restored was approved for a moment that has passed.",
|
|
33
|
+
"enum": [
|
|
34
|
+
"yes",
|
|
35
|
+
"no"
|
|
36
|
+
],
|
|
37
|
+
"boundType": {
|
|
38
|
+
"kind": "enum",
|
|
39
|
+
"values": [
|
|
40
|
+
"yes",
|
|
41
|
+
"no"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"contextSchema": {
|
|
48
|
+
"keyOrder": [
|
|
49
|
+
"allowed_repos",
|
|
50
|
+
"allowed_environments",
|
|
51
|
+
"allowed_workflows",
|
|
52
|
+
"allowed_branches"
|
|
53
|
+
],
|
|
54
|
+
"fields": {
|
|
55
|
+
"allowed_repos": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"required": true,
|
|
58
|
+
"displayName": "Allowed repositories",
|
|
59
|
+
"description": "Repositories the agent may deploy from, e.g. humanagencyprotocol/hap",
|
|
60
|
+
"constraint": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"enforceable": [
|
|
63
|
+
"subset"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"allowed_environments": {
|
|
68
|
+
"type": "string",
|
|
69
|
+
"required": true,
|
|
70
|
+
"displayName": "Allowed environments",
|
|
71
|
+
"description": "Deployment targets the agent may reach. Deliberately NOT an enum: hosts disagree — GitHub uses names you define, Vercel has production and preview, Netlify has deploy-preview and branch-deploy. The connector discovers the real list.",
|
|
72
|
+
"constraint": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"enforceable": [
|
|
75
|
+
"subset"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"allowed_workflows": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"required": true,
|
|
82
|
+
"displayName": "Allowed pipelines",
|
|
83
|
+
"description": "Named pipelines the agent may run, e.g. deploy.yml. Scoping by pipeline rather than by 'deploy' means adding CI later — a migration, an infrastructure apply — is an edit to this list, not a new profile. The limit of this approach: the grant knows a pipeline is permitted, not what it does. The name has to carry that meaning to the human signing.",
|
|
84
|
+
"constraint": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"enforceable": [
|
|
87
|
+
"subset"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"allowed_branches": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"required": false,
|
|
94
|
+
"displayName": "Allowed branches",
|
|
95
|
+
"description": "Branches a deployable commit may come from. Optional: a host with no branch concept leaves it empty.",
|
|
96
|
+
"constraint": {
|
|
97
|
+
"type": "string",
|
|
98
|
+
"enforceable": [
|
|
99
|
+
"subset"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"executionContextSchema": {
|
|
106
|
+
"fields": {
|
|
107
|
+
"action_type": {
|
|
108
|
+
"source": "static",
|
|
109
|
+
"description": "release or rollback — declared by the manifest, never taken from an agent argument",
|
|
110
|
+
"required": true,
|
|
111
|
+
"constraint": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"enforceable": [
|
|
114
|
+
"equals"
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"allowed_repos": {
|
|
119
|
+
"source": "declared",
|
|
120
|
+
"description": "Repository this action targets, checked against the authorized set",
|
|
121
|
+
"required": true,
|
|
122
|
+
"constraint": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"enforceable": [
|
|
125
|
+
"subset"
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"allowed_environments": {
|
|
130
|
+
"source": "declared",
|
|
131
|
+
"description": "Environment this action targets, checked against the authorized set. Recorded in the receipt, so the proof names where the release went.",
|
|
132
|
+
"required": true,
|
|
133
|
+
"constraint": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"enforceable": [
|
|
136
|
+
"subset"
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"allowed_workflows": {
|
|
141
|
+
"source": "declared",
|
|
142
|
+
"description": "Pipeline this action runs, checked against the authorized set. Recorded in the receipt, so the proof names what ran.",
|
|
143
|
+
"required": true,
|
|
144
|
+
"constraint": {
|
|
145
|
+
"type": "string",
|
|
146
|
+
"enforceable": [
|
|
147
|
+
"subset"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"requiredGates": [
|
|
154
|
+
"bounds",
|
|
155
|
+
"intent",
|
|
156
|
+
"commitment",
|
|
157
|
+
"decision_owner"
|
|
158
|
+
],
|
|
159
|
+
"ttl": {
|
|
160
|
+
"default": 2592000,
|
|
161
|
+
"max": 31536000
|
|
162
|
+
},
|
|
163
|
+
"retention_minimum": 7776000,
|
|
164
|
+
"content_binding": {
|
|
165
|
+
"version": "1",
|
|
166
|
+
"kind": "text"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "github.com/humanagencyprotocol/hap-profiles/email@0.4",
|
|
3
3
|
"name": "Email",
|
|
4
4
|
"version": "0.4",
|
|
5
|
-
"description": "Email authority
|
|
5
|
+
"description": "Email authority \u2014 governs sending, drafting, and reading email via Gmail",
|
|
6
6
|
"boundsSchema": {
|
|
7
7
|
"keyOrder": [
|
|
8
8
|
"profile",
|
|
@@ -94,6 +94,9 @@
|
|
|
94
94
|
"type": "string",
|
|
95
95
|
"enforceable": [
|
|
96
96
|
"subset"
|
|
97
|
+
],
|
|
98
|
+
"requiredFor": [
|
|
99
|
+
"send"
|
|
97
100
|
]
|
|
98
101
|
}
|
|
99
102
|
},
|
|
@@ -107,6 +110,9 @@
|
|
|
107
110
|
"type": "string",
|
|
108
111
|
"enforceable": [
|
|
109
112
|
"subset"
|
|
113
|
+
],
|
|
114
|
+
"requiredFor": [
|
|
115
|
+
"send"
|
|
110
116
|
]
|
|
111
117
|
}
|
|
112
118
|
}
|
package/profiles/index.json
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"github.com/humanagencyprotocol/hap-profiles/customers@0.6": "customers/0.6.profile.json",
|
|
10
10
|
"github.com/humanagencyprotocol/hap-profiles/calendar@0.4": "calendar/0.4.profile.json",
|
|
11
11
|
"github.com/humanagencyprotocol/hap-profiles/publish@0.4": "publish/0.4.profile.json",
|
|
12
|
-
"github.com/humanagencyprotocol/hap-profiles/records@0.4": "records/0.4.profile.json"
|
|
12
|
+
"github.com/humanagencyprotocol/hap-profiles/records@0.4": "records/0.4.profile.json",
|
|
13
|
+
"github.com/humanagencyprotocol/hap-profiles/deploy@0.6": "deploy/0.6.profile.json",
|
|
14
|
+
"github.com/humanagencyprotocol/hap-profiles/deploy@0.7": "deploy/0.7.profile.json"
|
|
13
15
|
}
|
|
14
16
|
}
|