@atlasauth/pca-connectors 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +73 -2
- package/dist/authorize.d.ts +72 -0
- package/dist/authorize.js +100 -0
- package/dist/authorize.js.map +1 -0
- package/dist/exchange.d.ts +100 -0
- package/dist/exchange.js +220 -0
- package/dist/exchange.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +93 -0
- package/dist/manifest.js +256 -0
- package/dist/manifest.js.map +1 -0
- package/dist/providers/index.d.ts +41 -0
- package/dist/providers/index.js +260 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/registry.d.ts +32 -0
- package/dist/registry.js +70 -0
- package/dist/registry.js.map +1 -0
- package/package.json +55 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Atlas Authorization
|
|
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
CHANGED
|
@@ -1,3 +1,74 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @atlasauth/pca-connectors
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The connector catalog for Proof-Carrying Authority (PCA): a declarative registry of outbound SaaS providers as data manifests, plus the authorize-URL, code-exchange and refresh helpers that feed the `@atlasauth/pca-connect` token vault. Wiring a new outbound tool is a manifest edit, and every connection minted here is bound to a PCA capability: the stored token is only released when a verified PCActn proves authority over the provider and scopes.
|
|
4
|
+
|
|
5
|
+
Built-in manifests: Airtable, Atlassian, Dropbox, GitHub, Google, HubSpot, Linear, Microsoft, Notion, Salesforce, Shopify, Slack, Snowflake, Stripe, Zoom. Each manifest declares the authorize and token URLs, default scopes, PKCE, how the access token is placed on a request, and refresh behaviour.
|
|
6
|
+
|
|
7
|
+
This package is the code layer only. It never makes the outbound API call and ships no consent UI.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm i @atlasauth/pca-connectors
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Depends on `@atlasauth/pca` and `@atlasauth/pca-connect` (installed automatically).
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { TokenVault } from '@atlasauth/pca-connect';
|
|
21
|
+
import {
|
|
22
|
+
listProviders, buildAuthorizeUrl, exchangeCode, buildVaultProviders, getProvider, applyAccessToken,
|
|
23
|
+
} from '@atlasauth/pca-connectors';
|
|
24
|
+
|
|
25
|
+
listProviders().map((p) => p.id); // ['airtable', 'atlassian', 'dropbox', 'github', 'google', ...]
|
|
26
|
+
|
|
27
|
+
// 1. Send the user to the provider. Keep `state` and `pkce.verifier` for the callback.
|
|
28
|
+
const { url, state, pkce } = buildAuthorizeUrl('google', {
|
|
29
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
30
|
+
redirectUri: 'https://app.example/callback',
|
|
31
|
+
scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// 2. A vault whose auto-refresh config is derived from the manifests.
|
|
35
|
+
const vault = new TokenVault({
|
|
36
|
+
providers: buildVaultProviders({ google: { clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET } }),
|
|
37
|
+
fetch, // your HTTP transport (the global fetch works)
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// 3. On callback, exchange the code and store a capability-bound connection.
|
|
41
|
+
await exchangeCode({
|
|
42
|
+
providerId: 'google',
|
|
43
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
44
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
45
|
+
code, // from the redirect
|
|
46
|
+
redirectUri: 'https://app.example/callback',
|
|
47
|
+
codeVerifier: pkce?.verifier,
|
|
48
|
+
scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
|
|
49
|
+
fetch,
|
|
50
|
+
bind: { vault, agentId, authority: { principal } }, // b64u keys: the agent, and the root the capability chain must start at
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Later, a verified PCActn releases the token via vault.getConnectionToken(...); then:
|
|
54
|
+
const header = applyAccessToken(getProvider('google')!, accessToken); // { kind: 'header', name: 'Authorization', value: 'Bearer ...' }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Custom providers: `registerProvider(manifest)` validates a manifest and adds it to the default registry, or create your own `ProviderRegistry`. Manifests with a `{var}` placeholder in their URLs (such as Shopify) take `vars: { shop: 'acme' }`.
|
|
58
|
+
|
|
59
|
+
## API
|
|
60
|
+
|
|
61
|
+
- Registry: `ProviderRegistry`, `defaultRegistry`, `registerProvider`, `getProvider`, `listProviders`, `validateManifest`, `assertManifest`
|
|
62
|
+
- Authorization: `buildAuthorizeUrl`, `pkceChallenge`, `applyAccessToken`, `substituteVars`
|
|
63
|
+
- Tokens: `exchangeCode`, `refresh`, `manifestToProviderConfig`, `buildVaultProviders`
|
|
64
|
+
- `providers` namespace with the built-in manifests
|
|
65
|
+
|
|
66
|
+
## Status
|
|
67
|
+
|
|
68
|
+
The manifests are data describing each provider's public OAuth endpoints; verify the scopes and endpoints for your own app registration before relying on them. Refresh behaviour and scope narrowing vary by provider and are declared per manifest. Cryptography in PCA is unaudited.
|
|
69
|
+
|
|
70
|
+
Source and issues: https://github.com/Atlas-Authorization/pca
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT - see LICENSE
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The authorization-request side of a connector: turn a declarative {@link ProviderManifest} into a correct
|
|
3
|
+
* OAuth 2.0 authorize URL (with PKCE when the provider wants it), and describe how the resulting access
|
|
4
|
+
* token is presented on an outbound API call.
|
|
5
|
+
*/
|
|
6
|
+
import { type ProviderManifest } from './manifest';
|
|
7
|
+
import { type ProviderRegistry } from './registry';
|
|
8
|
+
/** Caller-supplied PKCE material (RFC 7636). When omitted, {@link buildAuthorizeUrl} generates it. */
|
|
9
|
+
export interface PkceParams {
|
|
10
|
+
/** The high-entropy `code_verifier` (43–128 unreserved chars). */
|
|
11
|
+
verifier: string;
|
|
12
|
+
/** Challenge method. Default `'S256'`. */
|
|
13
|
+
method?: 'S256' | 'plain';
|
|
14
|
+
}
|
|
15
|
+
/** The PKCE values used for an authorize request; keep `verifier` to complete the code exchange. */
|
|
16
|
+
export interface PkceResult {
|
|
17
|
+
verifier: string;
|
|
18
|
+
challenge: string;
|
|
19
|
+
method: 'S256' | 'plain';
|
|
20
|
+
}
|
|
21
|
+
export interface BuildAuthorizeUrlOptions {
|
|
22
|
+
clientId: string;
|
|
23
|
+
redirectUri: string;
|
|
24
|
+
/** Requested scopes. Defaults to the manifest's `defaultScopes`. */
|
|
25
|
+
scopes?: string[];
|
|
26
|
+
/** CSRF `state`. A random value is generated when omitted; the value used is returned. */
|
|
27
|
+
state?: string;
|
|
28
|
+
/**
|
|
29
|
+
* PKCE control. `true` forces PKCE (auto-generating a verifier); an object supplies the verifier;
|
|
30
|
+
* `false` disables it; omitted follows the manifest's `pkce` flag.
|
|
31
|
+
*/
|
|
32
|
+
pkce?: boolean | PkceParams;
|
|
33
|
+
/** Substitutions for `{var}` placeholders in the manifest URLs (e.g. `{ shop: 'acme' }`). */
|
|
34
|
+
vars?: Record<string, string>;
|
|
35
|
+
/** Registry to resolve `providerId` against. Defaults to the shared {@link defaultRegistry}. */
|
|
36
|
+
registry?: ProviderRegistry;
|
|
37
|
+
/** Extra authorize-request parameters, merged after the manifest's `authParams`. */
|
|
38
|
+
extraParams?: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
/** A built authorize URL plus the `state` and (if used) PKCE values the caller must retain for the exchange. */
|
|
41
|
+
export interface AuthorizeUrl {
|
|
42
|
+
url: string;
|
|
43
|
+
state: string;
|
|
44
|
+
pkce?: PkceResult;
|
|
45
|
+
}
|
|
46
|
+
/** The S256 code challenge for a verifier: base64url(SHA-256(ASCII(verifier))), unpadded (RFC 7636 §4.2). */
|
|
47
|
+
export declare function pkceChallenge(verifier: string, method?: 'S256' | 'plain'): string;
|
|
48
|
+
/** Substitute `{var}` placeholders in `url`. Throws {@link ConnectorError} when a used var is not supplied. */
|
|
49
|
+
export declare function substituteVars(url: string, vars: Record<string, string> | undefined): string;
|
|
50
|
+
/**
|
|
51
|
+
* Build the OAuth 2.0 authorization-request URL for `providerId`. Always emits `response_type=code`,
|
|
52
|
+
* `client_id`, `redirect_uri`, `scope`, and `state`; adds `code_challenge` + `code_challenge_method` when
|
|
53
|
+
* PKCE is in effect, and merges the manifest's `authParams` then the caller's `extraParams`. Scopes are
|
|
54
|
+
* joined with the manifest's `scopeSeparator` (default space). Pure and synchronous.
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildAuthorizeUrl(providerId: string, options: BuildAuthorizeUrlOptions): AuthorizeUrl;
|
|
57
|
+
/** Where a manifest says an access token belongs on an outbound request. */
|
|
58
|
+
export type AppliedToken = {
|
|
59
|
+
kind: 'header';
|
|
60
|
+
name: string;
|
|
61
|
+
value: string;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'query';
|
|
64
|
+
name: string;
|
|
65
|
+
value: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Describe how `accessToken` is attached to a provider API call, per the manifest's `tokenPlacement`:
|
|
69
|
+
* `bearer` → `Authorization: Bearer <token>`; `header` → the custom `headerName`; `query` → the `queryParam`.
|
|
70
|
+
* Returns a value the caller applies to its own request; this package never performs the outbound call.
|
|
71
|
+
*/
|
|
72
|
+
export declare function applyAccessToken(manifest: ProviderManifest, accessToken: string): AppliedToken;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The authorization-request side of a connector: turn a declarative {@link ProviderManifest} into a correct
|
|
4
|
+
* OAuth 2.0 authorize URL (with PKCE when the provider wants it), and describe how the resulting access
|
|
5
|
+
* token is presented on an outbound API call.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.pkceChallenge = pkceChallenge;
|
|
9
|
+
exports.substituteVars = substituteVars;
|
|
10
|
+
exports.buildAuthorizeUrl = buildAuthorizeUrl;
|
|
11
|
+
exports.applyAccessToken = applyAccessToken;
|
|
12
|
+
const pca_1 = require("@atlasauth/pca");
|
|
13
|
+
const manifest_1 = require("./manifest");
|
|
14
|
+
const registry_1 = require("./registry");
|
|
15
|
+
/** 32 bytes of CSPRNG entropy, base64url (unpadded). */
|
|
16
|
+
function randomToken(bytes = 32) {
|
|
17
|
+
const b = new Uint8Array(bytes);
|
|
18
|
+
globalThis.crypto.getRandomValues(b);
|
|
19
|
+
return (0, pca_1.b64u)(b);
|
|
20
|
+
}
|
|
21
|
+
/** The S256 code challenge for a verifier: base64url(SHA-256(ASCII(verifier))), unpadded (RFC 7636 §4.2). */
|
|
22
|
+
function pkceChallenge(verifier, method = 'S256') {
|
|
23
|
+
return method === 'plain' ? verifier : (0, pca_1.b64u)((0, pca_1.sha256)((0, pca_1.utf8)(verifier)));
|
|
24
|
+
}
|
|
25
|
+
/** Substitute `{var}` placeholders in `url`. Throws {@link ConnectorError} when a used var is not supplied. */
|
|
26
|
+
function substituteVars(url, vars) {
|
|
27
|
+
return url.replace(/\{(\w+)\}/g, (_full, name) => {
|
|
28
|
+
const v = vars === undefined ? undefined : vars[name];
|
|
29
|
+
if (v === undefined)
|
|
30
|
+
throw new manifest_1.ConnectorError(`missing URL variable '{${name}}'`);
|
|
31
|
+
return v;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function encodeForm(params) {
|
|
35
|
+
return params.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the OAuth 2.0 authorization-request URL for `providerId`. Always emits `response_type=code`,
|
|
39
|
+
* `client_id`, `redirect_uri`, `scope`, and `state`; adds `code_challenge` + `code_challenge_method` when
|
|
40
|
+
* PKCE is in effect, and merges the manifest's `authParams` then the caller's `extraParams`. Scopes are
|
|
41
|
+
* joined with the manifest's `scopeSeparator` (default space). Pure and synchronous.
|
|
42
|
+
*/
|
|
43
|
+
function buildAuthorizeUrl(providerId, options) {
|
|
44
|
+
const registry = options.registry ?? registry_1.defaultRegistry;
|
|
45
|
+
const manifest = registry.require(providerId);
|
|
46
|
+
const scopes = options.scopes ?? manifest.defaultScopes;
|
|
47
|
+
const separator = manifest.scopeSeparator ?? ' ';
|
|
48
|
+
const state = options.state ?? randomToken();
|
|
49
|
+
const params = [
|
|
50
|
+
['response_type', 'code'],
|
|
51
|
+
['client_id', options.clientId],
|
|
52
|
+
['redirect_uri', options.redirectUri],
|
|
53
|
+
];
|
|
54
|
+
if (scopes.length > 0)
|
|
55
|
+
params.push(['scope', scopes.join(separator)]);
|
|
56
|
+
params.push(['state', state]);
|
|
57
|
+
// PKCE: enabled when explicitly requested, when a verifier object is passed, or (unless disabled) when
|
|
58
|
+
// the manifest declares it.
|
|
59
|
+
const wantPkce = options.pkce === false ? false : options.pkce !== undefined ? true : manifest.pkce === true;
|
|
60
|
+
let pkce;
|
|
61
|
+
if (wantPkce) {
|
|
62
|
+
const verifier = typeof options.pkce === 'object' ? options.pkce.verifier : randomToken();
|
|
63
|
+
const method = typeof options.pkce === 'object' ? options.pkce.method ?? 'S256' : 'S256';
|
|
64
|
+
const challenge = pkceChallenge(verifier, method);
|
|
65
|
+
params.push(['code_challenge', challenge], ['code_challenge_method', method]);
|
|
66
|
+
pkce = { verifier, challenge, method };
|
|
67
|
+
}
|
|
68
|
+
for (const [k, v] of Object.entries(manifest.authParams ?? {}))
|
|
69
|
+
params.push([k, v]);
|
|
70
|
+
for (const [k, v] of Object.entries(options.extraParams ?? {}))
|
|
71
|
+
params.push([k, v]);
|
|
72
|
+
const base = substituteVars(manifest.authorizeUrl, options.vars);
|
|
73
|
+
const url = `${base}${base.includes('?') ? '&' : '?'}${encodeForm(params)}`;
|
|
74
|
+
const result = { url, state };
|
|
75
|
+
if (pkce !== undefined)
|
|
76
|
+
result.pkce = pkce;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Describe how `accessToken` is attached to a provider API call, per the manifest's `tokenPlacement`:
|
|
81
|
+
* `bearer` → `Authorization: Bearer <token>`; `header` → the custom `headerName`; `query` → the `queryParam`.
|
|
82
|
+
* Returns a value the caller applies to its own request; this package never performs the outbound call.
|
|
83
|
+
*/
|
|
84
|
+
function applyAccessToken(manifest, accessToken) {
|
|
85
|
+
switch (manifest.tokenPlacement) {
|
|
86
|
+
case 'bearer':
|
|
87
|
+
return { kind: 'header', name: 'Authorization', value: `Bearer ${accessToken}` };
|
|
88
|
+
case 'header': {
|
|
89
|
+
if (manifest.headerName === undefined)
|
|
90
|
+
throw new manifest_1.ConnectorError(`manifest '${manifest.id}' is header-placed but has no headerName`);
|
|
91
|
+
return { kind: 'header', name: manifest.headerName, value: accessToken };
|
|
92
|
+
}
|
|
93
|
+
case 'query': {
|
|
94
|
+
if (manifest.queryParam === undefined)
|
|
95
|
+
throw new manifest_1.ConnectorError(`manifest '${manifest.id}' is query-placed but has no queryParam`);
|
|
96
|
+
return { kind: 'query', name: manifest.queryParam, value: accessToken };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=authorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../src/authorize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The token side of a connector: exchange an authorization code (or a refresh token) at a provider's token
|
|
3
|
+
* endpoint and FEED the `@atlasauth/pca-connect` vault, so every stored connection is bound to a PCA
|
|
4
|
+
* capability. A connection minted here is unusable until a verified Proof-Carrying Action proves authority
|
|
5
|
+
* over the provider and that the requested scopes are a subset of what the capability grants — that
|
|
6
|
+
* capability binding is the differentiator a plain token vault lacks.
|
|
7
|
+
*
|
|
8
|
+
* The vault's OWN auto-refresh (inside `getConnectionToken`) is wired from the same manifests via
|
|
9
|
+
* {@link manifestToProviderConfig} / {@link buildVaultProviders}, so the catalog is the single source of
|
|
10
|
+
* truth for both the initial grant and later refreshes.
|
|
11
|
+
*/
|
|
12
|
+
import type { ProviderConfig, StoredConnection, TokenVault, VaultFetch } from '@atlasauth/pca-connect';
|
|
13
|
+
import { type ProviderManifest } from './manifest';
|
|
14
|
+
import { type ProviderRegistry } from './registry';
|
|
15
|
+
/** How a minted connection is stored and bound to a PCA capability in the vault. */
|
|
16
|
+
export interface ConnectionBinding {
|
|
17
|
+
vault: TokenVault;
|
|
18
|
+
/** b64u public key of the agent — the capability chain's LEAF holder this connection belongs to. */
|
|
19
|
+
agentId: string;
|
|
20
|
+
/** Vault connection id. Defaults to the vault's own `defaultConnectionId`. */
|
|
21
|
+
connectionId?: string;
|
|
22
|
+
authority: {
|
|
23
|
+
/** b64u public key the capability chain must be rooted at (the PCActn's `cap_chain[0].issuer`). */
|
|
24
|
+
principal: string;
|
|
25
|
+
/** Scopes the capability must cover. Defaults to the requested scopes (least privilege). */
|
|
26
|
+
scopes?: string[];
|
|
27
|
+
/** When set, the PCActn's signed `aud` must equal this resource-server id. */
|
|
28
|
+
audience?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface ExchangeCodeArgs {
|
|
32
|
+
providerId: string;
|
|
33
|
+
clientId: string;
|
|
34
|
+
clientSecret?: string;
|
|
35
|
+
/** The authorization code returned to the redirect URI. */
|
|
36
|
+
code: string;
|
|
37
|
+
redirectUri: string;
|
|
38
|
+
/** The PKCE `code_verifier` used for the authorize request (required when the provider uses PKCE). */
|
|
39
|
+
codeVerifier?: string;
|
|
40
|
+
/** Scopes requested (and the least-privilege authority the connection is bound to). Defaults to the manifest's. */
|
|
41
|
+
scopes?: string[];
|
|
42
|
+
/** Injectable HTTP transport (same contract as the vault's `fetch`). */
|
|
43
|
+
fetch: VaultFetch;
|
|
44
|
+
/** How to store + capability-bind the resulting connection. */
|
|
45
|
+
bind: ConnectionBinding;
|
|
46
|
+
/** Clock, epoch ms. Defaults to `Date.now`. */
|
|
47
|
+
now?: number;
|
|
48
|
+
/** Registry to resolve `providerId` against. Defaults to {@link defaultRegistry}. */
|
|
49
|
+
registry?: ProviderRegistry;
|
|
50
|
+
/** `{var}` substitutions for the manifest token URL. */
|
|
51
|
+
vars?: Record<string, string>;
|
|
52
|
+
/** Extra static token-request form parameters. */
|
|
53
|
+
extraParams?: Record<string, string>;
|
|
54
|
+
}
|
|
55
|
+
export interface RefreshArgs {
|
|
56
|
+
providerId: string;
|
|
57
|
+
clientId: string;
|
|
58
|
+
clientSecret?: string;
|
|
59
|
+
/** The refresh token to present (the vault does not expose stored refresh tokens without a PCActn). */
|
|
60
|
+
refreshToken: string;
|
|
61
|
+
/** Scopes to request / re-bind. Defaults to the manifest's `defaultScopes`. */
|
|
62
|
+
scopes?: string[];
|
|
63
|
+
fetch: VaultFetch;
|
|
64
|
+
bind: ConnectionBinding;
|
|
65
|
+
now?: number;
|
|
66
|
+
registry?: ProviderRegistry;
|
|
67
|
+
vars?: Record<string, string>;
|
|
68
|
+
extraParams?: Record<string, string>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Exchange an authorization code for tokens and store a capability-bound connection in the vault. The
|
|
72
|
+
* requested scopes become the connection's least-privilege authority; the connection is unusable until a
|
|
73
|
+
* verified PCActn proves a capability covering them.
|
|
74
|
+
*/
|
|
75
|
+
export declare function exchangeCode(args: ExchangeCodeArgs): Promise<StoredConnection>;
|
|
76
|
+
/**
|
|
77
|
+
* Refresh an access token at the provider's refresh endpoint and re-store the capability-bound connection.
|
|
78
|
+
* Throws when the manifest declares `refresh.mode === 'none'`. Scope narrowing is sent only when the
|
|
79
|
+
* manifest opts in. The authority binding is preserved from `bind` (re-asserting least privilege).
|
|
80
|
+
*/
|
|
81
|
+
export declare function refresh(args: RefreshArgs): Promise<StoredConnection>;
|
|
82
|
+
/** Per-provider client credentials used to derive a vault {@link ProviderConfig}. */
|
|
83
|
+
export interface ProviderCredentials {
|
|
84
|
+
clientId: string;
|
|
85
|
+
clientSecret?: string;
|
|
86
|
+
/** `{var}` substitutions for the refresh token endpoint (e.g. `{ shop: 'acme' }`). */
|
|
87
|
+
vars?: Record<string, string>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Derive the `@atlasauth/pca-connect` {@link ProviderConfig} the vault uses for its OWN auto-refresh, from a
|
|
91
|
+
* manifest + credentials. This is how the catalog drives the vault's internal refresh: the manifest's token
|
|
92
|
+
* endpoint, scope-narrowing flag and extra params flow straight into the vault. Throws when the manifest
|
|
93
|
+
* does not support refresh.
|
|
94
|
+
*/
|
|
95
|
+
export declare function manifestToProviderConfig(manifest: ProviderManifest, creds: ProviderCredentials): ProviderConfig;
|
|
96
|
+
/**
|
|
97
|
+
* Build the vault's `providers` map (provider id → {@link ProviderConfig}) from a set of configured
|
|
98
|
+
* providers, skipping any whose manifest cannot refresh. Pass the result to `new TokenVault({ providers })`.
|
|
99
|
+
*/
|
|
100
|
+
export declare function buildVaultProviders(credsById: Record<string, ProviderCredentials>, registry?: ProviderRegistry): Record<string, ProviderConfig>;
|
package/dist/exchange.js
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The token side of a connector: exchange an authorization code (or a refresh token) at a provider's token
|
|
4
|
+
* endpoint and FEED the `@atlasauth/pca-connect` vault, so every stored connection is bound to a PCA
|
|
5
|
+
* capability. A connection minted here is unusable until a verified Proof-Carrying Action proves authority
|
|
6
|
+
* over the provider and that the requested scopes are a subset of what the capability grants — that
|
|
7
|
+
* capability binding is the differentiator a plain token vault lacks.
|
|
8
|
+
*
|
|
9
|
+
* The vault's OWN auto-refresh (inside `getConnectionToken`) is wired from the same manifests via
|
|
10
|
+
* {@link manifestToProviderConfig} / {@link buildVaultProviders}, so the catalog is the single source of
|
|
11
|
+
* truth for both the initial grant and later refreshes.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.exchangeCode = exchangeCode;
|
|
15
|
+
exports.refresh = refresh;
|
|
16
|
+
exports.manifestToProviderConfig = manifestToProviderConfig;
|
|
17
|
+
exports.buildVaultProviders = buildVaultProviders;
|
|
18
|
+
const pca_1 = require("@atlasauth/pca");
|
|
19
|
+
const manifest_1 = require("./manifest");
|
|
20
|
+
const registry_1 = require("./registry");
|
|
21
|
+
const authorize_1 = require("./authorize");
|
|
22
|
+
/** Default access-token lifetime assumed when the provider returns neither `expires_in` nor a JWT `exp`. */
|
|
23
|
+
const DEFAULT_TOKEN_LIFETIME_MS = 3_600_000;
|
|
24
|
+
/** Read own property `k` off `o` as `unknown`, without a cast. */
|
|
25
|
+
function prop(o, k) {
|
|
26
|
+
return Object.prototype.hasOwnProperty.call(o, k) ? Reflect.get(o, k) : undefined;
|
|
27
|
+
}
|
|
28
|
+
function errText(e) {
|
|
29
|
+
return e instanceof Error ? e.message : String(e);
|
|
30
|
+
}
|
|
31
|
+
/** Standard base64 (padded) of `s` — for HTTP Basic client authentication (RFC 6749 §2.3.1). */
|
|
32
|
+
function basicAuthHeader(clientId, clientSecret) {
|
|
33
|
+
let s = (0, pca_1.b64u)((0, pca_1.utf8)(`${clientId}:${clientSecret}`)).replace(/-/g, '+').replace(/_/g, '/');
|
|
34
|
+
while (s.length % 4 !== 0)
|
|
35
|
+
s += '=';
|
|
36
|
+
return `Basic ${s}`;
|
|
37
|
+
}
|
|
38
|
+
function formEncode(params) {
|
|
39
|
+
return Object.entries(params)
|
|
40
|
+
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
41
|
+
.join('&');
|
|
42
|
+
}
|
|
43
|
+
/** Parse an OAuth token-endpoint JSON body. Fails closed: a missing/empty `access_token` is a hard error. */
|
|
44
|
+
function parseTokenResponse(body, provider) {
|
|
45
|
+
if (body === null || typeof body !== 'object' || Array.isArray(body)) {
|
|
46
|
+
throw new manifest_1.ConnectorError(`[${provider}] token endpoint returned a non-object body`);
|
|
47
|
+
}
|
|
48
|
+
const accessToken = prop(body, 'access_token');
|
|
49
|
+
if (typeof accessToken !== 'string' || accessToken.length === 0) {
|
|
50
|
+
throw new manifest_1.ConnectorError(`[${provider}] token endpoint response has no access_token`);
|
|
51
|
+
}
|
|
52
|
+
const out = { accessToken };
|
|
53
|
+
const expiresIn = prop(body, 'expires_in');
|
|
54
|
+
if (typeof expiresIn === 'number' && Number.isFinite(expiresIn) && expiresIn > 0)
|
|
55
|
+
out.expiresInSecs = expiresIn;
|
|
56
|
+
const refreshToken = prop(body, 'refresh_token');
|
|
57
|
+
if (typeof refreshToken === 'string' && refreshToken.length > 0)
|
|
58
|
+
out.refreshToken = refreshToken;
|
|
59
|
+
const scope = prop(body, 'scope');
|
|
60
|
+
if (typeof scope === 'string' && scope.trim().length > 0)
|
|
61
|
+
out.scopes = scope.trim().split(/[\s,]+/);
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/** POST a form to a token endpoint via the injectable transport and parse the response (fail-closed). */
|
|
65
|
+
async function postToken(manifest, tokenEndpoint, params, clientSecret, fetchImpl) {
|
|
66
|
+
const headers = {
|
|
67
|
+
'content-type': 'application/x-www-form-urlencoded',
|
|
68
|
+
accept: 'application/json',
|
|
69
|
+
};
|
|
70
|
+
const body = { ...params };
|
|
71
|
+
if (manifest.clientAuth === 'basic') {
|
|
72
|
+
// Client credentials move to the Authorization header; they must not also appear in the body.
|
|
73
|
+
if (clientSecret === undefined)
|
|
74
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] clientAuth 'basic' requires a clientSecret`);
|
|
75
|
+
const clientId = body['client_id'];
|
|
76
|
+
if (clientId === undefined)
|
|
77
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] missing client_id for basic auth`);
|
|
78
|
+
headers['authorization'] = basicAuthHeader(clientId, clientSecret);
|
|
79
|
+
delete body['client_id'];
|
|
80
|
+
delete body['client_secret'];
|
|
81
|
+
}
|
|
82
|
+
let res;
|
|
83
|
+
try {
|
|
84
|
+
res = await fetchImpl(tokenEndpoint, { method: 'POST', headers, body: formEncode(body) });
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] token transport error: ${errText(e)}`);
|
|
88
|
+
}
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
let detail = '';
|
|
91
|
+
try {
|
|
92
|
+
detail = (await res.text()).slice(0, 256);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
detail = '<unreadable body>';
|
|
96
|
+
}
|
|
97
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] token endpoint ${res.status}: ${detail}`);
|
|
98
|
+
}
|
|
99
|
+
let json;
|
|
100
|
+
try {
|
|
101
|
+
json = await res.json();
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] unparseable token JSON: ${errText(e)}`);
|
|
105
|
+
}
|
|
106
|
+
return parseTokenResponse(json, manifest.id);
|
|
107
|
+
}
|
|
108
|
+
/** Store the token result in the vault, bound to the PCA capability authority. */
|
|
109
|
+
async function storeConnection(manifest, parsed, requested, bind, now, priorRefreshToken) {
|
|
110
|
+
const expiresAt = parsed.expiresInSecs !== undefined ? now + parsed.expiresInSecs * 1000 : now + DEFAULT_TOKEN_LIFETIME_MS;
|
|
111
|
+
// Scopes the stored token actually carries: the provider's echo wins; else the requested set.
|
|
112
|
+
const granted = parsed.scopes ?? requested;
|
|
113
|
+
// Token rotation: keep the prior refresh token unless the provider issued a new one.
|
|
114
|
+
const refreshToken = parsed.refreshToken ?? priorRefreshToken;
|
|
115
|
+
return bind.vault.putConnection({
|
|
116
|
+
agentId: bind.agentId,
|
|
117
|
+
provider: manifest.id,
|
|
118
|
+
accessToken: parsed.accessToken,
|
|
119
|
+
expiresAt,
|
|
120
|
+
scopes: granted,
|
|
121
|
+
authority: {
|
|
122
|
+
principal: bind.authority.principal,
|
|
123
|
+
scopes: bind.authority.scopes ?? requested,
|
|
124
|
+
...(bind.authority.audience !== undefined ? { audience: bind.authority.audience } : {}),
|
|
125
|
+
},
|
|
126
|
+
...(bind.connectionId !== undefined ? { connectionId: bind.connectionId } : {}),
|
|
127
|
+
...(refreshToken !== undefined ? { refreshToken } : {}),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Exchange an authorization code for tokens and store a capability-bound connection in the vault. The
|
|
132
|
+
* requested scopes become the connection's least-privilege authority; the connection is unusable until a
|
|
133
|
+
* verified PCActn proves a capability covering them.
|
|
134
|
+
*/
|
|
135
|
+
async function exchangeCode(args) {
|
|
136
|
+
const registry = args.registry ?? registry_1.defaultRegistry;
|
|
137
|
+
const manifest = registry.require(args.providerId);
|
|
138
|
+
const now = args.now ?? Date.now();
|
|
139
|
+
const requested = args.scopes ?? manifest.defaultScopes;
|
|
140
|
+
if (manifest.pkce === true && args.codeVerifier === undefined) {
|
|
141
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] provider uses PKCE; a codeVerifier is required to exchange the code`);
|
|
142
|
+
}
|
|
143
|
+
const params = {
|
|
144
|
+
grant_type: 'authorization_code',
|
|
145
|
+
code: args.code,
|
|
146
|
+
redirect_uri: args.redirectUri,
|
|
147
|
+
client_id: args.clientId,
|
|
148
|
+
...(args.clientSecret !== undefined ? { client_secret: args.clientSecret } : {}),
|
|
149
|
+
...(args.codeVerifier !== undefined ? { code_verifier: args.codeVerifier } : {}),
|
|
150
|
+
...(args.extraParams ?? {}),
|
|
151
|
+
};
|
|
152
|
+
const tokenEndpoint = (0, authorize_1.substituteVars)(manifest.tokenUrl, args.vars);
|
|
153
|
+
const parsed = await postToken(manifest, tokenEndpoint, params, args.clientSecret, args.fetch);
|
|
154
|
+
return storeConnection(manifest, parsed, requested, args.bind, now);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Refresh an access token at the provider's refresh endpoint and re-store the capability-bound connection.
|
|
158
|
+
* Throws when the manifest declares `refresh.mode === 'none'`. Scope narrowing is sent only when the
|
|
159
|
+
* manifest opts in. The authority binding is preserved from `bind` (re-asserting least privilege).
|
|
160
|
+
*/
|
|
161
|
+
async function refresh(args) {
|
|
162
|
+
const registry = args.registry ?? registry_1.defaultRegistry;
|
|
163
|
+
const manifest = registry.require(args.providerId);
|
|
164
|
+
if (manifest.refresh.mode === 'none') {
|
|
165
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] provider does not support token refresh`);
|
|
166
|
+
}
|
|
167
|
+
const now = args.now ?? Date.now();
|
|
168
|
+
const requested = args.scopes ?? manifest.defaultScopes;
|
|
169
|
+
const params = {
|
|
170
|
+
grant_type: 'refresh_token',
|
|
171
|
+
refresh_token: args.refreshToken,
|
|
172
|
+
client_id: args.clientId,
|
|
173
|
+
...(args.clientSecret !== undefined ? { client_secret: args.clientSecret } : {}),
|
|
174
|
+
...(manifest.refresh.extraParams ?? {}),
|
|
175
|
+
...(args.extraParams ?? {}),
|
|
176
|
+
};
|
|
177
|
+
if (manifest.refresh.supportsScopeNarrowing === true && requested.length > 0) {
|
|
178
|
+
params['scope'] = requested.join(manifest.scopeSeparator ?? ' ');
|
|
179
|
+
}
|
|
180
|
+
const tokenEndpoint = (0, authorize_1.substituteVars)(manifest.refresh.tokenEndpoint ?? manifest.tokenUrl, args.vars);
|
|
181
|
+
const parsed = await postToken(manifest, tokenEndpoint, params, args.clientSecret, args.fetch);
|
|
182
|
+
return storeConnection(manifest, parsed, requested, args.bind, now, args.refreshToken);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Derive the `@atlasauth/pca-connect` {@link ProviderConfig} the vault uses for its OWN auto-refresh, from a
|
|
186
|
+
* manifest + credentials. This is how the catalog drives the vault's internal refresh: the manifest's token
|
|
187
|
+
* endpoint, scope-narrowing flag and extra params flow straight into the vault. Throws when the manifest
|
|
188
|
+
* does not support refresh.
|
|
189
|
+
*/
|
|
190
|
+
function manifestToProviderConfig(manifest, creds) {
|
|
191
|
+
if (manifest.refresh.mode === 'none') {
|
|
192
|
+
throw new manifest_1.ConnectorError(`[${manifest.id}] provider does not support token refresh; no ProviderConfig`);
|
|
193
|
+
}
|
|
194
|
+
const config = {
|
|
195
|
+
tokenEndpoint: (0, authorize_1.substituteVars)(manifest.refresh.tokenEndpoint ?? manifest.tokenUrl, creds.vars),
|
|
196
|
+
clientId: creds.clientId,
|
|
197
|
+
};
|
|
198
|
+
if (creds.clientSecret !== undefined)
|
|
199
|
+
config.clientSecret = creds.clientSecret;
|
|
200
|
+
if (manifest.refresh.supportsScopeNarrowing !== undefined)
|
|
201
|
+
config.supportsScopeNarrowing = manifest.refresh.supportsScopeNarrowing;
|
|
202
|
+
if (manifest.refresh.extraParams !== undefined)
|
|
203
|
+
config.extraParams = { ...manifest.refresh.extraParams };
|
|
204
|
+
return config;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Build the vault's `providers` map (provider id → {@link ProviderConfig}) from a set of configured
|
|
208
|
+
* providers, skipping any whose manifest cannot refresh. Pass the result to `new TokenVault({ providers })`.
|
|
209
|
+
*/
|
|
210
|
+
function buildVaultProviders(credsById, registry = registry_1.defaultRegistry) {
|
|
211
|
+
const out = {};
|
|
212
|
+
for (const [id, creds] of Object.entries(credsById)) {
|
|
213
|
+
const manifest = registry.require(id);
|
|
214
|
+
if (manifest.refresh.mode === 'none')
|
|
215
|
+
continue;
|
|
216
|
+
out[id] = manifestToProviderConfig(manifest, creds);
|
|
217
|
+
}
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=exchange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange.js","sourceRoot":"","sources":["../src/exchange.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@atlasauth/pca-connectors` — the connector catalog for Proof-Carrying Authority.
|
|
3
|
+
*
|
|
4
|
+
* A declarative registry of outbound SaaS providers (Google, GitHub, Slack, …) as data manifests, plus the
|
|
5
|
+
* authorize-URL / code-exchange / refresh helpers that feed the `@atlasauth/pca-connect` token vault. Wiring
|
|
6
|
+
* a new outbound tool is a manifest edit, and EVERY connection minted here is bound to a PCA capability —
|
|
7
|
+
* so every outbound token a tool call presents is a proof-carrying, least-privilege capability, not an
|
|
8
|
+
* ambient secret. That capability binding is the property Composio / Descope / Auth0 Token Vault lack.
|
|
9
|
+
*
|
|
10
|
+
* This is the CODE layer; a hosted consent UI is a separate product piece built on top of it.
|
|
11
|
+
*/
|
|
12
|
+
export { type TokenPlacement, type RefreshMode, type ClientAuthMethod, type RefreshSpec, type ProviderManifest, type ManifestValidation, ConnectorError, ManifestValidationError, UnknownProviderError, validateManifest, assertManifest, } from './manifest';
|
|
13
|
+
export { ProviderRegistry, createDefaultRegistry, defaultRegistry, registerProvider, getProvider, listProviders, } from './registry';
|
|
14
|
+
export { type PkceParams, type PkceResult, type BuildAuthorizeUrlOptions, type AuthorizeUrl, type AppliedToken, buildAuthorizeUrl, pkceChallenge, substituteVars, applyAccessToken, } from './authorize';
|
|
15
|
+
export { type ConnectionBinding, type ExchangeCodeArgs, type RefreshArgs, type ProviderCredentials, exchangeCode, refresh, manifestToProviderConfig, buildVaultProviders, } from './exchange';
|
|
16
|
+
export * as providers from './providers';
|
|
17
|
+
export { type ConnectionToken, type StoredConnection, type ProviderConfig, type VaultFetch, type VaultHttpRequest, type VaultHttpResponse, TokenVault, InMemoryConnectionStore, oauthScopeCaveat, grantedOAuthScopes, NotAuthorizedError, ScopeExceededError, ExpiredNoRefreshError, RefreshFailedError, UnknownConnectionError, VaultError, } from '@atlasauth/pca-connect';
|