@nacre.work/api 0.0.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 +3 -0
- package/dist/__tests__/admin-surface.test.d.ts +2 -0
- package/dist/__tests__/admin-surface.test.d.ts.map +1 -0
- package/dist/__tests__/admin-surface.test.js +431 -0
- package/dist/__tests__/admin-surface.test.js.map +1 -0
- package/dist/__tests__/init.test.d.ts +2 -0
- package/dist/__tests__/init.test.d.ts.map +1 -0
- package/dist/__tests__/init.test.js +125 -0
- package/dist/__tests__/init.test.js.map +1 -0
- package/dist/__tests__/service-keys.test.d.ts +2 -0
- package/dist/__tests__/service-keys.test.d.ts.map +1 -0
- package/dist/__tests__/service-keys.test.js +204 -0
- package/dist/__tests__/service-keys.test.js.map +1 -0
- package/dist/adapters.d.ts +197 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +672 -0
- package/dist/adapters.js.map +1 -0
- package/dist/auth.d.ts +42 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +106 -0
- package/dist/auth.js.map +1 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +101 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +49 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +201 -0
- package/dist/init.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +113 -0
- package/dist/main.js.map +1 -0
- package/dist/server.d.ts +239 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +543 -0
- package/dist/server.js.map +1 -0
- package/dist/service-keys.d.ts +82 -0
- package/dist/service-keys.d.ts.map +1 -0
- package/dist/service-keys.js +158 -0
- package/dist/service-keys.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-keys.d.ts","sourceRoot":"","sources":["../src/service-keys.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAE9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE5C;;;;;;;;;;;;;;;GAeG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,UAAU,cAAc,CAAA;AAErC;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,oEAAoE;AACpE,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,MAAM,KAAG,OAAuC,CAAA;AAE3F,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAA;CACvD;AAED;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,kBAAkB;IAE1D,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBADL,IAAI,EAAE,IAAI,EACV,IAAI,CAAC,EAAE,MAAM,YAAA;IAG1B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAiD7D;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAAA;IAC3D,6DAA6D;IAC7D,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1F,gFAAgF;IAChF,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACxD;AAED,qBAAa,uBAAwB,YAAW,eAAe;IAE3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBADL,IAAI,EAAE,IAAI,EACV,IAAI,CAAC,EAAE,MAAM,YAAA;IAGhC,OAAO,KAAK,KAAK,GAEhB;IAEK,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC;IAkC3D,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,cAAc,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAgC1F,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAoB9D"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { withOrg } from '@nacre.work/core';
|
|
3
|
+
/**
|
|
4
|
+
* Service account keys.
|
|
5
|
+
*
|
|
6
|
+
* The one credential in the system meant to outlive a session. `init` issues a
|
|
7
|
+
* token that expires in an hour, which is right for getting through the
|
|
8
|
+
* quickstart and useless for an agent that runs for a week — until this
|
|
9
|
+
* existed, `NACRE_SERVICE_KEY` had nothing to put in it.
|
|
10
|
+
*
|
|
11
|
+
* The shape is not invented here: migration 0001 gave `service_accounts` a
|
|
12
|
+
* `key_hash`, a `key_prefix`, and a `revoked_at`, which is an opaque key stored
|
|
13
|
+
* hashed and looked up by a non-secret prefix. This implements that.
|
|
14
|
+
*
|
|
15
|
+
* A key is shown once, at creation, and never again. Storing anything
|
|
16
|
+
* reversible would make a database backup a set of live credentials, and the
|
|
17
|
+
* whole point of `key_hash` is that a stolen dump is not one.
|
|
18
|
+
*/
|
|
19
|
+
/** Identifies the credential type on sight, in a log or a pasted variable. */
|
|
20
|
+
export const KEY_PREFIX = 'nacre_sk_';
|
|
21
|
+
/**
|
|
22
|
+
* The lookup prefix: the marker plus the first 8 characters of the secret.
|
|
23
|
+
*
|
|
24
|
+
* Long enough that the indexed lookup returns one row in practice, short enough
|
|
25
|
+
* that it is not a meaningful head start — 8 base64url characters is 48 bits,
|
|
26
|
+
* against a 256-bit secret. It is stored in clear and shown in listings on
|
|
27
|
+
* purpose: an operator revoking a key needs to tell two apart, and the whole
|
|
28
|
+
* key is gone.
|
|
29
|
+
*/
|
|
30
|
+
export function prefixOf(key) {
|
|
31
|
+
return key.slice(0, KEY_PREFIX.length + 8);
|
|
32
|
+
}
|
|
33
|
+
export function hashOf(key) {
|
|
34
|
+
return createHash('sha256').update(key, 'utf8').digest('hex');
|
|
35
|
+
}
|
|
36
|
+
/** 32 bytes from the CSPRNG. Not a UUID — those are not secrets. */
|
|
37
|
+
export function generateKey() {
|
|
38
|
+
return `${KEY_PREFIX}${randomBytes(32).toString('base64url')}`;
|
|
39
|
+
}
|
|
40
|
+
export const looksLikeServiceKey = (value) => value.startsWith(KEY_PREFIX);
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a key against the database.
|
|
43
|
+
*
|
|
44
|
+
* Undefined for unknown, revoked, malformed and wrong alike — the caller turns
|
|
45
|
+
* all of them into the same 401 a bad JWT gets, so which one it was cannot be
|
|
46
|
+
* read off the response.
|
|
47
|
+
*/
|
|
48
|
+
export class PostgresServiceKeys {
|
|
49
|
+
pool;
|
|
50
|
+
role;
|
|
51
|
+
constructor(pool, role) {
|
|
52
|
+
this.pool = pool;
|
|
53
|
+
this.role = role;
|
|
54
|
+
}
|
|
55
|
+
async resolve(key) {
|
|
56
|
+
if (!looksLikeServiceKey(key))
|
|
57
|
+
return undefined;
|
|
58
|
+
const client = await this.pool.connect();
|
|
59
|
+
try {
|
|
60
|
+
// Across organizations: the key is what says which one, so there is no
|
|
61
|
+
// org to scope to yet. This is why the lookup runs here rather than
|
|
62
|
+
// inside withOrg, and why every column it reads is on service_accounts
|
|
63
|
+
// rather than joined from tenant data.
|
|
64
|
+
const { rows } = await client.query(`SELECT id, org_id, key_hash FROM service_accounts
|
|
65
|
+
WHERE key_prefix = $1 AND revoked_at IS NULL`, [prefixOf(key)]);
|
|
66
|
+
const expected = Buffer.from(hashOf(key), 'utf8');
|
|
67
|
+
for (const row of rows) {
|
|
68
|
+
const stored = Buffer.from(row.key_hash, 'utf8');
|
|
69
|
+
// Constant-time, and length-checked first because timingSafeEqual
|
|
70
|
+
// throws on a mismatch rather than returning false.
|
|
71
|
+
if (stored.length !== expected.length)
|
|
72
|
+
continue;
|
|
73
|
+
if (!timingSafeEqual(stored, expected))
|
|
74
|
+
continue;
|
|
75
|
+
// Best-effort. A failure to record when a key was last used must not
|
|
76
|
+
// fail the request it authenticated — the column is for an operator
|
|
77
|
+
// pruning dead keys, not for the decision.
|
|
78
|
+
void client
|
|
79
|
+
.query('UPDATE service_accounts SET last_used_at = now() WHERE id = $1', [row.id])
|
|
80
|
+
.catch(() => undefined);
|
|
81
|
+
// 'member', always. A service account holds nothing by virtue of being
|
|
82
|
+
// one; every permission it has comes from a grant, which is what
|
|
83
|
+
// docs/mcp.md means by "permissions are exactly the service account's".
|
|
84
|
+
return {
|
|
85
|
+
orgId: row.org_id,
|
|
86
|
+
principal: { type: 'service_account', id: row.id },
|
|
87
|
+
role: 'member',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
client.release();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export class PostgresServiceAccounts {
|
|
98
|
+
pool;
|
|
99
|
+
role;
|
|
100
|
+
constructor(pool, role) {
|
|
101
|
+
this.pool = pool;
|
|
102
|
+
this.role = role;
|
|
103
|
+
}
|
|
104
|
+
get scope() {
|
|
105
|
+
return this.role === undefined ? {} : { role: this.role };
|
|
106
|
+
}
|
|
107
|
+
async list(auth) {
|
|
108
|
+
return withOrg(this.pool, auth.orgId, async (client) => {
|
|
109
|
+
const { rows } = await client.query(`SELECT id, name, key_prefix, created_at, last_used_at, revoked_at
|
|
110
|
+
FROM service_accounts WHERE org_id = $1 ORDER BY created_at`, [auth.orgId]);
|
|
111
|
+
// Revoked ones are listed rather than hidden: "this key was revoked on
|
|
112
|
+
// Tuesday" is the answer to the question an operator is actually
|
|
113
|
+
// asking, and a key that vanishes looks like one that never existed.
|
|
114
|
+
return rows.map((r) => ({
|
|
115
|
+
id: r.id,
|
|
116
|
+
name: r.name,
|
|
117
|
+
keyPrefix: r.key_prefix,
|
|
118
|
+
createdAt: r.created_at.toISOString(),
|
|
119
|
+
lastUsedAt: r.last_used_at?.toISOString() ?? null,
|
|
120
|
+
revokedAt: r.revoked_at?.toISOString() ?? null,
|
|
121
|
+
}));
|
|
122
|
+
}, this.scope);
|
|
123
|
+
}
|
|
124
|
+
async create(auth, name) {
|
|
125
|
+
const key = generateKey();
|
|
126
|
+
return withOrg(this.pool, auth.orgId, async (client) => {
|
|
127
|
+
const { rows } = await client.query(`INSERT INTO service_accounts (org_id, name, key_hash, key_prefix)
|
|
128
|
+
VALUES ($1,$2,$3,$4) RETURNING id, created_at`, [auth.orgId, name, hashOf(key), prefixOf(key)]);
|
|
129
|
+
const row = rows[0];
|
|
130
|
+
if (row === undefined)
|
|
131
|
+
throw new Error('the service account insert returned no row');
|
|
132
|
+
return {
|
|
133
|
+
key,
|
|
134
|
+
account: {
|
|
135
|
+
id: row.id,
|
|
136
|
+
name,
|
|
137
|
+
keyPrefix: prefixOf(key),
|
|
138
|
+
createdAt: row.created_at.toISOString(),
|
|
139
|
+
lastUsedAt: null,
|
|
140
|
+
revokedAt: null,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}, this.scope);
|
|
144
|
+
}
|
|
145
|
+
async revoke(auth, id) {
|
|
146
|
+
if (!/^[0-9a-f-]{36}$/i.test(id))
|
|
147
|
+
return false;
|
|
148
|
+
return withOrg(this.pool, auth.orgId, async (client) => {
|
|
149
|
+
// Revoked, never deleted. The audit log refers to this id, and a row
|
|
150
|
+
// that disappears turns every past event into an unresolvable
|
|
151
|
+
// reference — which is the one thing an access log must not do.
|
|
152
|
+
const { rowCount } = await client.query(`UPDATE service_accounts SET revoked_at = now()
|
|
153
|
+
WHERE org_id = $1 AND id = $2 AND revoked_at IS NULL`, [auth.orgId, id]);
|
|
154
|
+
return (rowCount ?? 0) > 0;
|
|
155
|
+
}, this.scope);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=service-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-keys.js","sourceRoot":"","sources":["../src/service-keys.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nacre.work/api",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "REST API and authorization service",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/nacre-work/nacre.git",
|
|
8
|
+
"directory": "packages/api"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://nacre.work",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc -b",
|
|
15
|
+
"dev": "tsx watch src/index.ts"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"default": "./dist/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@nacre.work/core": "workspace:*",
|
|
33
|
+
"jose": "^6.2.7",
|
|
34
|
+
"pg": "^8.22.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.20.1",
|
|
38
|
+
"@types/pg": "^8.20.3"
|
|
39
|
+
}
|
|
40
|
+
}
|