@kya-os/mcp-i-cloudflare 1.13.3 → 1.13.4
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 +8 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +32 -2
- package/dist/agent.js.map +1 -1
- package/dist/constants/storage-keys.d.ts +37 -0
- package/dist/constants/storage-keys.d.ts.map +1 -1
- package/dist/constants/storage-keys.js +50 -0
- package/dist/constants/storage-keys.js.map +1 -1
- package/dist/runtime/oauth-handler.d.ts.map +1 -1
- package/dist/runtime/oauth-handler.js +25 -1
- package/dist/runtime/oauth-handler.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +17 -0
- package/dist/runtime.js.map +1 -1
- package/dist/services/batch-queue.d.ts +3 -1
- package/dist/services/batch-queue.d.ts.map +1 -1
- package/dist/services/batch-queue.js +16 -10
- package/dist/services/batch-queue.js.map +1 -1
- package/dist/services/consent.service.d.ts.map +1 -1
- package/dist/services/consent.service.js +59 -2
- package/dist/services/consent.service.js.map +1 -1
- package/dist/services/delegation.service.d.ts.map +1 -1
- package/dist/services/delegation.service.js +4 -0
- package/dist/services/delegation.service.js.map +1 -1
- package/dist/utils/hidden-consent-tools.d.ts +37 -0
- package/dist/utils/hidden-consent-tools.d.ts.map +1 -0
- package/dist/utils/hidden-consent-tools.js +60 -0
- package/dist/utils/hidden-consent-tools.js.map +1 -0
- package/package.json +4 -4
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { ConsentConfigService } from "./consent-config.service";
|
|
10
10
|
import { TemplateRenderer } from "./consent-templates/template-renderer";
|
|
11
11
|
import { DEFAULT_AGENTSHIELD_URL, DEFAULT_SESSION_CACHE_TTL, KEY_PAIR_TTL_SECONDS, CONSENT_PROVIDER_TYPES, } from "../constants";
|
|
12
|
-
import { STORAGE_KEYS } from "../constants/storage-keys";
|
|
12
|
+
import { STORAGE_KEYS, isPendingDelegationId, } from "../constants/storage-keys";
|
|
13
13
|
import { loadDay0Config, getDelegationFieldName } from "../utils/day0-config";
|
|
14
14
|
import { buildProviderAuthorizeUrl } from "../runtime/oidc/authorize-url.js";
|
|
15
15
|
import { resolveIdpScopes } from "../runtime/oidc/idp-scopes.js";
|
|
@@ -4045,7 +4045,34 @@ export class ConsentService {
|
|
|
4045
4045
|
const delegationStorage = this.env.DELEGATION_STORAGE;
|
|
4046
4046
|
// Task B2: normalize once (folds deprecated aliases: oauth→oauth2) so every
|
|
4047
4047
|
// stored record and every read compares in the same vocabulary.
|
|
4048
|
-
|
|
4048
|
+
//
|
|
4049
|
+
// SECURITY — the authoritative pre-consent guard. This method is the single
|
|
4050
|
+
// choke point through which an authorization type reaches BOTH destinations
|
|
4051
|
+
// the enforcement gate can read: the Durable Object record
|
|
4052
|
+
// (`storeDelegationViaDO` below) and the KV sidecar. A `pending_` delegation
|
|
4053
|
+
// id means the OAuth callback parked a placeholder whose token is still the
|
|
4054
|
+
// raw IdP access token — the real delegation is only minted once the user
|
|
4055
|
+
// approves on the clickwrap. Recording a type for it would let the gate
|
|
4056
|
+
// treat a pre-consent token as a satisfying delegation and run a protected
|
|
4057
|
+
// tool before the user ever consented.
|
|
4058
|
+
//
|
|
4059
|
+
// Guarding HERE rather than at each caller is deliberate: `oauth-handler.ts`
|
|
4060
|
+
// reaches this via `storeDelegationForOAuth` with a hardcoded "oauth2" and
|
|
4061
|
+
// the pending tokenData, so a per-call-site guard would have to be repeated
|
|
4062
|
+
// at every present and future writer. Dropping the type to undefined makes
|
|
4063
|
+
// every downstream consumer fail safe, because absent already means
|
|
4064
|
+
// "reject" at the gate.
|
|
4065
|
+
const isPendingDelegation = isPendingDelegationId(delegationId);
|
|
4066
|
+
const normalizedAuthorizationType = isPendingDelegation
|
|
4067
|
+
? undefined
|
|
4068
|
+
: normalizeAuthType(authorizationType);
|
|
4069
|
+
if (isPendingDelegation && authorizationType) {
|
|
4070
|
+
logger.warn("[ConsentService] Refusing to record an authorization type for a pending (pre-consent) delegation", {
|
|
4071
|
+
delegationId,
|
|
4072
|
+
requestedAuthorizationType: authorizationType,
|
|
4073
|
+
note: "The real delegation is minted after clickwrap approval; typing this token would authorize it pre-consent.",
|
|
4074
|
+
});
|
|
4075
|
+
}
|
|
4049
4076
|
// Resolve userDid if not provided
|
|
4050
4077
|
let userDid = providedUserDid;
|
|
4051
4078
|
if (!userDid && delegationStorage) {
|
|
@@ -4079,6 +4106,36 @@ export class ConsentService {
|
|
|
4079
4106
|
await delegationStorage.put(userAgentKey, token, {
|
|
4080
4107
|
expirationTtl: ttl,
|
|
4081
4108
|
});
|
|
4109
|
+
// Record the auth type alongside it (separate key — the value above
|
|
4110
|
+
// is a bare token that several readers consume as the JWT itself).
|
|
4111
|
+
// Without this, a delegation recovered via the KV-legacy path in
|
|
4112
|
+
// agent.ts carries no type and can never satisfy a typed tool, so a
|
|
4113
|
+
// DO miss becomes a permanent re-challenge loop rather than a
|
|
4114
|
+
// one-time re-auth.
|
|
4115
|
+
//
|
|
4116
|
+
// INVARIANT: a sidecar present ⇒ it describes the token currently
|
|
4117
|
+
// under the key above. So an untyped write must CLEAR any existing
|
|
4118
|
+
// sidecar rather than leave it: the token was just replaced, and a
|
|
4119
|
+
// leftover type from a previous mint would be inherited by the new
|
|
4120
|
+
// (weaker or unknown) token on the next KV read. Revocation already
|
|
4121
|
+
// deletes the sidecar for exactly this reason; a remint must too.
|
|
4122
|
+
const authTypeKey = STORAGE_KEYS.delegationAuthType(userDid, agentDid);
|
|
4123
|
+
if (normalizedAuthorizationType) {
|
|
4124
|
+
await delegationStorage.put(authTypeKey, normalizedAuthorizationType, { expirationTtl: ttl });
|
|
4125
|
+
}
|
|
4126
|
+
else {
|
|
4127
|
+
// Clearing a stale sidecar is cleanup, not the primary write: it
|
|
4128
|
+
// must never abort the session-key write that follows. Swallow its
|
|
4129
|
+
// failure rather than letting it escape to the enclosing catch.
|
|
4130
|
+
// Failing to clear is safe in the conservative direction only for
|
|
4131
|
+
// the token it described, so it is logged rather than ignored.
|
|
4132
|
+
try {
|
|
4133
|
+
await delegationStorage.delete?.(authTypeKey);
|
|
4134
|
+
}
|
|
4135
|
+
catch (clearError) {
|
|
4136
|
+
logger.warn("[ConsentService] Could not clear stale delegation auth-type sidecar", clearError);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4082
4139
|
logger.debug("[ConsentService] Token also stored to KV (user+agent key)");
|
|
4083
4140
|
}
|
|
4084
4141
|
// Store session key (for session data preservation)
|