@kindgi/api 0.0.0-bootstrap.0 → 0.1.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 +201 -0
- package/README.md +216 -1
- package/dist/adapter-binding.d.ts +177 -0
- package/dist/adapter-binding.d.ts.map +1 -0
- package/dist/adapter-binding.js +12 -0
- package/dist/adapter-binding.js.map +1 -0
- package/dist/agent-binding.d.ts +207 -0
- package/dist/agent-binding.d.ts.map +1 -0
- package/dist/agent-binding.js +4 -0
- package/dist/agent-binding.js.map +1 -0
- package/dist/app.d.ts +770 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +396 -0
- package/dist/app.js.map +1 -0
- package/dist/capability-binding.d.ts +76 -0
- package/dist/capability-binding.d.ts.map +1 -0
- package/dist/capability-binding.js +4 -0
- package/dist/capability-binding.js.map +1 -0
- package/dist/cost-binding.d.ts +175 -0
- package/dist/cost-binding.d.ts.map +1 -0
- package/dist/cost-binding.js +13 -0
- package/dist/cost-binding.js.map +1 -0
- package/dist/deployment-binding.d.ts +201 -0
- package/dist/deployment-binding.d.ts.map +1 -0
- package/dist/deployment-binding.js +4 -0
- package/dist/deployment-binding.js.map +1 -0
- package/dist/env-binding.d.ts +132 -0
- package/dist/env-binding.d.ts.map +1 -0
- package/dist/env-binding.js +4 -0
- package/dist/env-binding.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +264 -0
- package/dist/errors.js.map +1 -0
- package/dist/eval-run-binding.d.ts +196 -0
- package/dist/eval-run-binding.d.ts.map +1 -0
- package/dist/eval-run-binding.js +16 -0
- package/dist/eval-run-binding.js.map +1 -0
- package/dist/eval-run-dispatcher.d.ts +131 -0
- package/dist/eval-run-dispatcher.d.ts.map +1 -0
- package/dist/eval-run-dispatcher.js +368 -0
- package/dist/eval-run-dispatcher.js.map +1 -0
- package/dist/eval-suite-binding.d.ts +227 -0
- package/dist/eval-suite-binding.d.ts.map +1 -0
- package/dist/eval-suite-binding.js +24 -0
- package/dist/eval-suite-binding.js.map +1 -0
- package/dist/event-bus-binding.d.ts +107 -0
- package/dist/event-bus-binding.d.ts.map +1 -0
- package/dist/event-bus-binding.js +5 -0
- package/dist/event-bus-binding.js.map +1 -0
- package/dist/flow-binding.d.ts +194 -0
- package/dist/flow-binding.d.ts.map +1 -0
- package/dist/flow-binding.js +4 -0
- package/dist/flow-binding.js.map +1 -0
- package/dist/guardrail-binding.d.ts +138 -0
- package/dist/guardrail-binding.d.ts.map +1 -0
- package/dist/guardrail-binding.js +4 -0
- package/dist/guardrail-binding.js.map +1 -0
- package/dist/handler-binding.d.ts +126 -0
- package/dist/handler-binding.d.ts.map +1 -0
- package/dist/handler-binding.js +4 -0
- package/dist/handler-binding.js.map +1 -0
- package/dist/hitl-binding.d.ts +115 -0
- package/dist/hitl-binding.d.ts.map +1 -0
- package/dist/hitl-binding.js +4 -0
- package/dist/hitl-binding.js.map +1 -0
- package/dist/identity-directory-binding.d.ts +116 -0
- package/dist/identity-directory-binding.d.ts.map +1 -0
- package/dist/identity-directory-binding.js +4 -0
- package/dist/identity-directory-binding.js.map +1 -0
- package/dist/identity-provider-binding.d.ts +184 -0
- package/dist/identity-provider-binding.d.ts.map +1 -0
- package/dist/identity-provider-binding.js +4 -0
- package/dist/identity-provider-binding.js.map +1 -0
- package/dist/image-registry-binding.d.ts +165 -0
- package/dist/image-registry-binding.d.ts.map +1 -0
- package/dist/image-registry-binding.js +4 -0
- package/dist/image-registry-binding.js.map +1 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/key-management-binding.d.ts +101 -0
- package/dist/key-management-binding.d.ts.map +1 -0
- package/dist/key-management-binding.js +4 -0
- package/dist/key-management-binding.js.map +1 -0
- package/dist/mcp-endpoint-binding.d.ts +312 -0
- package/dist/mcp-endpoint-binding.d.ts.map +1 -0
- package/dist/mcp-endpoint-binding.js +12 -0
- package/dist/mcp-endpoint-binding.js.map +1 -0
- package/dist/memory-binding.d.ts +209 -0
- package/dist/memory-binding.d.ts.map +1 -0
- package/dist/memory-binding.js +4 -0
- package/dist/memory-binding.js.map +1 -0
- package/dist/middleware/auth.d.ts +168 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +247 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/authorize.d.ts +26 -0
- package/dist/middleware/authorize.d.ts.map +1 -0
- package/dist/middleware/authorize.js +65 -0
- package/dist/middleware/authorize.js.map +1 -0
- package/dist/middleware/error-mapper.d.ts +13 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -0
- package/dist/middleware/error-mapper.js +32 -0
- package/dist/middleware/error-mapper.js.map +1 -0
- package/dist/middleware/idempotency.d.ts +43 -0
- package/dist/middleware/idempotency.d.ts.map +1 -0
- package/dist/middleware/idempotency.js +118 -0
- package/dist/middleware/idempotency.js.map +1 -0
- package/dist/middleware/principal.d.ts +4 -0
- package/dist/middleware/principal.d.ts.map +1 -0
- package/dist/middleware/principal.js +42 -0
- package/dist/middleware/principal.js.map +1 -0
- package/dist/middleware/public-run-routes.d.ts +16 -0
- package/dist/middleware/public-run-routes.d.ts.map +1 -0
- package/dist/middleware/public-run-routes.js +43 -0
- package/dist/middleware/public-run-routes.js.map +1 -0
- package/dist/middleware/request-id.d.ts +14 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +24 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/middleware/sigv4-verify.d.ts +64 -0
- package/dist/middleware/sigv4-verify.d.ts.map +1 -0
- package/dist/middleware/sigv4-verify.js +286 -0
- package/dist/middleware/sigv4-verify.js.map +1 -0
- package/dist/middleware/sigv4.d.ts +25 -0
- package/dist/middleware/sigv4.d.ts.map +1 -0
- package/dist/middleware/sigv4.js +120 -0
- package/dist/middleware/sigv4.js.map +1 -0
- package/dist/openapi/generate.d.ts +15 -0
- package/dist/openapi/generate.d.ts.map +1 -0
- package/dist/openapi/generate.js +241 -0
- package/dist/openapi/generate.js.map +1 -0
- package/dist/openapi/operations.d.ts +70 -0
- package/dist/openapi/operations.d.ts.map +1 -0
- package/dist/openapi/operations.js +5051 -0
- package/dist/openapi/operations.js.map +1 -0
- package/dist/openapi/schemas.d.ts +590 -0
- package/dist/openapi/schemas.d.ts.map +1 -0
- package/dist/openapi/schemas.js +5820 -0
- package/dist/openapi/schemas.js.map +1 -0
- package/dist/provenance-binding.d.ts +116 -0
- package/dist/provenance-binding.d.ts.map +1 -0
- package/dist/provenance-binding.js +31 -0
- package/dist/provenance-binding.js.map +1 -0
- package/dist/provider-binding.d.ts +174 -0
- package/dist/provider-binding.d.ts.map +1 -0
- package/dist/provider-binding.js +4 -0
- package/dist/provider-binding.js.map +1 -0
- package/dist/public-run-token.d.ts +97 -0
- package/dist/public-run-token.d.ts.map +1 -0
- package/dist/public-run-token.js +167 -0
- package/dist/public-run-token.js.map +1 -0
- package/dist/retention-binding.d.ts +69 -0
- package/dist/retention-binding.d.ts.map +1 -0
- package/dist/retention-binding.js +4 -0
- package/dist/retention-binding.js.map +1 -0
- package/dist/reviewer-binding.d.ts +84 -0
- package/dist/reviewer-binding.d.ts.map +1 -0
- package/dist/reviewer-binding.js +4 -0
- package/dist/reviewer-binding.js.map +1 -0
- package/dist/rotation-status-store.d.ts +96 -0
- package/dist/rotation-status-store.d.ts.map +1 -0
- package/dist/rotation-status-store.js +106 -0
- package/dist/rotation-status-store.js.map +1 -0
- package/dist/routes/adapters.d.ts +29 -0
- package/dist/routes/adapters.d.ts.map +1 -0
- package/dist/routes/adapters.js +230 -0
- package/dist/routes/adapters.js.map +1 -0
- package/dist/routes/agents.d.ts +17 -0
- package/dist/routes/agents.d.ts.map +1 -0
- package/dist/routes/agents.js +342 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/approvals.d.ts +37 -0
- package/dist/routes/approvals.d.ts.map +1 -0
- package/dist/routes/approvals.js +551 -0
- package/dist/routes/approvals.js.map +1 -0
- package/dist/routes/artifacts.d.ts +25 -0
- package/dist/routes/artifacts.d.ts.map +1 -0
- package/dist/routes/artifacts.js +265 -0
- package/dist/routes/artifacts.js.map +1 -0
- package/dist/routes/audit.d.ts +6 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +162 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/auth.d.ts +47 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +630 -0
- package/dist/routes/auth.js.map +1 -0
- package/dist/routes/capabilities.d.ts +14 -0
- package/dist/routes/capabilities.d.ts.map +1 -0
- package/dist/routes/capabilities.js +62 -0
- package/dist/routes/capabilities.js.map +1 -0
- package/dist/routes/compliance.d.ts +37 -0
- package/dist/routes/compliance.d.ts.map +1 -0
- package/dist/routes/compliance.js +321 -0
- package/dist/routes/compliance.js.map +1 -0
- package/dist/routes/conversations.d.ts +13 -0
- package/dist/routes/conversations.d.ts.map +1 -0
- package/dist/routes/conversations.js +295 -0
- package/dist/routes/conversations.js.map +1 -0
- package/dist/routes/cost.d.ts +24 -0
- package/dist/routes/cost.d.ts.map +1 -0
- package/dist/routes/cost.js +243 -0
- package/dist/routes/cost.js.map +1 -0
- package/dist/routes/deployments.d.ts +122 -0
- package/dist/routes/deployments.d.ts.map +1 -0
- package/dist/routes/deployments.js +1036 -0
- package/dist/routes/deployments.js.map +1 -0
- package/dist/routes/env.d.ts +62 -0
- package/dist/routes/env.d.ts.map +1 -0
- package/dist/routes/env.js +311 -0
- package/dist/routes/env.js.map +1 -0
- package/dist/routes/eval-runs.d.ts +28 -0
- package/dist/routes/eval-runs.d.ts.map +1 -0
- package/dist/routes/eval-runs.js +479 -0
- package/dist/routes/eval-runs.js.map +1 -0
- package/dist/routes/eval-suites.d.ts +24 -0
- package/dist/routes/eval-suites.d.ts.map +1 -0
- package/dist/routes/eval-suites.js +381 -0
- package/dist/routes/eval-suites.js.map +1 -0
- package/dist/routes/event-triggers.d.ts +12 -0
- package/dist/routes/event-triggers.d.ts.map +1 -0
- package/dist/routes/event-triggers.js +218 -0
- package/dist/routes/event-triggers.js.map +1 -0
- package/dist/routes/flows.d.ts +23 -0
- package/dist/routes/flows.d.ts.map +1 -0
- package/dist/routes/flows.js +344 -0
- package/dist/routes/flows.js.map +1 -0
- package/dist/routes/guardrails.d.ts +33 -0
- package/dist/routes/guardrails.d.ts.map +1 -0
- package/dist/routes/guardrails.js +236 -0
- package/dist/routes/guardrails.js.map +1 -0
- package/dist/routes/identity.d.ts +39 -0
- package/dist/routes/identity.d.ts.map +1 -0
- package/dist/routes/identity.js +138 -0
- package/dist/routes/identity.js.map +1 -0
- package/dist/routes/mcp.d.ts +23 -0
- package/dist/routes/mcp.d.ts.map +1 -0
- package/dist/routes/mcp.js +727 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/memory.d.ts +16 -0
- package/dist/routes/memory.d.ts.map +1 -0
- package/dist/routes/memory.js +353 -0
- package/dist/routes/memory.js.map +1 -0
- package/dist/routes/observations.d.ts +19 -0
- package/dist/routes/observations.d.ts.map +1 -0
- package/dist/routes/observations.js +135 -0
- package/dist/routes/observations.js.map +1 -0
- package/dist/routes/orgs.d.ts +24 -0
- package/dist/routes/orgs.d.ts.map +1 -0
- package/dist/routes/orgs.js +208 -0
- package/dist/routes/orgs.js.map +1 -0
- package/dist/routes/pagination.d.ts +18 -0
- package/dist/routes/pagination.d.ts.map +1 -0
- package/dist/routes/pagination.js +35 -0
- package/dist/routes/pagination.js.map +1 -0
- package/dist/routes/policies.d.ts +23 -0
- package/dist/routes/policies.d.ts.map +1 -0
- package/dist/routes/policies.js +314 -0
- package/dist/routes/policies.js.map +1 -0
- package/dist/routes/projects.d.ts +45 -0
- package/dist/routes/projects.d.ts.map +1 -0
- package/dist/routes/projects.js +485 -0
- package/dist/routes/projects.js.map +1 -0
- package/dist/routes/proposals.d.ts +24 -0
- package/dist/routes/proposals.d.ts.map +1 -0
- package/dist/routes/proposals.js +581 -0
- package/dist/routes/proposals.js.map +1 -0
- package/dist/routes/provenance.d.ts +34 -0
- package/dist/routes/provenance.d.ts.map +1 -0
- package/dist/routes/provenance.js +274 -0
- package/dist/routes/provenance.js.map +1 -0
- package/dist/routes/providers.d.ts +32 -0
- package/dist/routes/providers.d.ts.map +1 -0
- package/dist/routes/providers.js +490 -0
- package/dist/routes/providers.js.map +1 -0
- package/dist/routes/public-run-tokens.d.ts +17 -0
- package/dist/routes/public-run-tokens.d.ts.map +1 -0
- package/dist/routes/public-run-tokens.js +69 -0
- package/dist/routes/public-run-tokens.js.map +1 -0
- package/dist/routes/retention.d.ts +19 -0
- package/dist/routes/retention.d.ts.map +1 -0
- package/dist/routes/retention.js +152 -0
- package/dist/routes/retention.js.map +1 -0
- package/dist/routes/reviewers.d.ts +5 -0
- package/dist/routes/reviewers.d.ts.map +1 -0
- package/dist/routes/reviewers.js +161 -0
- package/dist/routes/reviewers.js.map +1 -0
- package/dist/routes/runs.d.ts +34 -0
- package/dist/routes/runs.d.ts.map +1 -0
- package/dist/routes/runs.js +773 -0
- package/dist/routes/runs.js.map +1 -0
- package/dist/routes/s3.d.ts +31 -0
- package/dist/routes/s3.d.ts.map +1 -0
- package/dist/routes/s3.js +433 -0
- package/dist/routes/s3.js.map +1 -0
- package/dist/routes/schedules.d.ts +20 -0
- package/dist/routes/schedules.d.ts.map +1 -0
- package/dist/routes/schedules.js +234 -0
- package/dist/routes/schedules.js.map +1 -0
- package/dist/routes/scope-params.d.ts +57 -0
- package/dist/routes/scope-params.d.ts.map +1 -0
- package/dist/routes/scope-params.js +105 -0
- package/dist/routes/scope-params.js.map +1 -0
- package/dist/routes/secret-ref.d.ts +20 -0
- package/dist/routes/secret-ref.d.ts.map +1 -0
- package/dist/routes/secret-ref.js +42 -0
- package/dist/routes/secret-ref.js.map +1 -0
- package/dist/routes/secrets.d.ts +53 -0
- package/dist/routes/secrets.d.ts.map +1 -0
- package/dist/routes/secrets.js +715 -0
- package/dist/routes/secrets.js.map +1 -0
- package/dist/routes/signing-keys.d.ts +23 -0
- package/dist/routes/signing-keys.d.ts.map +1 -0
- package/dist/routes/signing-keys.js +212 -0
- package/dist/routes/signing-keys.js.map +1 -0
- package/dist/routes/sse.d.ts +58 -0
- package/dist/routes/sse.d.ts.map +1 -0
- package/dist/routes/sse.js +92 -0
- package/dist/routes/sse.js.map +1 -0
- package/dist/routes/teams.d.ts +30 -0
- package/dist/routes/teams.d.ts.map +1 -0
- package/dist/routes/teams.js +443 -0
- package/dist/routes/teams.js.map +1 -0
- package/dist/routes/tenant.d.ts +57 -0
- package/dist/routes/tenant.d.ts.map +1 -0
- package/dist/routes/tenant.js +352 -0
- package/dist/routes/tenant.js.map +1 -0
- package/dist/routes/tokens.d.ts +14 -0
- package/dist/routes/tokens.d.ts.map +1 -0
- package/dist/routes/tokens.js +231 -0
- package/dist/routes/tokens.js.map +1 -0
- package/dist/routes/tools.d.ts +33 -0
- package/dist/routes/tools.d.ts.map +1 -0
- package/dist/routes/tools.js +380 -0
- package/dist/routes/tools.js.map +1 -0
- package/dist/routes/webhook-endpoints.d.ts +10 -0
- package/dist/routes/webhook-endpoints.d.ts.map +1 -0
- package/dist/routes/webhook-endpoints.js +407 -0
- package/dist/routes/webhook-endpoints.js.map +1 -0
- package/dist/routes/webhooks.d.ts +21 -0
- package/dist/routes/webhooks.d.ts.map +1 -0
- package/dist/routes/webhooks.js +228 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/s3-credential-binding.d.ts +54 -0
- package/dist/s3-credential-binding.d.ts.map +1 -0
- package/dist/s3-credential-binding.js +4 -0
- package/dist/s3-credential-binding.js.map +1 -0
- package/dist/secrets-binding.d.ts +281 -0
- package/dist/secrets-binding.d.ts.map +1 -0
- package/dist/secrets-binding.js +10 -0
- package/dist/secrets-binding.js.map +1 -0
- package/dist/secrets-provider-binding.d.ts +164 -0
- package/dist/secrets-provider-binding.d.ts.map +1 -0
- package/dist/secrets-provider-binding.js +4 -0
- package/dist/secrets-provider-binding.js.map +1 -0
- package/dist/session-store-binding.d.ts +148 -0
- package/dist/session-store-binding.d.ts.map +1 -0
- package/dist/session-store-binding.js +4 -0
- package/dist/session-store-binding.js.map +1 -0
- package/dist/signing-key-binding.d.ts +210 -0
- package/dist/signing-key-binding.d.ts.map +1 -0
- package/dist/signing-key-binding.js +4 -0
- package/dist/signing-key-binding.js.map +1 -0
- package/dist/state-store-binding.d.ts +53 -0
- package/dist/state-store-binding.d.ts.map +1 -0
- package/dist/state-store-binding.js +38 -0
- package/dist/state-store-binding.js.map +1 -0
- package/dist/supervisor-binding.d.ts +526 -0
- package/dist/supervisor-binding.d.ts.map +1 -0
- package/dist/supervisor-binding.js +4 -0
- package/dist/supervisor-binding.js.map +1 -0
- package/dist/tenant-host-access.d.ts +41 -0
- package/dist/tenant-host-access.d.ts.map +1 -0
- package/dist/tenant-host-access.js +42 -0
- package/dist/tenant-host-access.js.map +1 -0
- package/dist/token-admin.d.ts +99 -0
- package/dist/token-admin.d.ts.map +1 -0
- package/dist/token-admin.js +4 -0
- package/dist/token-admin.js.map +1 -0
- package/dist/tool-binding.d.ts +247 -0
- package/dist/tool-binding.d.ts.map +1 -0
- package/dist/tool-binding.js +4 -0
- package/dist/tool-binding.js.map +1 -0
- package/dist/trigger-binding.d.ts +13 -0
- package/dist/trigger-binding.d.ts.map +1 -0
- package/dist/trigger-binding.js +4 -0
- package/dist/trigger-binding.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/webhook-endpoint-binding.d.ts +230 -0
- package/dist/webhook-endpoint-binding.d.ts.map +1 -0
- package/dist/webhook-endpoint-binding.js +12 -0
- package/dist/webhook-endpoint-binding.js.map +1 -0
- package/dist/xml.d.ts +79 -0
- package/dist/xml.d.ts.map +1 -0
- package/dist/xml.js +115 -0
- package/dist/xml.js.map +1 -0
- package/openapi.json +29659 -0
- package/package.json +76 -4
- package/scripts/emit-openapi.mjs +44 -0
- package/src/adapter-binding.ts +204 -0
- package/src/agent-binding.ts +231 -0
- package/src/app.ts +1285 -0
- package/src/capability-binding.ts +83 -0
- package/src/cost-binding.ts +213 -0
- package/src/deployment-binding.ts +225 -0
- package/src/env-binding.ts +140 -0
- package/src/errors.ts +291 -0
- package/src/eval-run-binding.ts +209 -0
- package/src/eval-run-dispatcher.ts +497 -0
- package/src/eval-suite-binding.ts +257 -0
- package/src/event-bus-binding.ts +127 -0
- package/src/flow-binding.ts +213 -0
- package/src/guardrail-binding.ts +151 -0
- package/src/handler-binding.ts +132 -0
- package/src/hitl-binding.ts +172 -0
- package/src/identity-directory-binding.ts +128 -0
- package/src/identity-provider-binding.ts +203 -0
- package/src/image-registry-binding.ts +193 -0
- package/src/index.ts +606 -0
- package/src/key-management-binding.ts +91 -0
- package/src/mcp-endpoint-binding.ts +311 -0
- package/src/memory-binding.ts +239 -0
- package/src/middleware/auth.ts +437 -0
- package/src/middleware/authorize.ts +125 -0
- package/src/middleware/error-mapper.ts +37 -0
- package/src/middleware/idempotency.ts +160 -0
- package/src/middleware/principal.ts +64 -0
- package/src/middleware/public-run-routes.ts +50 -0
- package/src/middleware/request-id.ts +28 -0
- package/src/middleware/sigv4-verify.ts +374 -0
- package/src/middleware/sigv4.ts +165 -0
- package/src/openapi/generate.ts +307 -0
- package/src/openapi/operations.ts +5445 -0
- package/src/openapi/schemas.ts +6363 -0
- package/src/provenance-binding.ts +169 -0
- package/src/provider-binding.ts +196 -0
- package/src/public-run-token.ts +263 -0
- package/src/retention-binding.ts +78 -0
- package/src/reviewer-binding.ts +99 -0
- package/src/rotation-status-store.ts +209 -0
- package/src/routes/adapters.ts +319 -0
- package/src/routes/agents.ts +424 -0
- package/src/routes/approvals.ts +759 -0
- package/src/routes/artifacts.ts +317 -0
- package/src/routes/audit.ts +219 -0
- package/src/routes/auth.ts +806 -0
- package/src/routes/capabilities.ts +79 -0
- package/src/routes/compliance.ts +482 -0
- package/src/routes/conversations.ts +369 -0
- package/src/routes/cost.ts +327 -0
- package/src/routes/deployments.ts +1493 -0
- package/src/routes/env.ts +429 -0
- package/src/routes/eval-runs.ts +631 -0
- package/src/routes/eval-suites.ts +490 -0
- package/src/routes/event-triggers.ts +283 -0
- package/src/routes/flows.ts +423 -0
- package/src/routes/guardrails.ts +320 -0
- package/src/routes/identity.ts +203 -0
- package/src/routes/mcp.ts +940 -0
- package/src/routes/memory.ts +430 -0
- package/src/routes/observations.ts +175 -0
- package/src/routes/orgs.ts +273 -0
- package/src/routes/pagination.ts +51 -0
- package/src/routes/policies.ts +413 -0
- package/src/routes/projects.ts +634 -0
- package/src/routes/proposals.ts +719 -0
- package/src/routes/provenance.ts +406 -0
- package/src/routes/providers.ts +624 -0
- package/src/routes/public-run-tokens.ts +104 -0
- package/src/routes/retention.ts +193 -0
- package/src/routes/reviewers.ts +209 -0
- package/src/routes/runs.ts +981 -0
- package/src/routes/s3.ts +519 -0
- package/src/routes/schedules.ts +300 -0
- package/src/routes/scope-params.ts +133 -0
- package/src/routes/secret-ref.ts +52 -0
- package/src/routes/secrets.ts +975 -0
- package/src/routes/signing-keys.ts +259 -0
- package/src/routes/sse.ts +148 -0
- package/src/routes/teams.ts +584 -0
- package/src/routes/tenant.ts +530 -0
- package/src/routes/tokens.ts +285 -0
- package/src/routes/tools.ts +491 -0
- package/src/routes/webhook-endpoints.ts +534 -0
- package/src/routes/webhooks.ts +296 -0
- package/src/s3-credential-binding.ts +58 -0
- package/src/secrets-binding.ts +308 -0
- package/src/secrets-provider-binding.ts +167 -0
- package/src/session-store-binding.ts +163 -0
- package/src/signing-key-binding.ts +235 -0
- package/src/state-store-binding.ts +84 -0
- package/src/supervisor-binding.ts +554 -0
- package/src/tenant-host-access.ts +62 -0
- package/src/token-admin.ts +104 -0
- package/src/tool-binding.ts +274 -0
- package/src/trigger-binding.ts +38 -0
- package/src/types.ts +74 -0
- package/src/webhook-endpoint-binding.ts +246 -0
- package/src/xml.ts +196 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Context, MiddlewareHandler } from 'hono';
|
|
2
|
+
import { type Action, type AuthzCheckBinding, type Decision, type ResourceRef } from '@kindgi/authz';
|
|
3
|
+
import type { AppEnv } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Callback that produces the resource being acted upon from the Hono
|
|
6
|
+
* context. Called at request time — can read path params, query, or
|
|
7
|
+
* body (if already parsed).
|
|
8
|
+
*/
|
|
9
|
+
export type ResourceGetter = (c: Context<AppEnv>) => ResourceRef | Promise<ResourceRef>;
|
|
10
|
+
export interface Authorizer {
|
|
11
|
+
readonly authorize: (action: Action, getResource: ResourceGetter) => MiddlewareHandler<AppEnv>;
|
|
12
|
+
readonly can: (c: Context<AppEnv>, action: Action, resource: ResourceRef) => Promise<boolean>;
|
|
13
|
+
readonly check: (c: Context<AppEnv>, action: Action, resource: ResourceRef) => Promise<Decision>;
|
|
14
|
+
/**
|
|
15
|
+
* List-filtering helper — takes items + a ref-extractor and returns
|
|
16
|
+
* only those items where the principal has `action` on the derived
|
|
17
|
+
* resource. Preserves input order. Empty in → empty out.
|
|
18
|
+
*
|
|
19
|
+
* Use in GET-list route handlers after fetching tenant-scoped rows;
|
|
20
|
+
* strips rows the caller can't read so the response only includes
|
|
21
|
+
* what they'd be allowed to touch.
|
|
22
|
+
*/
|
|
23
|
+
readonly filterByCan: <T>(c: Context<AppEnv>, action: Action, items: readonly T[], refFn: (item: T) => ResourceRef) => Promise<T[]>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createAuthorizer(binding: AuthzCheckBinding): Authorizer;
|
|
26
|
+
//# sourceMappingURL=authorize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEvD,OAAO,EACL,KAAK,MAAM,EACX,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EAEb,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAExF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,KAAK,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC/F,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9F,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjG;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,EACtB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,WAAW,KAC5B,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAgEvE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { denyPayload, } from '@kindgi/authz';
|
|
4
|
+
export function createAuthorizer(binding) {
|
|
5
|
+
async function checkInternal(c, action, resource) {
|
|
6
|
+
const principal = c.get('principal');
|
|
7
|
+
if (principal === undefined) {
|
|
8
|
+
return {
|
|
9
|
+
allowed: false,
|
|
10
|
+
failing: 'actor',
|
|
11
|
+
reason: 'no principal on request (bearer/principal middleware did not run)',
|
|
12
|
+
evidence: {
|
|
13
|
+
action,
|
|
14
|
+
relation: '',
|
|
15
|
+
resource: `${resource.type}:${resource.id}`,
|
|
16
|
+
actorSubject: '',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const requestId = c.get('requestId');
|
|
21
|
+
const ctx = typeof requestId === 'string' && requestId.length > 0
|
|
22
|
+
? { correlationId: requestId }
|
|
23
|
+
: undefined;
|
|
24
|
+
return binding.check(principal, action, resource, ctx);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
check: checkInternal,
|
|
28
|
+
async can(c, action, resource) {
|
|
29
|
+
const d = await checkInternal(c, action, resource);
|
|
30
|
+
return d.allowed;
|
|
31
|
+
},
|
|
32
|
+
authorize(action, getResource) {
|
|
33
|
+
return async (c, next) => {
|
|
34
|
+
const resource = await getResource(c);
|
|
35
|
+
const decision = await checkInternal(c, action, resource);
|
|
36
|
+
if (!decision.allowed) {
|
|
37
|
+
const body = denyPayload(action, resource.type, resource.id, decision.reason);
|
|
38
|
+
c.status(403);
|
|
39
|
+
return c.json(body);
|
|
40
|
+
}
|
|
41
|
+
return next();
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
async filterByCan(c, action, items, refFn) {
|
|
45
|
+
if (items.length === 0)
|
|
46
|
+
return [];
|
|
47
|
+
const principal = c.get('principal');
|
|
48
|
+
if (principal === undefined)
|
|
49
|
+
return [];
|
|
50
|
+
const refs = items.map(refFn);
|
|
51
|
+
const requestId = c.get('requestId');
|
|
52
|
+
const ctx = typeof requestId === 'string' && requestId.length > 0
|
|
53
|
+
? { correlationId: requestId }
|
|
54
|
+
: undefined;
|
|
55
|
+
const decisions = await binding.checkBatch(principal, action, refs, ctx);
|
|
56
|
+
const out = [];
|
|
57
|
+
for (let i = 0; i < items.length; i++) {
|
|
58
|
+
if (decisions[i]?.allowed)
|
|
59
|
+
out.push(items[i]);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=authorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorize.js","sourceRoot":"","sources":["../../src/middleware/authorize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Top-level catch-all. Any uncaught exception is translated to a
|
|
4
|
+
* `500 internal-server-error` wire error. Domain errors returned via
|
|
5
|
+
* `Result<T, E>` are handled per-route — this middleware only catches
|
|
6
|
+
* thrown exceptions (framework bugs, DB failures without Result wrap,
|
|
7
|
+
* etc.).
|
|
8
|
+
*
|
|
9
|
+
* The requestId embedded in the response body matches
|
|
10
|
+
* `middleware/request-id.ts`, so a caller can correlate.
|
|
11
|
+
*/
|
|
12
|
+
export declare function errorMapperMiddleware(): MiddlewareHandler;
|
|
13
|
+
//# sourceMappingURL=error-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/middleware/error-mapper.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,iBAAiB,CAmBzD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { statusFor, toWireError } from '../errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Top-level catch-all. Any uncaught exception is translated to a
|
|
6
|
+
* `500 internal-server-error` wire error. Domain errors returned via
|
|
7
|
+
* `Result<T, E>` are handled per-route — this middleware only catches
|
|
8
|
+
* thrown exceptions (framework bugs, DB failures without Result wrap,
|
|
9
|
+
* etc.).
|
|
10
|
+
*
|
|
11
|
+
* The requestId embedded in the response body matches
|
|
12
|
+
* `middleware/request-id.ts`, so a caller can correlate.
|
|
13
|
+
*/
|
|
14
|
+
export function errorMapperMiddleware() {
|
|
15
|
+
return async (c, next) => {
|
|
16
|
+
try {
|
|
17
|
+
await next();
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
const requestId = c.get('requestId') ?? 'req-unknown';
|
|
22
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
23
|
+
const body = toWireError({
|
|
24
|
+
code: 'internal-server-error',
|
|
25
|
+
message: message.length > 0 ? message : 'Unhandled server error',
|
|
26
|
+
}, requestId);
|
|
27
|
+
c.status(statusFor('internal-server-error'));
|
|
28
|
+
return c.json(body);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=error-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.js","sourceRoot":"","sources":["../../src/middleware/error-mapper.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAIjC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,SAAS,GAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAwB,IAAI,aAAa,CAAC;YAC9E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,GAAG,WAAW,CACtB;gBACE,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB;aACjE,EACD,SAAS,CACV,CAAC;YACF,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAU,CAAC,CAAC;YACtD,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Idempotency-key store: `(tenantId, route, key) → cached response`,
|
|
4
|
+
* cached for `ttlMs` (default 24h per API-ROUTE-CONVENTIONS.md §3.1).
|
|
5
|
+
*
|
|
6
|
+
* Injected into the middleware so deployments can plug in a durable
|
|
7
|
+
* store (e.g. Postgres, Redis). The bundled `createInMemoryIdempotencyStore()`
|
|
8
|
+
* is fine for dev + tests; production installs are expected to plug
|
|
9
|
+
* in a persistent one so retries survive restarts.
|
|
10
|
+
*/
|
|
11
|
+
export interface IdempotencyStore {
|
|
12
|
+
get(key: string): Promise<StoredIdempotencyEntry | null>;
|
|
13
|
+
set(key: string, entry: StoredIdempotencyEntry): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export interface StoredIdempotencyEntry {
|
|
16
|
+
readonly bodyHash: string;
|
|
17
|
+
readonly status: number;
|
|
18
|
+
readonly contentType: string;
|
|
19
|
+
readonly bodyText: string;
|
|
20
|
+
readonly expiresAt: number;
|
|
21
|
+
}
|
|
22
|
+
/** Simple in-memory store with lazy expiry — swap for a DB store in prod. */
|
|
23
|
+
export declare function createInMemoryIdempotencyStore(): IdempotencyStore;
|
|
24
|
+
/**
|
|
25
|
+
* Idempotency-Key middleware per API-ROUTE-CONVENTIONS.md §3.1.
|
|
26
|
+
*
|
|
27
|
+
* Behaviour:
|
|
28
|
+
* - Only applies to mutating methods (POST/PUT/PATCH/DELETE).
|
|
29
|
+
* - No `Idempotency-Key` header → pass through.
|
|
30
|
+
* - Cached hit with matching body hash → replay stored response
|
|
31
|
+
* byte-identical (status, content-type, body).
|
|
32
|
+
* - Cached hit with different body hash → 409
|
|
33
|
+
* `idempotency-key-body-mismatch`.
|
|
34
|
+
* - Cache miss → run the handler, then store the response.
|
|
35
|
+
*
|
|
36
|
+
* The middleware sits AFTER auth so `tenantId` is available; the
|
|
37
|
+
* cache key is namespaced by tenant so callers can't collide across
|
|
38
|
+
* tenants.
|
|
39
|
+
*/
|
|
40
|
+
export declare function idempotencyMiddleware(store: IdempotencyStore, opts?: {
|
|
41
|
+
ttlMs?: number;
|
|
42
|
+
}): MiddlewareHandler;
|
|
43
|
+
//# sourceMappingURL=idempotency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/middleware/idempotency.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAM9C;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IACzD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,6EAA6E;AAC7E,wBAAgB,8BAA8B,IAAI,gBAAgB,CAgBjE;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5B,iBAAiB,CA6DnB"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { statusFor, toWireError } from '../errors.js';
|
|
5
|
+
/** Simple in-memory store with lazy expiry — swap for a DB store in prod. */
|
|
6
|
+
export function createInMemoryIdempotencyStore() {
|
|
7
|
+
const table = new Map();
|
|
8
|
+
return {
|
|
9
|
+
async get(key) {
|
|
10
|
+
const hit = table.get(key);
|
|
11
|
+
if (hit === undefined)
|
|
12
|
+
return null;
|
|
13
|
+
if (hit.expiresAt <= Date.now()) {
|
|
14
|
+
table.delete(key);
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return hit;
|
|
18
|
+
},
|
|
19
|
+
async set(key, entry) {
|
|
20
|
+
table.set(key, entry);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
|
|
25
|
+
const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
|
|
26
|
+
/**
|
|
27
|
+
* Idempotency-Key middleware per API-ROUTE-CONVENTIONS.md §3.1.
|
|
28
|
+
*
|
|
29
|
+
* Behaviour:
|
|
30
|
+
* - Only applies to mutating methods (POST/PUT/PATCH/DELETE).
|
|
31
|
+
* - No `Idempotency-Key` header → pass through.
|
|
32
|
+
* - Cached hit with matching body hash → replay stored response
|
|
33
|
+
* byte-identical (status, content-type, body).
|
|
34
|
+
* - Cached hit with different body hash → 409
|
|
35
|
+
* `idempotency-key-body-mismatch`.
|
|
36
|
+
* - Cache miss → run the handler, then store the response.
|
|
37
|
+
*
|
|
38
|
+
* The middleware sits AFTER auth so `tenantId` is available; the
|
|
39
|
+
* cache key is namespaced by tenant so callers can't collide across
|
|
40
|
+
* tenants.
|
|
41
|
+
*/
|
|
42
|
+
export function idempotencyMiddleware(store, opts = {}) {
|
|
43
|
+
const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
44
|
+
return async (c, next) => {
|
|
45
|
+
if (!MUTATING_METHODS.has(c.req.method.toUpperCase())) {
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
const rawKey = c.req.header('idempotency-key');
|
|
49
|
+
if (rawKey === undefined || rawKey.length === 0) {
|
|
50
|
+
return next();
|
|
51
|
+
}
|
|
52
|
+
const requestId = c.get('requestId');
|
|
53
|
+
const tenantId = c.get('tenantId');
|
|
54
|
+
if (tenantId === undefined) {
|
|
55
|
+
// Auth middleware didn't set it — bail out and let the auth
|
|
56
|
+
// failure surface. This shouldn't happen because auth runs
|
|
57
|
+
// first, but the guard keeps the cache key well-formed.
|
|
58
|
+
return next();
|
|
59
|
+
}
|
|
60
|
+
const bodyText = await readRawBody(c.req.raw);
|
|
61
|
+
const bodyHash = hashBody(bodyText);
|
|
62
|
+
const cacheKey = `${tenantId}|${c.req.method.toUpperCase()}:${c.req.path}|${rawKey}`;
|
|
63
|
+
const hit = await store.get(cacheKey);
|
|
64
|
+
if (hit !== null) {
|
|
65
|
+
if (hit.bodyHash !== bodyHash) {
|
|
66
|
+
c.status(statusFor('idempotency-key-body-mismatch'));
|
|
67
|
+
return c.json(toWireError({
|
|
68
|
+
code: 'idempotency-key-body-mismatch',
|
|
69
|
+
message: 'Idempotency-Key was reused with a different request body. Use a fresh key or the original body.',
|
|
70
|
+
}, requestId));
|
|
71
|
+
}
|
|
72
|
+
return c.body(hit.bodyText, hit.status, {
|
|
73
|
+
'Content-Type': hit.contentType,
|
|
74
|
+
'X-Idempotent-Replay': 'true',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Re-attach the buffered body so downstream handlers reading
|
|
78
|
+
// `c.req.json()` see the same bytes.
|
|
79
|
+
if (bodyText.length > 0)
|
|
80
|
+
rebindBody(c, bodyText);
|
|
81
|
+
await next();
|
|
82
|
+
const res = c.res;
|
|
83
|
+
const savedBody = await res.clone().text();
|
|
84
|
+
const contentType = res.headers.get('Content-Type') ?? 'application/octet-stream';
|
|
85
|
+
await store.set(cacheKey, {
|
|
86
|
+
bodyHash,
|
|
87
|
+
status: res.status,
|
|
88
|
+
contentType,
|
|
89
|
+
bodyText: savedBody,
|
|
90
|
+
expiresAt: Date.now() + ttlMs,
|
|
91
|
+
});
|
|
92
|
+
return;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
async function readRawBody(req) {
|
|
96
|
+
const method = req.method.toUpperCase();
|
|
97
|
+
if (method === 'GET' || method === 'HEAD')
|
|
98
|
+
return '';
|
|
99
|
+
try {
|
|
100
|
+
return await req.clone().text();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return '';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function hashBody(body) {
|
|
107
|
+
return createHash('sha256').update(body).digest('hex');
|
|
108
|
+
}
|
|
109
|
+
function rebindBody(c, body) {
|
|
110
|
+
const original = c.req.raw;
|
|
111
|
+
const rebuilt = new Request(original.url, {
|
|
112
|
+
method: original.method,
|
|
113
|
+
headers: original.headers,
|
|
114
|
+
body,
|
|
115
|
+
});
|
|
116
|
+
Object.defineProperty(c.req, 'raw', { value: rebuilt, configurable: true });
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=idempotency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/middleware/idempotency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../../src/middleware/principal.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAI9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,wBAAgB,mBAAmB,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAuC/D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { principalFromToken } from '@kindgi/authz';
|
|
4
|
+
export function principalMiddleware() {
|
|
5
|
+
return async (c, next) => {
|
|
6
|
+
const tenantId = c.get('tenantId');
|
|
7
|
+
const userId = c.get('userId');
|
|
8
|
+
const tokenId = c.get('tokenId');
|
|
9
|
+
const sessionId = c.get('sessionId');
|
|
10
|
+
if (tenantId === undefined) {
|
|
11
|
+
// Bearer middleware didn't populate — either the route is
|
|
12
|
+
// pre-auth (unlikely at this mount point) or the resolver
|
|
13
|
+
// failed silently. Skip; downstream authorize() will 403 in a
|
|
14
|
+
// coherent way if it needs the principal.
|
|
15
|
+
return next();
|
|
16
|
+
}
|
|
17
|
+
// A user when the token names one; otherwise a service account: a
|
|
18
|
+
// durable API key's id, or else the session id (which uniquely
|
|
19
|
+
// identifies the token record). With none of them, leave `principal`
|
|
20
|
+
// unset; `authorize()` treats that as "no principal" and 403s cleanly.
|
|
21
|
+
const serviceAccountId = tokenId ?? sessionId;
|
|
22
|
+
if (userId === undefined && serviceAccountId === undefined) {
|
|
23
|
+
return next();
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const principal = principalFromToken({
|
|
27
|
+
tenantId,
|
|
28
|
+
...(userId !== undefined ? { userId } : {}),
|
|
29
|
+
...(userId === undefined && serviceAccountId !== undefined
|
|
30
|
+
? { tokenId: serviceAccountId }
|
|
31
|
+
: {}),
|
|
32
|
+
});
|
|
33
|
+
c.set('principal', principal);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Defensive: principalFromToken throws when its guardrail is
|
|
37
|
+
// violated; downstream authorize() handles the missing principal.
|
|
38
|
+
}
|
|
39
|
+
return next();
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=principal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.js","sourceRoot":"","sources":["../../src/middleware/principal.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAmBjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAInD,MAAM,UAAU,mBAAmB;IACjC,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAErC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,0DAA0D;YAC1D,0DAA0D;YAC1D,8DAA8D;YAC9D,0CAA0C;YAC1C,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,kEAAkE;QAClE,+DAA+D;QAC/D,qEAAqE;QACrE,uEAAuE;QACvE,MAAM,gBAAgB,GACnB,OAAyC,IAAK,SAA2C,CAAC;QAC7F,IAAI,MAAM,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,kBAAkB,CAAC;gBACnC,QAAQ;gBACR,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3C,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS;oBACxD,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE;oBAC/B,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;YACH,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,kEAAkE;QACpE,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* The routes a public run token may call: the operations registered with
|
|
4
|
+
* `security: 'bearer-or-public-run'`. Deriving the list from the
|
|
5
|
+
* operation registry keeps the middleware, the OpenAPI document and the
|
|
6
|
+
* routes in step.
|
|
7
|
+
*/
|
|
8
|
+
export declare function publicRunRouteMatcher(): (method: string, path: string) => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* CORS for the public-run-token routes only, so a browser on one of
|
|
11
|
+
* `allowedOrigins` can call them with a public token. Every other route
|
|
12
|
+
* gets no CORS headers: secret API tokens stay server-side. Registered
|
|
13
|
+
* ahead of authentication, so preflights don't need a token.
|
|
14
|
+
*/
|
|
15
|
+
export declare function publicRunCorsMiddleware(allowedOrigins: readonly string[]): MiddlewareHandler;
|
|
16
|
+
//# sourceMappingURL=public-run-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-run-routes.d.ts","sourceRoot":"","sources":["../../src/middleware/public-run-routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAK9C;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CASjF;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAkB5F"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { cors } from 'hono/cors';
|
|
4
|
+
import { OPERATIONS } from '../openapi/operations.js';
|
|
5
|
+
/**
|
|
6
|
+
* The routes a public run token may call: the operations registered with
|
|
7
|
+
* `security: 'bearer-or-public-run'`. Deriving the list from the
|
|
8
|
+
* operation registry keeps the middleware, the OpenAPI document and the
|
|
9
|
+
* routes in step.
|
|
10
|
+
*/
|
|
11
|
+
export function publicRunRouteMatcher() {
|
|
12
|
+
const routes = OPERATIONS.filter((op) => op.security === 'bearer-or-public-run').map((op) => ({
|
|
13
|
+
method: op.method.toUpperCase(),
|
|
14
|
+
pattern: new RegExp(`^${op.honoPath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/:[A-Za-z][A-Za-z0-9_]*/g, '[^/]+')}$`),
|
|
15
|
+
}));
|
|
16
|
+
return (method, path) => routes.some((route) => route.method === method && route.pattern.test(path));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* CORS for the public-run-token routes only, so a browser on one of
|
|
20
|
+
* `allowedOrigins` can call them with a public token. Every other route
|
|
21
|
+
* gets no CORS headers: secret API tokens stay server-side. Registered
|
|
22
|
+
* ahead of authentication, so preflights don't need a token.
|
|
23
|
+
*/
|
|
24
|
+
export function publicRunCorsMiddleware(allowedOrigins) {
|
|
25
|
+
const matchesPath = publicRunRouteMatcher();
|
|
26
|
+
const handler = cors({
|
|
27
|
+
origin: [...allowedOrigins],
|
|
28
|
+
allowMethods: ['GET'],
|
|
29
|
+
allowHeaders: ['Authorization', 'Last-Event-ID'],
|
|
30
|
+
exposeHeaders: ['X-Request-Id'],
|
|
31
|
+
maxAge: 600,
|
|
32
|
+
});
|
|
33
|
+
return async (c, next) => {
|
|
34
|
+
// A preflight asks about the method it will use; match on that.
|
|
35
|
+
const method = c.req.method === 'OPTIONS'
|
|
36
|
+
? (c.req.header('access-control-request-method') ?? '').toUpperCase()
|
|
37
|
+
: c.req.method;
|
|
38
|
+
if (!matchesPath(method, c.req.path))
|
|
39
|
+
return next();
|
|
40
|
+
return handler(c, next);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=public-run-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-run-routes.js","sourceRoot":"","sources":["../../src/middleware/public-run-routes.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAGjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,KAAK,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5F,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE;QAC/B,OAAO,EAAE,IAAI,MAAM,CACjB,IAAI,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,OAAO,CAAC,GAAG,CACtG;KACF,CAAC,CAAC,CAAC;IACJ,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CACtB,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,cAAiC;IACvE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC;QACnB,MAAM,EAAE,CAAC,GAAG,cAAc,CAAC;QAC3B,YAAY,EAAE,CAAC,KAAK,CAAC;QACrB,YAAY,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;QAChD,aAAa,EAAE,CAAC,cAAc,CAAC;QAC/B,MAAM,EAAE,GAAG;KACZ,CAAC,CAAC;IACH,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,gEAAgE;QAChE,MAAM,MAAM,GACV,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS;YACxB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,+BAA+B,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE;YACrE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;QACnB,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Assigns a request id to every incoming request. Stored on the Hono
|
|
4
|
+
* context as `c.get('requestId')`. Every error envelope embeds this so
|
|
5
|
+
* a caller reporting a bug can hand us one string to grep the logs.
|
|
6
|
+
*
|
|
7
|
+
* If the client provided `X-Request-Id`, we honor it (matching a
|
|
8
|
+
* caller-supplied id makes SDK retries observable in server logs).
|
|
9
|
+
* Otherwise we mint a new UUID.
|
|
10
|
+
*
|
|
11
|
+
* The response header `X-Request-Id` mirrors the id back.
|
|
12
|
+
*/
|
|
13
|
+
export declare function requestIdMiddleware(): MiddlewareHandler;
|
|
14
|
+
//# sourceMappingURL=request-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,iBAAiB,CASvD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright (C) 2026 Kindgi Inc.
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
/**
|
|
5
|
+
* Assigns a request id to every incoming request. Stored on the Hono
|
|
6
|
+
* context as `c.get('requestId')`. Every error envelope embeds this so
|
|
7
|
+
* a caller reporting a bug can hand us one string to grep the logs.
|
|
8
|
+
*
|
|
9
|
+
* If the client provided `X-Request-Id`, we honor it (matching a
|
|
10
|
+
* caller-supplied id makes SDK retries observable in server logs).
|
|
11
|
+
* Otherwise we mint a new UUID.
|
|
12
|
+
*
|
|
13
|
+
* The response header `X-Request-Id` mirrors the id back.
|
|
14
|
+
*/
|
|
15
|
+
export function requestIdMiddleware() {
|
|
16
|
+
return async (c, next) => {
|
|
17
|
+
const provided = c.req.header('x-request-id');
|
|
18
|
+
const requestId = provided !== undefined && provided.length > 0 ? provided : `req-${randomUUID()}`;
|
|
19
|
+
c.set('requestId', requestId);
|
|
20
|
+
await next();
|
|
21
|
+
c.header('X-Request-Id', requestId);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=request-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,SAAS,GACb,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,EAAE,CAAC;QACnF,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAC9B,MAAM,IAAI,EAAE,CAAC;QACb,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** S3's allowed clock skew for signed requests (15 minutes). */
|
|
2
|
+
export declare const MAX_CLOCK_SKEW_SECONDS: number;
|
|
3
|
+
/** S3's maximum presigned-URL lifetime (7 days). */
|
|
4
|
+
export declare const MAX_PRESIGN_EXPIRES_SECONDS: number;
|
|
5
|
+
export interface SigV4Error {
|
|
6
|
+
/** S3 error code. */
|
|
7
|
+
readonly code: string;
|
|
8
|
+
readonly message: string;
|
|
9
|
+
readonly status: 400 | 403;
|
|
10
|
+
}
|
|
11
|
+
export type SigV4Result<T> = {
|
|
12
|
+
readonly kind: 'ok';
|
|
13
|
+
readonly value: T;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'err';
|
|
16
|
+
readonly error: SigV4Error;
|
|
17
|
+
};
|
|
18
|
+
/** What a request claims about its signature, before verification. */
|
|
19
|
+
export interface SigV4Claim {
|
|
20
|
+
readonly kind: 'header' | 'presigned';
|
|
21
|
+
readonly accessKeyId: string;
|
|
22
|
+
/** Credential-scope date, `YYYYMMDD`. */
|
|
23
|
+
readonly scopeDate: string;
|
|
24
|
+
readonly region: string;
|
|
25
|
+
readonly service: string;
|
|
26
|
+
/** Lowercase header names, as the client listed them. */
|
|
27
|
+
readonly signedHeaders: readonly string[];
|
|
28
|
+
readonly signature: string;
|
|
29
|
+
/** `YYYYMMDDTHHMMSSZ`. */
|
|
30
|
+
readonly amzDate: string;
|
|
31
|
+
/** Presigned only: `X-Amz-Expires`, seconds. */
|
|
32
|
+
readonly expiresSeconds?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface SigV4Request {
|
|
35
|
+
readonly method: string;
|
|
36
|
+
/** The request URL as received (pathname still percent-encoded). */
|
|
37
|
+
readonly url: URL;
|
|
38
|
+
readonly headers: Headers;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse the signature claim from the `Authorization` header or the
|
|
42
|
+
* presigned-URL query parameters. Does not verify anything.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseSigV4(request: SigV4Request): SigV4Result<SigV4Claim>;
|
|
45
|
+
/**
|
|
46
|
+
* Check the claim's timestamp and shape against the server clock:
|
|
47
|
+
* `X-Amz-Date` well-formed and consistent with the credential scope,
|
|
48
|
+
* within {@link MAX_CLOCK_SKEW_SECONDS} (header auth / presigned not
|
|
49
|
+
* dated in the future), and — presigned — not expired. Also checks the
|
|
50
|
+
* signed-header list is sorted, lowercase, and covers what must be
|
|
51
|
+
* signed.
|
|
52
|
+
*/
|
|
53
|
+
export declare function checkSigV4Claim(claim: SigV4Claim, now: Date): SigV4Result<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Re-derive the signature from exactly what the client signed and compare
|
|
56
|
+
* it (constant-time) with the claimed one. `payloadHash` is the header
|
|
57
|
+
* `x-amz-content-sha256` for header auth (the caller verifies it against
|
|
58
|
+
* the body); presigned requests always sign `UNSIGNED-PAYLOAD`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function verifySigV4Signature(request: SigV4Request, claim: SigV4Claim, secretKey: string): SigV4Result<void>;
|
|
61
|
+
/** The SigV4 canonical request (exported for tests). */
|
|
62
|
+
export declare function canonicalRequest(request: SigV4Request, claim: SigV4Claim): SigV4Result<string>;
|
|
63
|
+
export declare function constantTimeEqual(a: string, b: string): boolean;
|
|
64
|
+
//# sourceMappingURL=sigv4-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigv4-verify.d.ts","sourceRoot":"","sources":["../../src/middleware/sigv4-verify.ts"],"names":[],"mappings":"AA0BA,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,QAAU,CAAC;AAC9C,oDAAoD;AACpD,eAAO,MAAM,2BAA2B,QAAmB,CAAC;AAM5D,MAAM,WAAW,UAAU;IACzB,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;CAC5B;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC1C;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzD,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0BAA0B;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAMD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,CAmFzE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CA0C/E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GAChB,WAAW,CAAC,IAAI,CAAC,CAkBnB;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CA+B9F;AA2FD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAK/D"}
|