@mesh-tech/mesh-cli 0.1.0 → 0.12.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/assets/intent/agents-fence.md +10 -0
- package/assets/intent/intent-claude-gate.mjs +255 -0
- package/assets/log-shipper.mjs +94 -0
- package/bin/mesh.mjs +80 -0
- package/dist/bin/mesh.d.ts +7 -9
- package/dist/bin/mesh.d.ts.map +1 -1
- package/dist/bin/mesh.js +20826 -37
- package/dist/bin/mesh.js.map +7 -1
- package/dist/build-info.json +4 -0
- package/dist/src/commands/agent-api-client.d.ts +79 -0
- package/dist/src/commands/agent-api-client.d.ts.map +1 -0
- package/dist/src/commands/agent-api-client.js +170 -0
- package/dist/src/commands/agent-api-client.js.map +1 -0
- package/dist/src/commands/artifacts.d.ts +13 -0
- package/dist/src/commands/artifacts.d.ts.map +1 -0
- package/dist/src/commands/artifacts.js +140 -0
- package/dist/src/commands/artifacts.js.map +1 -0
- package/dist/src/commands/cluster.d.ts +45 -0
- package/dist/src/commands/cluster.d.ts.map +1 -0
- package/dist/src/commands/cluster.js +259 -0
- package/dist/src/commands/cluster.js.map +1 -0
- package/dist/src/commands/conversations.d.ts +61 -0
- package/dist/src/commands/conversations.d.ts.map +1 -0
- package/dist/src/commands/conversations.js +239 -0
- package/dist/src/commands/conversations.js.map +1 -0
- package/dist/src/commands/create-app.d.ts +26 -3
- package/dist/src/commands/create-app.d.ts.map +1 -1
- package/dist/src/commands/create-app.js +465 -107
- package/dist/src/commands/create-app.js.map +1 -1
- package/dist/src/commands/deploy.d.ts +19 -0
- package/dist/src/commands/deploy.d.ts.map +1 -1
- package/dist/src/commands/deploy.js +83 -142
- package/dist/src/commands/deploy.js.map +1 -1
- package/dist/src/commands/dev-doctor.d.ts +137 -0
- package/dist/src/commands/dev-doctor.d.ts.map +1 -0
- package/dist/src/commands/dev-doctor.js +671 -0
- package/dist/src/commands/dev-doctor.js.map +1 -0
- package/dist/src/commands/dev-launch.d.ts +59 -0
- package/dist/src/commands/dev-launch.d.ts.map +1 -0
- package/dist/src/commands/dev-launch.js +118 -0
- package/dist/src/commands/dev-launch.js.map +1 -0
- package/dist/src/commands/dev-token-server.d.ts +32 -0
- package/dist/src/commands/dev-token-server.d.ts.map +1 -0
- package/dist/src/commands/dev-token-server.js +68 -0
- package/dist/src/commands/dev-token-server.js.map +1 -0
- package/dist/src/commands/dev.d.ts +289 -2
- package/dist/src/commands/dev.d.ts.map +1 -1
- package/dist/src/commands/dev.js +2501 -574
- package/dist/src/commands/dev.js.map +1 -1
- package/dist/src/commands/docs.d.ts +3 -0
- package/dist/src/commands/docs.d.ts.map +1 -0
- package/dist/src/commands/docs.js +262 -0
- package/dist/src/commands/docs.js.map +1 -0
- package/dist/src/commands/hub/index.d.ts +99 -0
- package/dist/src/commands/hub/index.d.ts.map +1 -0
- package/dist/src/commands/hub/index.js +452 -0
- package/dist/src/commands/hub/index.js.map +1 -0
- package/dist/src/commands/init.d.ts +65 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +370 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/install-shim.d.ts +21 -0
- package/dist/src/commands/install-shim.d.ts.map +1 -0
- package/dist/src/commands/install-shim.js +132 -0
- package/dist/src/commands/install-shim.js.map +1 -0
- package/dist/src/commands/local/auth-provision.d.ts +71 -0
- package/dist/src/commands/local/auth-provision.d.ts.map +1 -0
- package/dist/src/commands/local/auth-provision.js +286 -0
- package/dist/src/commands/local/auth-provision.js.map +1 -0
- package/dist/src/commands/local/dev-local.d.ts +97 -0
- package/dist/src/commands/local/dev-local.d.ts.map +1 -0
- package/dist/src/commands/local/dev-local.js +306 -0
- package/dist/src/commands/local/dev-local.js.map +1 -0
- package/dist/src/commands/local/docker-runner.d.ts +37 -0
- package/dist/src/commands/local/docker-runner.d.ts.map +1 -0
- package/dist/src/commands/local/docker-runner.js +104 -0
- package/dist/src/commands/local/docker-runner.js.map +1 -0
- package/dist/src/commands/local/helpers.d.ts +22 -0
- package/dist/src/commands/local/helpers.d.ts.map +1 -0
- package/dist/src/commands/local/helpers.js +46 -0
- package/dist/src/commands/local/helpers.js.map +1 -0
- package/dist/src/commands/local/hub-local.d.ts +51 -0
- package/dist/src/commands/local/hub-local.d.ts.map +1 -0
- package/dist/src/commands/local/hub-local.js +197 -0
- package/dist/src/commands/local/hub-local.js.map +1 -0
- package/dist/src/commands/local/index.d.ts +23 -0
- package/dist/src/commands/local/index.d.ts.map +1 -0
- package/dist/src/commands/local/index.js +386 -0
- package/dist/src/commands/local/index.js.map +1 -0
- package/dist/src/commands/local/mocks.d.ts +361 -0
- package/dist/src/commands/local/mocks.d.ts.map +1 -0
- package/dist/src/commands/local/mocks.js +756 -0
- package/dist/src/commands/local/mocks.js.map +1 -0
- package/dist/src/commands/local/seed-zitadel.d.ts +151 -0
- package/dist/src/commands/local/seed-zitadel.d.ts.map +1 -0
- package/dist/src/commands/local/seed-zitadel.js +408 -0
- package/dist/src/commands/local/seed-zitadel.js.map +1 -0
- package/dist/src/commands/local/seed.d.ts +106 -0
- package/dist/src/commands/local/seed.d.ts.map +1 -0
- package/dist/src/commands/local/seed.js +252 -0
- package/dist/src/commands/local/seed.js.map +1 -0
- package/dist/src/commands/local/stack.d.ts +173 -0
- package/dist/src/commands/local/stack.d.ts.map +1 -0
- package/dist/src/commands/local/stack.js +499 -0
- package/dist/src/commands/local/stack.js.map +1 -0
- package/dist/src/commands/login.d.ts +256 -12
- package/dist/src/commands/login.d.ts.map +1 -1
- package/dist/src/commands/login.js +978 -50
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/peer-addressing.d.ts +51 -0
- package/dist/src/commands/peer-addressing.d.ts.map +1 -0
- package/dist/src/commands/peer-addressing.js +64 -0
- package/dist/src/commands/peer-addressing.js.map +1 -0
- package/dist/src/commands/port-ownership.d.ts +69 -0
- package/dist/src/commands/port-ownership.d.ts.map +1 -0
- package/dist/src/commands/port-ownership.js +161 -0
- package/dist/src/commands/port-ownership.js.map +1 -0
- package/dist/src/commands/registry-publish.d.ts +3 -0
- package/dist/src/commands/registry-publish.d.ts.map +1 -0
- package/dist/src/commands/registry-publish.js +161 -0
- package/dist/src/commands/registry-publish.js.map +1 -0
- package/dist/src/commands/registry.d.ts +146 -2
- package/dist/src/commands/registry.d.ts.map +1 -1
- package/dist/src/commands/registry.js +541 -85
- package/dist/src/commands/registry.js.map +1 -1
- package/dist/src/commands/secrets/index.d.ts.map +1 -1
- package/dist/src/commands/secrets/index.js +15 -1
- package/dist/src/commands/secrets/index.js.map +1 -1
- package/dist/src/commands/secrets/migrate-config.d.ts +24 -0
- package/dist/src/commands/secrets/migrate-config.d.ts.map +1 -0
- package/dist/src/commands/secrets/migrate-config.js +277 -0
- package/dist/src/commands/secrets/migrate-config.js.map +1 -0
- package/dist/src/commands/secrets/set.d.ts +4 -0
- package/dist/src/commands/secrets/set.d.ts.map +1 -1
- package/dist/src/commands/secrets/set.js +243 -64
- package/dist/src/commands/secrets/set.js.map +1 -1
- package/dist/src/commands/skills.d.ts +34 -0
- package/dist/src/commands/skills.d.ts.map +1 -0
- package/dist/src/commands/skills.js +207 -0
- package/dist/src/commands/skills.js.map +1 -0
- package/dist/src/commands/stack.d.ts.map +1 -1
- package/dist/src/commands/stack.js +361 -23
- package/dist/src/commands/stack.js.map +1 -1
- package/dist/src/commands/temporal.d.ts +15 -0
- package/dist/src/commands/temporal.d.ts.map +1 -0
- package/dist/src/commands/temporal.js +781 -0
- package/dist/src/commands/temporal.js.map +1 -0
- package/dist/src/commands/tenant.d.ts +56 -0
- package/dist/src/commands/tenant.d.ts.map +1 -0
- package/dist/src/commands/tenant.js +233 -0
- package/dist/src/commands/tenant.js.map +1 -0
- package/dist/src/commands/tunnel/index.d.ts +49 -3
- package/dist/src/commands/tunnel/index.d.ts.map +1 -1
- package/dist/src/commands/tunnel/index.js +331 -8
- package/dist/src/commands/tunnel/index.js.map +1 -1
- package/dist/src/commands/vcs/clone.d.ts +3 -0
- package/dist/src/commands/vcs/clone.d.ts.map +1 -0
- package/dist/src/commands/vcs/clone.js +20 -0
- package/dist/src/commands/vcs/clone.js.map +1 -0
- package/dist/src/commands/vcs/common.d.ts +21 -0
- package/dist/src/commands/vcs/common.d.ts.map +1 -0
- package/dist/src/commands/vcs/common.js +62 -0
- package/dist/src/commands/vcs/common.js.map +1 -0
- package/dist/src/commands/vcs/drafts.d.ts +13 -0
- package/dist/src/commands/vcs/drafts.d.ts.map +1 -0
- package/dist/src/commands/vcs/drafts.js +45 -0
- package/dist/src/commands/vcs/drafts.js.map +1 -0
- package/dist/src/commands/vcs/get.d.ts +8 -0
- package/dist/src/commands/vcs/get.d.ts.map +1 -0
- package/dist/src/commands/vcs/get.js +61 -0
- package/dist/src/commands/vcs/get.js.map +1 -0
- package/dist/src/commands/vcs/index.d.ts +3 -0
- package/dist/src/commands/vcs/index.d.ts.map +1 -0
- package/dist/src/commands/vcs/index.js +58 -0
- package/dist/src/commands/vcs/index.js.map +1 -0
- package/dist/src/commands/vcs/propose.d.ts +23 -0
- package/dist/src/commands/vcs/propose.d.ts.map +1 -0
- package/dist/src/commands/vcs/propose.js +94 -0
- package/dist/src/commands/vcs/propose.js.map +1 -0
- package/dist/src/commands/vcs/review.d.ts +15 -0
- package/dist/src/commands/vcs/review.d.ts.map +1 -0
- package/dist/src/commands/vcs/review.js +35 -0
- package/dist/src/commands/vcs/review.js.map +1 -0
- package/dist/src/commands/vcs-enrich.d.ts +15 -0
- package/dist/src/commands/vcs-enrich.d.ts.map +1 -0
- package/dist/src/commands/vcs-enrich.js +28 -0
- package/dist/src/commands/vcs-enrich.js.map +1 -0
- package/dist/src/commands/vpn/index.d.ts +24 -0
- package/dist/src/commands/vpn/index.d.ts.map +1 -0
- package/dist/src/commands/vpn/index.js +543 -0
- package/dist/src/commands/vpn/index.js.map +1 -0
- package/dist/src/commands/vpn/tunnel.d.ts +11 -0
- package/dist/src/commands/vpn/tunnel.d.ts.map +1 -0
- package/dist/src/commands/vpn/tunnel.js +188 -0
- package/dist/src/commands/vpn/tunnel.js.map +1 -0
- package/dist/src/commands/workflow.d.ts +24 -0
- package/dist/src/commands/workflow.d.ts.map +1 -0
- package/dist/src/commands/workflow.js +577 -0
- package/dist/src/commands/workflow.js.map +1 -0
- package/dist/src/docs/assemble.d.ts +217 -0
- package/dist/src/docs/assemble.d.ts.map +1 -0
- package/dist/src/docs/assemble.js +739 -0
- package/dist/src/docs/assemble.js.map +1 -0
- package/dist/src/docs/cli-reference.d.ts +93 -0
- package/dist/src/docs/cli-reference.d.ts.map +1 -0
- package/dist/src/docs/cli-reference.js +256 -0
- package/dist/src/docs/cli-reference.js.map +1 -0
- package/dist/src/docs/discover.d.ts +60 -0
- package/dist/src/docs/discover.d.ts.map +1 -0
- package/dist/src/docs/discover.js +233 -0
- package/dist/src/docs/discover.js.map +1 -0
- package/dist/src/docs/portal.d.ts +79 -0
- package/dist/src/docs/portal.d.ts.map +1 -0
- package/dist/src/docs/portal.js +242 -0
- package/dist/src/docs/portal.js.map +1 -0
- package/dist/src/docs/registry-docs.d.ts +43 -0
- package/dist/src/docs/registry-docs.d.ts.map +1 -0
- package/dist/src/docs/registry-docs.js +138 -0
- package/dist/src/docs/registry-docs.js.map +1 -0
- package/dist/src/docs/schema.d.ts +48 -0
- package/dist/src/docs/schema.d.ts.map +1 -0
- package/dist/src/docs/schema.js +96 -0
- package/dist/src/docs/schema.js.map +1 -0
- package/dist/src/docs/serve.d.ts +27 -0
- package/dist/src/docs/serve.d.ts.map +1 -0
- package/dist/src/docs/serve.js +102 -0
- package/dist/src/docs/serve.js.map +1 -0
- package/dist/src/docs/start.d.ts +80 -0
- package/dist/src/docs/start.d.ts.map +1 -0
- package/dist/src/docs/start.js +313 -0
- package/dist/src/docs/start.js.map +1 -0
- package/dist/src/eval/agent-eval.d.mts +14 -0
- package/dist/src/eval/agent-eval.d.mts.map +1 -0
- package/dist/src/eval/agent-eval.mjs +273 -0
- package/dist/src/eval/agent-eval.mjs.map +1 -0
- package/dist/src/index.js +624 -7
- package/dist/src/index.js.map +7 -1
- package/dist/src/program.d.ts +26 -0
- package/dist/src/program.d.ts.map +1 -0
- package/dist/src/program.js +76 -0
- package/dist/src/program.js.map +1 -0
- package/dist/src/utils/auth-preflight.d.ts +159 -0
- package/dist/src/utils/auth-preflight.d.ts.map +1 -0
- package/dist/src/utils/auth-preflight.js +298 -0
- package/dist/src/utils/auth-preflight.js.map +1 -0
- package/dist/src/utils/aws-auth.d.ts +181 -0
- package/dist/src/utils/aws-auth.d.ts.map +1 -0
- package/dist/src/utils/aws-auth.js +527 -0
- package/dist/src/utils/aws-auth.js.map +1 -0
- package/dist/src/utils/bastion.d.ts +1 -1
- package/dist/src/utils/bastion.d.ts.map +1 -1
- package/dist/src/utils/bastion.js +29 -8
- package/dist/src/utils/bastion.js.map +1 -1
- package/dist/src/utils/build-info.d.ts +33 -0
- package/dist/src/utils/build-info.d.ts.map +1 -0
- package/dist/src/utils/build-info.js +102 -0
- package/dist/src/utils/build-info.js.map +1 -0
- package/dist/src/utils/capture-history.d.ts +62 -0
- package/dist/src/utils/capture-history.d.ts.map +1 -0
- package/dist/src/utils/capture-history.js +94 -0
- package/dist/src/utils/capture-history.js.map +1 -0
- package/dist/src/utils/deploy-preflight.d.ts +52 -0
- package/dist/src/utils/deploy-preflight.d.ts.map +1 -0
- package/dist/src/utils/deploy-preflight.js +183 -0
- package/dist/src/utils/deploy-preflight.js.map +1 -0
- package/dist/src/utils/errors.d.ts +75 -0
- package/dist/src/utils/errors.d.ts.map +1 -0
- package/dist/src/utils/errors.js +106 -0
- package/dist/src/utils/errors.js.map +1 -0
- package/dist/src/utils/first-party-contexts.d.ts +40 -0
- package/dist/src/utils/first-party-contexts.d.ts.map +1 -0
- package/dist/src/utils/first-party-contexts.js +53 -0
- package/dist/src/utils/first-party-contexts.js.map +1 -0
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +2 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/kubeconfig.d.ts +62 -0
- package/dist/src/utils/kubeconfig.d.ts.map +1 -0
- package/dist/src/utils/kubeconfig.js +118 -0
- package/dist/src/utils/kubeconfig.js.map +1 -0
- package/dist/src/utils/log.d.ts +27 -1
- package/dist/src/utils/log.d.ts.map +1 -1
- package/dist/src/utils/log.js +59 -5
- package/dist/src/utils/log.js.map +1 -1
- package/dist/src/utils/pid.d.ts +47 -0
- package/dist/src/utils/pid.d.ts.map +1 -0
- package/dist/src/utils/pid.js +83 -0
- package/dist/src/utils/pid.js.map +1 -0
- package/dist/src/utils/pulumi-run.d.ts +23 -0
- package/dist/src/utils/pulumi-run.d.ts.map +1 -0
- package/dist/src/utils/pulumi-run.js +112 -0
- package/dist/src/utils/pulumi-run.js.map +1 -0
- package/dist/src/utils/pulumi.d.ts +15 -0
- package/dist/src/utils/pulumi.d.ts.map +1 -1
- package/dist/src/utils/pulumi.js +35 -0
- package/dist/src/utils/pulumi.js.map +1 -1
- package/dist/src/utils/reachability.d.ts +29 -0
- package/dist/src/utils/reachability.d.ts.map +1 -0
- package/dist/src/utils/reachability.js +81 -0
- package/dist/src/utils/reachability.js.map +1 -0
- package/dist/src/utils/recover-conversation.d.ts +154 -0
- package/dist/src/utils/recover-conversation.d.ts.map +1 -0
- package/dist/src/utils/recover-conversation.js +314 -0
- package/dist/src/utils/recover-conversation.js.map +1 -0
- package/dist/src/utils/registry-broker.d.ts +148 -0
- package/dist/src/utils/registry-broker.d.ts.map +1 -0
- package/dist/src/utils/registry-broker.js +180 -0
- package/dist/src/utils/registry-broker.js.map +1 -0
- package/dist/src/utils/socks-forward.d.ts +40 -0
- package/dist/src/utils/socks-forward.d.ts.map +1 -0
- package/dist/src/utils/socks-forward.js +97 -0
- package/dist/src/utils/socks-forward.js.map +1 -0
- package/dist/src/utils/stack-flag.d.ts +23 -0
- package/dist/src/utils/stack-flag.d.ts.map +1 -0
- package/dist/src/utils/stack-flag.js +41 -0
- package/dist/src/utils/stack-flag.js.map +1 -0
- package/dist/src/utils/tailscale-targets.d.ts +52 -0
- package/dist/src/utils/tailscale-targets.d.ts.map +1 -0
- package/dist/src/utils/tailscale-targets.js +93 -0
- package/dist/src/utils/tailscale-targets.js.map +1 -0
- package/dist/src/utils/tailscale.d.ts +277 -0
- package/dist/src/utils/tailscale.d.ts.map +1 -0
- package/dist/src/utils/tailscale.js +1007 -0
- package/dist/src/utils/tailscale.js.map +1 -0
- package/dist/src/utils/temporal-auth.d.ts +43 -0
- package/dist/src/utils/temporal-auth.d.ts.map +1 -0
- package/dist/src/utils/temporal-auth.js +176 -0
- package/dist/src/utils/temporal-auth.js.map +1 -0
- package/dist/src/utils/temporal-codec.d.ts +101 -0
- package/dist/src/utils/temporal-codec.d.ts.map +1 -0
- package/dist/src/utils/temporal-codec.js +319 -0
- package/dist/src/utils/temporal-codec.js.map +1 -0
- package/dist/src/utils/tunnel-ownership.d.ts +130 -0
- package/dist/src/utils/tunnel-ownership.d.ts.map +1 -0
- package/dist/src/utils/tunnel-ownership.js +274 -0
- package/dist/src/utils/tunnel-ownership.js.map +1 -0
- package/dist/src/utils/vpn-join.d.ts +32 -0
- package/dist/src/utils/vpn-join.d.ts.map +1 -0
- package/dist/src/utils/vpn-join.js +62 -0
- package/dist/src/utils/vpn-join.js.map +1 -0
- package/dist/src/utils/vpn.d.ts +62 -0
- package/dist/src/utils/vpn.d.ts.map +1 -0
- package/dist/src/utils/vpn.js +183 -0
- package/dist/src/utils/vpn.js.map +1 -0
- package/dist/src/utils/workflow-fingerprint.d.ts +49 -0
- package/dist/src/utils/workflow-fingerprint.d.ts.map +1 -0
- package/dist/src/utils/workflow-fingerprint.js +135 -0
- package/dist/src/utils/workflow-fingerprint.js.map +1 -0
- package/dist/src/utils/worktree-identity.d.ts +86 -0
- package/dist/src/utils/worktree-identity.d.ts.map +1 -0
- package/dist/src/utils/worktree-identity.js +164 -0
- package/dist/src/utils/worktree-identity.js.map +1 -0
- package/fragments/agents/AGENTS.md.hbs +92 -0
- package/fragments/agents/CLAUDE.md.hbs +8 -0
- package/fragments/base/Pulumi.dev.yaml.hbs +10 -0
- package/fragments/base/Pulumi.yaml.hbs +9 -0
- package/fragments/base/index.ts.hbs +107 -0
- package/fragments/base/package.json.hbs +22 -0
- package/{templates/api-web-db/api → fragments/base}/tsconfig.json +3 -4
- package/fragments/bucket/api/src/storage.ts.hbs +81 -0
- package/fragments/database/api/src/db.ts.hbs +23 -0
- package/fragments/database/prisma/schema.prisma.hbs +18 -0
- package/{templates/api-web-db → fragments/service}/api/.dockerignore +2 -0
- package/fragments/service/api/package.json.hbs +40 -0
- package/fragments/service/api/src/index.ts.hbs +58 -0
- package/{templates/api-web-db → fragments/service/api}/tsconfig.json +5 -3
- package/fragments/temporal/worker/.dockerignore +4 -0
- package/fragments/temporal/worker/Dockerfile +15 -0
- package/{templates/temporal-api-worker → fragments/temporal}/worker/package.json.hbs +3 -2
- package/fragments/temporal/worker/src/activities.ts.hbs +14 -0
- package/fragments/temporal/worker/src/worker.ts.hbs +27 -0
- package/fragments/temporal/worker/src/workflows.ts.hbs +24 -0
- package/fragments/temporal/worker/tsconfig.json +13 -0
- package/package.json +35 -21
- package/skills/core/SKILL.md +365 -0
- package/skills/pull-remote-agent-context/SKILL.md +194 -0
- package/stack/docker-compose.hub.yml +134 -0
- package/stack/docker-compose.yml +447 -0
- package/stack/hub/Dockerfile.api +18 -0
- package/stack/hub/Dockerfile.auth +10 -0
- package/stack/hub/Dockerfile.ui +10 -0
- package/stack/init/01-databases.sql +12 -0
- package/stack/observability/blackbox.yml +20 -0
- package/stack/observability/otel-collector.yaml +73 -0
- package/stack/observability/prometheus.yml +36 -0
- package/stack/observability/tempo.yaml +25 -0
- package/stack/temporal/local.yaml +44 -0
- package/templates/api-auth/AGENTS.md.hbs +16 -0
- package/templates/api-auth/Pulumi.dev.yaml.hbs +8 -0
- package/templates/api-auth/Pulumi.yaml.hbs +8 -0
- package/templates/api-auth/README.md.hbs +67 -0
- package/templates/api-auth/api/package.json.hbs +28 -0
- package/templates/api-auth/api/src/index.ts.hbs +96 -0
- package/templates/api-auth/api/src/schema.ts.hbs +35 -0
- package/templates/api-auth/api/src/seed-authz.ts.hbs +48 -0
- package/templates/api-auth/api/src/spicedb-http-provider.ts.hbs +89 -0
- package/templates/api-auth/index.ts.hbs +65 -0
- package/templates/api-auth/package.json.hbs +20 -0
- package/templates/api-auth/skills/develop/SKILL.md.hbs +32 -0
- package/templates/api-role-gating/AGENTS.md.hbs +20 -0
- package/templates/api-role-gating/Pulumi.dev.yaml.hbs +8 -0
- package/templates/api-role-gating/Pulumi.yaml.hbs +8 -0
- package/templates/api-role-gating/README.md.hbs +64 -0
- package/templates/api-role-gating/api/Dockerfile +17 -0
- package/templates/api-role-gating/api/package.json.hbs +28 -0
- package/templates/api-role-gating/api/src/authn.ts.hbs +29 -0
- package/templates/api-role-gating/api/src/authz.ts.hbs +12 -0
- package/templates/api-role-gating/api/src/main.ts.hbs +58 -0
- package/templates/api-role-gating/api/src/schema.ts.hbs +22 -0
- package/templates/api-role-gating/api/tsconfig.json +13 -0
- package/templates/api-role-gating/index.ts.hbs +107 -0
- package/templates/api-role-gating/package.json.hbs +21 -0
- package/templates/api-role-gating/skills/develop/SKILL.md.hbs +60 -0
- package/templates/api-role-gating/tsconfig.json +10 -0
- package/templates/apps-repo/README.md.hbs +24 -0
- package/templates/apps-repo/gitignore +41 -0
- package/templates/apps-repo/npmrc.hbs +7 -0
- package/templates/apps-repo/package.json.hbs +15 -0
- package/templates/apps-repo/pnpm-workspace.yaml +3 -0
- package/templates/apps-repo/tsconfig.json +18 -0
- package/templates/external-service/AGENTS.md.hbs +20 -0
- package/templates/external-service/Pulumi.dev.yaml.hbs +8 -0
- package/templates/external-service/Pulumi.yaml.hbs +8 -0
- package/templates/external-service/README.md.hbs +56 -0
- package/templates/external-service/api/Dockerfile +15 -0
- package/templates/external-service/api/package.json.hbs +25 -0
- package/templates/external-service/api/src/index.ts.hbs +81 -0
- package/templates/external-service/index.ts.hbs +82 -0
- package/templates/external-service/mocks/vendorpay/package.json.hbs +9 -0
- package/templates/external-service/mocks/vendorpay/server.mjs.hbs +61 -0
- package/templates/external-service/package.json.hbs +34 -0
- package/templates/external-service/skills/develop/SKILL.md.hbs +55 -0
- package/templates/external-service/tsconfig.json +10 -0
- package/templates/platform-repo/AGENTS.md.hbs +18 -0
- package/templates/platform-repo/README.md.hbs +38 -0
- package/templates/platform-repo/core/Pulumi.yaml.hbs +12 -0
- package/templates/platform-repo/core/Pulumi.{{tenant}}-{{env}}.yaml.hbs +57 -0
- package/templates/platform-repo/core/index.ts +62 -0
- package/templates/platform-repo/core/package.json.hbs +22 -0
- package/templates/platform-repo/core/tsconfig.json +8 -0
- package/templates/platform-repo/package.json.hbs +15 -0
- package/templates/platform-repo/platform/Pulumi.yaml.hbs +12 -0
- package/templates/platform-repo/platform/Pulumi.{{tenant}}-{{env}}.yaml.hbs +59 -0
- package/templates/platform-repo/platform/index.ts +95 -0
- package/templates/platform-repo/platform/package.json.hbs +26 -0
- package/templates/platform-repo/platform/tsconfig.json +8 -0
- package/templates/platform-repo/pnpm-workspace.yaml +3 -0
- package/templates/workflow/AGENTS.md.hbs +15 -0
- package/templates/workflow/Pulumi.dev.yaml.hbs +8 -0
- package/templates/workflow/Pulumi.yaml.hbs +8 -0
- package/templates/workflow/README.md.hbs +45 -0
- package/templates/workflow/api/.dockerignore +4 -0
- package/templates/workflow/api/Dockerfile +15 -0
- package/templates/{temporal-api-worker → workflow}/api/package.json.hbs +8 -6
- package/templates/workflow/api/src/index.ts.hbs +130 -0
- package/templates/workflow/api/tsconfig.json +14 -0
- package/templates/workflow/index.ts.hbs +67 -0
- package/templates/workflow/package.json.hbs +20 -0
- package/templates/workflow/skills/develop/SKILL.md.hbs +32 -0
- package/templates/workflow/tsconfig.json +10 -0
- package/templates/workflow/worker/.dockerignore +4 -0
- package/templates/workflow/worker/Dockerfile +13 -0
- package/templates/workflow/worker/package.json.hbs +25 -0
- package/templates/workflow/worker/src/worker.ts.hbs +24 -0
- package/templates/workflow/worker/tsconfig.json +14 -0
- package/dist/src/commands/devbox.d.ts +0 -22
- package/dist/src/commands/devbox.d.ts.map +0 -1
- package/dist/src/commands/devbox.js +0 -463
- package/dist/src/commands/devbox.js.map +0 -1
- package/templates/api-web-db/api/Dockerfile +0 -16
- package/templates/api-web-db/api/package.json.hbs +0 -21
- package/templates/api-web-db/api/src/index.ts.hbs +0 -123
- package/templates/api-web-db/package.json.hbs +0 -27
- package/templates/api-web-db/sst.config.ts.hbs +0 -151
- package/templates/api-web-db/web/.dockerignore +0 -3
- package/templates/api-web-db/web/Dockerfile +0 -17
- package/templates/api-web-db/web/app/lib/db.server.ts +0 -36
- package/templates/api-web-db/web/app/root.tsx +0 -29
- package/templates/api-web-db/web/app/routes/home.tsx.hbs +0 -114
- package/templates/api-web-db/web/app/routes.ts +0 -3
- package/templates/api-web-db/web/package.json.hbs +0 -30
- package/templates/api-web-db/web/prisma/schema.prisma +0 -25
- package/templates/api-web-db/web/prisma.config.ts +0 -18
- package/templates/api-web-db/web/react-router.config.ts +0 -5
- package/templates/api-web-db/web/tsconfig.json +0 -19
- package/templates/api-web-db/web/vite.config.ts +0 -9
- package/templates/temporal-api-worker/README.md.hbs +0 -133
- package/templates/temporal-api-worker/api/src/index.ts.hbs +0 -145
- package/templates/temporal-api-worker/package.json.hbs +0 -29
- package/templates/temporal-api-worker/sst.config.ts.hbs +0 -161
- package/templates/temporal-api-worker/worker/Dockerfile +0 -11
- package/templates/temporal-api-worker/worker/src/bundle-workflows.ts +0 -38
- package/templates/temporal-api-worker/worker/src/worker.ts.hbs +0 -93
- /package/templates/{temporal-api-worker → api-auth}/api/.dockerignore +0 -0
- /package/templates/{temporal-api-worker → api-auth}/api/Dockerfile +0 -0
- /package/templates/{temporal-api-worker → api-auth}/api/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker → api-auth}/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker/worker → api-role-gating/api}/.dockerignore +0 -0
- /package/templates/{temporal-api-worker/worker → external-service/api}/tsconfig.json +0 -0
- /package/templates/{temporal-api-worker → workflow}/api/src/encryption-codec.ts +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/activities.ts.hbs +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/encryption-codec.ts +0 -0
- /package/templates/{temporal-api-worker → workflow}/worker/src/workflows.ts.hbs +0 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared AWS credential resolution for mesh CLI commands.
|
|
3
|
+
*
|
|
4
|
+
* Three-tier resolution:
|
|
5
|
+
* 1. Existing AWS credentials in environment (CI/CD) → use directly
|
|
6
|
+
* 2. Zitadel JWT via `mesh login` → AssumeRoleWithWebIdentity
|
|
7
|
+
* 3. Fallback → AssumeRole via current AWS session (SSO)
|
|
8
|
+
*
|
|
9
|
+
* Uses @aws-sdk/client-sts directly — does NOT shell out to the `aws` CLI
|
|
10
|
+
* binary, so the binary is not a runtime requirement.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from "fs";
|
|
13
|
+
import * as path from "path";
|
|
14
|
+
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand, GetCallerIdentityCommand, STSClient, } from "@aws-sdk/client-sts";
|
|
15
|
+
import { logInfo, logSuccess, logWarn } from "./log.js";
|
|
16
|
+
import { isExpiredAwsTokenMessage, SSO_LOGIN_FIX } from "./auth-preflight.js";
|
|
17
|
+
import { ensureLogin } from "../commands/login.js";
|
|
18
|
+
const DEFAULT_REGION = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? "us-east-2";
|
|
19
|
+
/**
|
|
20
|
+
* Derive the platform context key (e.g., "mesh.dev") from a Pulumi stack config.
|
|
21
|
+
*
|
|
22
|
+
* Reads `mesh:platform` from Pulumi.<stack>.yaml. Supports both formats:
|
|
23
|
+
* mesh:platform: '{"env":"dev","name":"mesh"}' → "mesh.dev"
|
|
24
|
+
* mesh:platform:
|
|
25
|
+
* name: mesh
|
|
26
|
+
* env: dev → "mesh.dev"
|
|
27
|
+
*/
|
|
28
|
+
export function derivePlatformContext(appRoot, stack) {
|
|
29
|
+
const configFile = path.join(appRoot, `Pulumi.${stack}.yaml`);
|
|
30
|
+
if (!fs.existsSync(configFile))
|
|
31
|
+
return null;
|
|
32
|
+
const content = fs.readFileSync(configFile, "utf-8");
|
|
33
|
+
// Try JSON-encoded string first
|
|
34
|
+
const jsonMatch = content.match(/mesh:platform:\s*'(\{[^']+\})'/);
|
|
35
|
+
if (jsonMatch) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(jsonMatch[1]);
|
|
38
|
+
if (parsed.name && parsed.env)
|
|
39
|
+
return `${parsed.name}.${parsed.env}`;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// fall through
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Try YAML block format
|
|
46
|
+
const nameMatch = content.match(/mesh:platform:[\s\S]*?name:\s*(\S+)/);
|
|
47
|
+
const envMatch = content.match(/mesh:platform:[\s\S]*?env:\s*(\S+)/);
|
|
48
|
+
if (nameMatch && envMatch) {
|
|
49
|
+
return `${nameMatch[1]}.${envMatch[1]}`;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Quote a `credential_process` command token for AWS config-file syntax: the
|
|
55
|
+
* AWS SDK/CLI split the value on spaces, honoring double quotes — so any
|
|
56
|
+
* token containing whitespace (e.g. a mesh binary under "Application
|
|
57
|
+
* Support") must be wrapped in double quotes or the command is mis-split.
|
|
58
|
+
* Tokens without whitespace are left bare (byte-identical to the historic
|
|
59
|
+
* output).
|
|
60
|
+
*/
|
|
61
|
+
function quoteCredProcessToken(token) {
|
|
62
|
+
return /\s/.test(token) ? `"${token}"` : token;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a STABLE absolute path to the running `mesh` entrypoint for
|
|
66
|
+
* embedding in a `credential_process` line — or fall back to plain `mesh`
|
|
67
|
+
* (PATH lookup) when `argv1` is missing, doesn't exist on disk, or lives in
|
|
68
|
+
* a transient location (`npx` cache / OS temp dir): a profile pointing at a
|
|
69
|
+
* path that evaporates breaks every later AWS call with a cryptic
|
|
70
|
+
* credential_process error. The fallback is announced via `logWarn` so the
|
|
71
|
+
* user knows to install mesh-cli globally.
|
|
72
|
+
*/
|
|
73
|
+
export function resolveStableMeshBin(argv1, deps = {}) {
|
|
74
|
+
const exists = deps.exists ?? fs.existsSync;
|
|
75
|
+
const warn = deps.warn ?? logWarn;
|
|
76
|
+
let resolved = argv1 ? path.resolve(argv1) : undefined;
|
|
77
|
+
// Under the source launcher the CLI process's argv[1] is a TypeScript entry
|
|
78
|
+
// (bin/mesh.ts), which plain node cannot execute (type-stripped .js-suffixed
|
|
79
|
+
// imports fail with ERR_MODULE_NOT_FOUND). Point the profile at the sibling
|
|
80
|
+
// .mjs launcher instead — it bootstraps tsx itself, from any cwd/env. Keyed on
|
|
81
|
+
// the `.ts` extension + a derived sibling (not the literal `mesh.ts`), so a
|
|
82
|
+
// rename of the source entry doesn't silently revert to a broken value. Assign
|
|
83
|
+
// unconditionally: if the sibling is absent the existing !exists guard below
|
|
84
|
+
// reports it by name (rather than collapsing into the "argv1 missing" branch).
|
|
85
|
+
if (resolved && /\.ts$/.test(resolved)) {
|
|
86
|
+
resolved = path.join(path.dirname(resolved), path.basename(resolved, ".ts") + ".mjs");
|
|
87
|
+
}
|
|
88
|
+
const transient = resolved !== undefined &&
|
|
89
|
+
(/[\\/]_npx[\\/]/.test(resolved) || /^\/(?:private\/)?(?:tmp|var\/folders)\//.test(resolved));
|
|
90
|
+
if (!resolved || !exists(resolved) || transient) {
|
|
91
|
+
warn(`credential_process cannot reference a stable mesh binary` +
|
|
92
|
+
(resolved ? ` (${resolved} is transient or missing)` : "") +
|
|
93
|
+
` — falling back to \`mesh\` on PATH. Install mesh-cli globally so the profile keeps refreshing.`);
|
|
94
|
+
return "mesh";
|
|
95
|
+
}
|
|
96
|
+
return resolved;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Render an AWS config-file `[profile …]` block whose `credential_process`
|
|
100
|
+
* re-invokes `mesh login … --credential-process`, so the AWS SDK's default
|
|
101
|
+
* provider chain auto-refreshes the underlying STS triple (the `mesh login`
|
|
102
|
+
* process re-issues the Zitadel token as needed).
|
|
103
|
+
*
|
|
104
|
+
* Shared by `mesh dev` (child services) and `mesh login --export` so both
|
|
105
|
+
* produce byte-identical profiles. Pure — no I/O. The `region` line is
|
|
106
|
+
* emitted only when `region` is a non-empty string. Includes a trailing
|
|
107
|
+
* newline. The binary path and role ARN are double-quoted when they contain
|
|
108
|
+
* whitespace (AWS config command-splitting rules).
|
|
109
|
+
*/
|
|
110
|
+
export function renderCredentialProcessProfile(args) {
|
|
111
|
+
const lines = [
|
|
112
|
+
`[profile ${args.profileName}]`,
|
|
113
|
+
`credential_process = ${quoteCredProcessToken(args.meshBin)} login ${quoteCredProcessToken(args.context)} --credential-process --role ${quoteCredProcessToken(args.roleArn)}`,
|
|
114
|
+
];
|
|
115
|
+
if (args.region)
|
|
116
|
+
lines.push(`region = ${args.region}`);
|
|
117
|
+
return lines.join("\n") + "\n";
|
|
118
|
+
}
|
|
119
|
+
// Marker lines delimiting the mesh-managed section of the user's AWS config
|
|
120
|
+
// file. Follows the `conda init` / `nvm` managed-block convention so the
|
|
121
|
+
// section is discoverable and safely re-writable. The START marker carries
|
|
122
|
+
// the context (one managed section per context); the END marker is shared.
|
|
123
|
+
const MANAGED_START_PREFIX = `# >>> mesh-cli managed profile `;
|
|
124
|
+
const MANAGED_START = (context) => `${MANAGED_START_PREFIX}${context} >>>`;
|
|
125
|
+
const MANAGED_END = `# <<< mesh-cli managed <<<`;
|
|
126
|
+
/**
|
|
127
|
+
* Given a managed START marker for OUR context whose matching END is missing
|
|
128
|
+
* (orphaned — e.g. the user deleted the END line), find the index of the first
|
|
129
|
+
* character we should NOT reclaim. Conservative by construction: because
|
|
130
|
+
* `MANAGED_END` is a shared literal across contexts, an END found further down
|
|
131
|
+
* may belong to ANOTHER context's healthy section — so we never scan to a
|
|
132
|
+
* distant END or to EOF. We only reclaim the lines the mesh CLI provably
|
|
133
|
+
* wrote (see `renderCredentialProcessProfile`): one `[profile …]` header
|
|
134
|
+
* followed by contiguous `key = value` lines, stopping at the first blank
|
|
135
|
+
* line, comment/marker, second profile header, or `boundIdx` (the next
|
|
136
|
+
* managed START of any context), whichever comes first.
|
|
137
|
+
*
|
|
138
|
+
* @param afterStart index just past OUR START marker text (before its newline)
|
|
139
|
+
* @param boundIdx index of the next managed START marker after ours, or -1
|
|
140
|
+
*/
|
|
141
|
+
function orphanedSectionTail(existing, afterStart, boundIdx) {
|
|
142
|
+
const limit = boundIdx === -1 ? existing.length : boundIdx;
|
|
143
|
+
let idx = afterStart;
|
|
144
|
+
if (idx >= limit || existing[idx] !== "\n")
|
|
145
|
+
return Math.min(idx, limit);
|
|
146
|
+
idx++; // consume the newline terminating our START marker line
|
|
147
|
+
let claimedHeader = false;
|
|
148
|
+
while (idx < limit) {
|
|
149
|
+
const nl = existing.indexOf("\n", idx);
|
|
150
|
+
const lineEnd = nl === -1 || nl > limit ? limit : nl;
|
|
151
|
+
const line = existing.slice(idx, lineEnd);
|
|
152
|
+
const ours = claimedHeader
|
|
153
|
+
? /^[A-Za-z_][A-Za-z0-9_]*\s*=/.test(line) // key = value continuation
|
|
154
|
+
: /^\[profile [^\]]+\]\s*$/.test(line); // exactly one profile header
|
|
155
|
+
if (!ours)
|
|
156
|
+
return idx;
|
|
157
|
+
claimedHeader = true;
|
|
158
|
+
idx = lineEnd >= limit ? limit : lineEnd + 1;
|
|
159
|
+
}
|
|
160
|
+
return limit;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Insert or replace the mesh-managed `[profile …]` section for `context` in
|
|
164
|
+
* the user's AWS config content, preserving ALL other content byte-for-byte
|
|
165
|
+
* (this is the user's real ~/.aws/config — clobbering it breaks their other
|
|
166
|
+
* profiles). Pure — no I/O; exported for unit testing.
|
|
167
|
+
*
|
|
168
|
+
* - Existing managed section for this context → replaced in place.
|
|
169
|
+
* - Orphaned START (matching END lost) → only the contiguous profile block
|
|
170
|
+
* that is provably ours is reclaimed; other contexts' sections and user
|
|
171
|
+
* content below are preserved (see `orphanedSectionTail`).
|
|
172
|
+
* - No section → appended, separated by a single blank line (and a trailing
|
|
173
|
+
* newline is added to the existing content if it lacks one).
|
|
174
|
+
*/
|
|
175
|
+
export function upsertManagedAwsConfigSection(existing, context, profileBlock) {
|
|
176
|
+
const body = profileBlock.endsWith("\n") ? profileBlock : profileBlock + "\n";
|
|
177
|
+
const section = `${MANAGED_START(context)}\n${body}${MANAGED_END}\n`;
|
|
178
|
+
const startIdx = existing.indexOf(MANAGED_START(context));
|
|
179
|
+
if (startIdx !== -1) {
|
|
180
|
+
const afterStart = startIdx + MANAGED_START(context).length;
|
|
181
|
+
const endIdx = existing.indexOf(MANAGED_END, afterStart);
|
|
182
|
+
// MANAGED_END is a shared literal across contexts, so the first END below
|
|
183
|
+
// our START is only OURS if no other context's START sits in between —
|
|
184
|
+
// otherwise that END closes the OTHER section and scanning to it would
|
|
185
|
+
// swallow that section whole.
|
|
186
|
+
const foreignIdx = existing.indexOf(MANAGED_START_PREFIX, afterStart);
|
|
187
|
+
let tail;
|
|
188
|
+
if (endIdx !== -1 && (foreignIdx === -1 || endIdx < foreignIdx)) {
|
|
189
|
+
// Healthy section: replace START..END. Swallow a single trailing
|
|
190
|
+
// newline of the old section so replacement is idempotent (the new
|
|
191
|
+
// section brings its own).
|
|
192
|
+
const tailIdx = endIdx + MANAGED_END.length;
|
|
193
|
+
tail = existing[tailIdx] === "\n" ? tailIdx + 1 : tailIdx;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Orphaned START (our END missing). Reclaim only the contiguous
|
|
197
|
+
// profile block that is provably ours — never foreign sections, user
|
|
198
|
+
// profiles below, or everything to EOF.
|
|
199
|
+
tail = orphanedSectionTail(existing, afterStart, foreignIdx);
|
|
200
|
+
}
|
|
201
|
+
return existing.slice(0, startIdx) + section + existing.slice(tail);
|
|
202
|
+
}
|
|
203
|
+
if (existing.length === 0)
|
|
204
|
+
return section;
|
|
205
|
+
const sep = existing.endsWith("\n\n") ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
|
|
206
|
+
return existing + sep + section;
|
|
207
|
+
}
|
|
208
|
+
function newStsClient() {
|
|
209
|
+
return new STSClient({ region: DEFAULT_REGION });
|
|
210
|
+
}
|
|
211
|
+
/** Pull AWS env vars out of an STS Credentials struct; null if any field is missing. */
|
|
212
|
+
function toEnv(credentials) {
|
|
213
|
+
const { AccessKeyId, SecretAccessKey, SessionToken } = credentials;
|
|
214
|
+
if (!AccessKeyId || !SecretAccessKey || !SessionToken)
|
|
215
|
+
return null;
|
|
216
|
+
return {
|
|
217
|
+
AWS_ACCESS_KEY_ID: AccessKeyId,
|
|
218
|
+
AWS_SECRET_ACCESS_KEY: SecretAccessKey,
|
|
219
|
+
AWS_SESSION_TOKEN: SessionToken,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* IAM rejects a DurationSeconds higher than the role's MaxSessionDuration with
|
|
224
|
+
* a ValidationError. We detect that and fall back to a one-hour session.
|
|
225
|
+
*/
|
|
226
|
+
function isMaxSessionDurationError(err) {
|
|
227
|
+
if (!(err instanceof Error))
|
|
228
|
+
return false;
|
|
229
|
+
const message = err.message ?? "";
|
|
230
|
+
return (message.includes("MaxSessionDuration") ||
|
|
231
|
+
message.includes("DurationSeconds"));
|
|
232
|
+
}
|
|
233
|
+
/** Assume an IAM role via current AWS session and return credentials as env vars. */
|
|
234
|
+
export async function assumeRole(roleArn, sessionName = "mesh-cli", durationSeconds = 43200) {
|
|
235
|
+
const sts = newStsClient();
|
|
236
|
+
for (const duration of [durationSeconds, 3600]) {
|
|
237
|
+
try {
|
|
238
|
+
const resp = await sts.send(new AssumeRoleCommand({
|
|
239
|
+
RoleArn: roleArn,
|
|
240
|
+
RoleSessionName: sessionName,
|
|
241
|
+
DurationSeconds: duration,
|
|
242
|
+
}));
|
|
243
|
+
if (!resp.Credentials)
|
|
244
|
+
return null;
|
|
245
|
+
return toEnv(resp.Credentials);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
if (!isMaxSessionDurationError(err) || duration === 3600) {
|
|
249
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
250
|
+
logWarn(`AssumeRole failed: ${message}`);
|
|
251
|
+
// Name the SSO fix when the ambient session is the problem — the raw
|
|
252
|
+
// STS error never mentions `aws sso login` (MESH-2479).
|
|
253
|
+
if (isExpiredAwsTokenMessage(message)) {
|
|
254
|
+
logWarn(` Your AWS SSO session looks expired or missing — refresh with: ${SSO_LOGIN_FIX}`);
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
// Retry with shorter duration
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Assume role using a Zitadel JWT via AssumeRoleWithWebIdentity, returning
|
|
265
|
+
* the full STS credential struct (including `Expiration`) rather than the
|
|
266
|
+
* env-var shape. Used by callers that need to track/refresh expiry (e.g.
|
|
267
|
+
* `credential_process`).
|
|
268
|
+
*/
|
|
269
|
+
export async function assumeRoleCredentials(roleArn, idToken, sessionName, durationSeconds = 43200) {
|
|
270
|
+
// STS WebIdentity does not require ambient AWS credentials — the JWT proves identity.
|
|
271
|
+
const sts = newStsClient();
|
|
272
|
+
for (const duration of [durationSeconds, 3600]) {
|
|
273
|
+
try {
|
|
274
|
+
const resp = await sts.send(new AssumeRoleWithWebIdentityCommand({
|
|
275
|
+
RoleArn: roleArn,
|
|
276
|
+
RoleSessionName: sessionName,
|
|
277
|
+
WebIdentityToken: idToken,
|
|
278
|
+
DurationSeconds: duration,
|
|
279
|
+
}));
|
|
280
|
+
if (!resp.Credentials)
|
|
281
|
+
return null;
|
|
282
|
+
const env = toEnv(resp.Credentials);
|
|
283
|
+
if (!env)
|
|
284
|
+
return null;
|
|
285
|
+
return {
|
|
286
|
+
// `env` is a `Record<string, string>` (index-signature typed), so
|
|
287
|
+
// `noUncheckedIndexedAccess` widens these to `string | undefined`
|
|
288
|
+
// even though `toEnv` guarantees they're set — assert accordingly.
|
|
289
|
+
AccessKeyId: env.AWS_ACCESS_KEY_ID,
|
|
290
|
+
SecretAccessKey: env.AWS_SECRET_ACCESS_KEY,
|
|
291
|
+
SessionToken: env.AWS_SESSION_TOKEN,
|
|
292
|
+
Expiration: resp.Credentials.Expiration.toISOString(),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
if (!isMaxSessionDurationError(err) || duration === 3600) {
|
|
297
|
+
logWarn(`AssumeRoleWithWebIdentity failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
// Retry with shorter duration
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
/** Assume role using a Zitadel JWT via AssumeRoleWithWebIdentity. */
|
|
306
|
+
export async function assumeRoleWithWebIdentity(roleArn, idToken, sessionName, durationSeconds = 43200) {
|
|
307
|
+
const creds = await assumeRoleCredentials(roleArn, idToken, sessionName, durationSeconds);
|
|
308
|
+
if (!creds)
|
|
309
|
+
return null;
|
|
310
|
+
return toEnv(creds);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Extract the `iss` claim from a JWT without ever throwing — malformed or
|
|
314
|
+
* corrupt tokens (e.g. a damaged `~/.config/mesh/credentials.json`) yield
|
|
315
|
+
* `undefined`. The failure-diagnostic paths use this; a decode that throws
|
|
316
|
+
* there would crash before the diagnostic prints, which is exactly the
|
|
317
|
+
* failure class MESH-2515 removes.
|
|
318
|
+
*/
|
|
319
|
+
export function tokenIssuer(token) {
|
|
320
|
+
const iss = decodeJwtPayload(token)?.iss;
|
|
321
|
+
return typeof iss === "string" && iss ? iss : undefined;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Explain an AssumeRoleWithWebIdentity failure in platform terms: which login
|
|
325
|
+
* session (context + token issuer) tried to assume which role, in which AWS
|
|
326
|
+
* account. STS's "web identity token could not be validated" reads like an
|
|
327
|
+
* IAM/expiry problem, but the usual cause is a context whose issuer the role's
|
|
328
|
+
* account simply doesn't trust — e.g. a `mesh.dev` session against a role in a
|
|
329
|
+
* `trabian`-platform account (MESH-2515). stderr only — callers in
|
|
330
|
+
* `--credential-process` mode must keep stdout JSON-clean.
|
|
331
|
+
*
|
|
332
|
+
* `format: "inline"` renders the same facts as one line, for detail fields
|
|
333
|
+
* that get interpolated mid-sentence (the doctor/preflight cred probe). Both
|
|
334
|
+
* forms keep the `AssumeRoleWithWebIdentity failed` prefix the doctor plan
|
|
335
|
+
* documents as the detail capture.
|
|
336
|
+
*/
|
|
337
|
+
export function describeAssumeFailure(opts, format = "block") {
|
|
338
|
+
const account = /^arn:aws:iam::(\d+):/.exec(opts.roleArn)?.[1];
|
|
339
|
+
const head = `AssumeRoleWithWebIdentity failed for ${opts.roleArn}` +
|
|
340
|
+
(account ? ` (account ${account})` : "");
|
|
341
|
+
const session = opts.context
|
|
342
|
+
? `mesh login context '${opts.context}'` + (opts.issuer ? ` (issuer ${opts.issuer})` : "")
|
|
343
|
+
: opts.issuer
|
|
344
|
+
? `issuer ${opts.issuer}`
|
|
345
|
+
: undefined;
|
|
346
|
+
if (format === "inline") {
|
|
347
|
+
return (head +
|
|
348
|
+
(session ? ` via ${session}` : "") +
|
|
349
|
+
" — if the role's account doesn't trust this issuer, this is a context mismatch" +
|
|
350
|
+
" (wrong `mesh:platform`), not an IAM permission problem");
|
|
351
|
+
}
|
|
352
|
+
const lines = [head];
|
|
353
|
+
if (session)
|
|
354
|
+
lines.push(` Session: ${session}`);
|
|
355
|
+
lines.push(" If the role's account does not trust this issuer, you are logged into the", " wrong context for this stack — check `mesh:platform` in the app's Pulumi", " config and `mesh login <platform>.<env>` accordingly. (This is a context", " mismatch, not an IAM permission problem.)");
|
|
356
|
+
return lines.join("\n");
|
|
357
|
+
}
|
|
358
|
+
/** Format STS credentials as AWS `credential_process` JSON (Version 1). */
|
|
359
|
+
export function toCredentialProcessJson(creds) {
|
|
360
|
+
return JSON.stringify({
|
|
361
|
+
Version: 1,
|
|
362
|
+
AccessKeyId: creds.AccessKeyId,
|
|
363
|
+
SecretAccessKey: creds.SecretAccessKey,
|
|
364
|
+
SessionToken: creds.SessionToken,
|
|
365
|
+
Expiration: creds.Expiration,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Ask "is there a working AWS connection right now?" — nothing more.
|
|
370
|
+
*
|
|
371
|
+
* Deliberately NOT `resolveAwsCredentials`: that one answers "get me credentials
|
|
372
|
+
* for role X" and has an opinion about how they were obtained. This one runs
|
|
373
|
+
* GetCallerIdentity through the SDK's default provider chain and reports whatever
|
|
374
|
+
* it finds, so a static key/secret pair in `~/.aws/credentials` counts exactly as
|
|
375
|
+
* much as an SSO session or a Zitadel-minted role. Returns null when the chain
|
|
376
|
+
* yields nothing usable.
|
|
377
|
+
*/
|
|
378
|
+
export async function probeAwsIdentity() {
|
|
379
|
+
try {
|
|
380
|
+
const out = await newStsClient().send(new GetCallerIdentityCommand({}));
|
|
381
|
+
if (!out.Arn || !out.Account)
|
|
382
|
+
return null;
|
|
383
|
+
return {
|
|
384
|
+
arn: out.Arn,
|
|
385
|
+
accountId: out.Account,
|
|
386
|
+
source: process.env.AWS_ACCESS_KEY_ID ? "environment" : "profile",
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Decode a Zitadel-issued JWT payload (no signature check — we only
|
|
395
|
+
* use it for role-selection hints in mesh-cli; the actual STS calls
|
|
396
|
+
* still verify against the OIDC provider). Returns null on malformed
|
|
397
|
+
* input.
|
|
398
|
+
*/
|
|
399
|
+
function decodeJwtPayload(token) {
|
|
400
|
+
const parts = token.split(".");
|
|
401
|
+
if (parts.length !== 3 || !parts[1])
|
|
402
|
+
return null;
|
|
403
|
+
try {
|
|
404
|
+
return JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Pick the AWS role ARN to assume based on Zitadel claims.
|
|
412
|
+
*
|
|
413
|
+
* Zitadel emits project roles under
|
|
414
|
+
* `urn:zitadel:iam:org:project:<projectId>:roles` as a nested object
|
|
415
|
+
* keyed by role name. We treat the presence of `mesh.platform:admin`
|
|
416
|
+
* (or any role listed in `meshcli.adminRoles` in config) as the
|
|
417
|
+
* signal to assume the broader admin role when the caller has
|
|
418
|
+
* configured one.
|
|
419
|
+
*
|
|
420
|
+
* Returns `defaultRole` when no admin role is configured, no admin
|
|
421
|
+
* claim is present, or the JWT can't be parsed. This keeps existing
|
|
422
|
+
* deployments working without a config change.
|
|
423
|
+
*
|
|
424
|
+
* The admin AWS role's IAM trust policy is expected to gate
|
|
425
|
+
* assumption on the same Zitadel claim in production (so the CLI
|
|
426
|
+
* preference can't be spoofed). That setup is its own change — see
|
|
427
|
+
* TODO(mesh-zitadel-aws-role-mapping).
|
|
428
|
+
*/
|
|
429
|
+
export function selectRoleForCaller(idToken, options) {
|
|
430
|
+
if (!options.adminRole || !idToken)
|
|
431
|
+
return options.defaultRole;
|
|
432
|
+
const adminRoles = options.adminClaimRoles ?? ["mesh.platform:admin"];
|
|
433
|
+
const claims = decodeJwtPayload(idToken);
|
|
434
|
+
if (!claims)
|
|
435
|
+
return options.defaultRole;
|
|
436
|
+
// Find the project-roles claim — key shape:
|
|
437
|
+
// urn:zitadel:iam:org:project:<projectId>:roles
|
|
438
|
+
// Multiple projects can emit roles; we walk all matching keys.
|
|
439
|
+
for (const [key, value] of Object.entries(claims)) {
|
|
440
|
+
if (!key.startsWith("urn:zitadel:iam:org:project:"))
|
|
441
|
+
continue;
|
|
442
|
+
if (!key.endsWith(":roles"))
|
|
443
|
+
continue;
|
|
444
|
+
if (!value || typeof value !== "object")
|
|
445
|
+
continue;
|
|
446
|
+
const claimedRoles = Object.keys(value);
|
|
447
|
+
for (const target of adminRoles) {
|
|
448
|
+
if (claimedRoles.includes(target))
|
|
449
|
+
return options.adminRole;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return options.defaultRole;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Resolve AWS credentials using the three-tier strategy.
|
|
456
|
+
*
|
|
457
|
+
* @param roleArn The IAM role to assume (from mesh:deployerRole)
|
|
458
|
+
* @param appRoot Pulumi app root directory
|
|
459
|
+
* @param stack Pulumi stack name
|
|
460
|
+
* @returns Resolved credentials, or null if all methods fail
|
|
461
|
+
*
|
|
462
|
+
* To inherit a broader role based on Zitadel claims, call
|
|
463
|
+
* `selectRoleForCaller` first and pass the result as `roleArn`.
|
|
464
|
+
*/
|
|
465
|
+
export async function resolveAwsCredentials(roleArn, appRoot, stack) {
|
|
466
|
+
const roleName = roleArn.split("/").pop() ?? roleArn;
|
|
467
|
+
// Path 1: Existing AWS credentials in environment (CI/CD)
|
|
468
|
+
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SESSION_TOKEN) {
|
|
469
|
+
logInfo("Using existing AWS credentials from environment");
|
|
470
|
+
return {
|
|
471
|
+
env: {
|
|
472
|
+
AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
|
|
473
|
+
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY ?? "",
|
|
474
|
+
AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN,
|
|
475
|
+
},
|
|
476
|
+
method: "environment",
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
// Path 2: Zitadel JWT via mesh login → AssumeRoleWithWebIdentity.
|
|
480
|
+
// Non-interactive here: only a valid CACHED session is used. An interactive
|
|
481
|
+
// device-flow before the SSO fallback would stall headless runs (CI,
|
|
482
|
+
// `mesh dev` with a working AWS_PROFILE) for minutes polling device codes
|
|
483
|
+
// nobody sees — SSO gets its chance first; interactive login is Path 4.
|
|
484
|
+
const platformContext = derivePlatformContext(appRoot, stack);
|
|
485
|
+
if (platformContext) {
|
|
486
|
+
const meshCreds = await ensureLogin(platformContext, { interactive: false });
|
|
487
|
+
if (meshCreds) {
|
|
488
|
+
const sessionName = (meshCreds.email ?? "mesh-cli")
|
|
489
|
+
.replace(/[^a-zA-Z0-9=,.@-]/g, "_")
|
|
490
|
+
.slice(0, 64);
|
|
491
|
+
logInfo(`Assuming ${roleName} via Zitadel (${meshCreds.email ?? platformContext})`);
|
|
492
|
+
const creds = await assumeRoleWithWebIdentity(roleArn, meshCreds.idToken, sessionName);
|
|
493
|
+
if (creds) {
|
|
494
|
+
logSuccess(`Assumed ${roleName} via Zitadel`);
|
|
495
|
+
return { env: creds, method: "zitadel" };
|
|
496
|
+
}
|
|
497
|
+
logWarn("Zitadel JWT auth failed — falling back to AWS SSO.\n" +
|
|
498
|
+
` (Try: mesh login ${platformContext})`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
// Path 3: Fallback — AssumeRole via current AWS session (SSO)
|
|
502
|
+
logInfo(`Assuming ${roleName} via AWS SSO`);
|
|
503
|
+
const creds = await assumeRole(roleArn, "mesh-cli");
|
|
504
|
+
if (creds) {
|
|
505
|
+
logSuccess(`Assumed ${roleName}`);
|
|
506
|
+
return { env: creds, method: "sso" };
|
|
507
|
+
}
|
|
508
|
+
// Path 4: Last resort — interactive Zitadel login (device/browser). Only
|
|
509
|
+
// reached when there's no env cred, no cached session, and no working SSO,
|
|
510
|
+
// i.e. a human at a terminal who genuinely needs to log in.
|
|
511
|
+
if (platformContext && process.stdout.isTTY) {
|
|
512
|
+
const meshCreds = await ensureLogin(platformContext);
|
|
513
|
+
if (meshCreds) {
|
|
514
|
+
const sessionName = (meshCreds.email ?? "mesh-cli")
|
|
515
|
+
.replace(/[^a-zA-Z0-9=,.@-]/g, "_")
|
|
516
|
+
.slice(0, 64);
|
|
517
|
+
logInfo(`Assuming ${roleName} via Zitadel (${meshCreds.email ?? platformContext})`);
|
|
518
|
+
const zCreds = await assumeRoleWithWebIdentity(roleArn, meshCreds.idToken, sessionName);
|
|
519
|
+
if (zCreds) {
|
|
520
|
+
logSuccess(`Assumed ${roleName} via Zitadel`);
|
|
521
|
+
return { env: zCreds, method: "zitadel" };
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=aws-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws-auth.js","sourceRoot":"","sources":["../../../src/utils/aws-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,7 +32,7 @@ export interface BastionInfo {
|
|
|
32
32
|
* separate parameter at /mesh-platform/{tenant}/{platformEnv}/platform-bastion
|
|
33
33
|
* for backward compatibility.
|
|
34
34
|
*/
|
|
35
|
-
export declare function getPlatformBastionInfo(tenant: string, platformEnv: string): Promise<PlatformBastionInfo>;
|
|
35
|
+
export declare function getPlatformBastionInfo(tenant: string, platformEnv: string, region?: string): Promise<PlatformBastionInfo>;
|
|
36
36
|
/**
|
|
37
37
|
* Get bastion info from SSM parameter store (legacy format).
|
|
38
38
|
* Reads from /mesh/{tenant}/{platformEnv}/platform-bastion and extracts RDS info.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bastion.d.ts","sourceRoot":"","sources":["../../../src/utils/bastion.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"bastion.d.ts","sourceRoot":"","sources":["../../../src/utils/bastion.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,CAAC,CA2F9B;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CAatB"}
|
|
@@ -11,8 +11,13 @@ import { logInfo, logSuccess, logError } from "./log.js";
|
|
|
11
11
|
* separate parameter at /mesh-platform/{tenant}/{platformEnv}/platform-bastion
|
|
12
12
|
* for backward compatibility.
|
|
13
13
|
*/
|
|
14
|
-
export async function getPlatformBastionInfo(tenant, platformEnv) {
|
|
15
|
-
const ssm = new SSMClient({});
|
|
14
|
+
export async function getPlatformBastionInfo(tenant, platformEnv, region) {
|
|
15
|
+
const ssm = new SSMClient(region ? { region } : {});
|
|
16
|
+
// Captured so the final error can distinguish a CREDS failure (the common
|
|
17
|
+
// case — stale/expired ambient AWS creds, or creds lacking cross-tenant read
|
|
18
|
+
// on the hub param) from a genuinely missing bastion. Without this the read
|
|
19
|
+
// error is swallowed and every failure looks like "bastion not deployed".
|
|
20
|
+
let primaryError;
|
|
16
21
|
// Primary: read from the platform export (platformBastion is a nested key)
|
|
17
22
|
const platformPath = `/mesh-platform/${tenant}/${platformEnv}/platform`;
|
|
18
23
|
logInfo(`Looking up platform bastion from ${platformPath}...`);
|
|
@@ -31,8 +36,10 @@ export async function getPlatformBastionInfo(tenant, platformEnv) {
|
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
|
-
catch {
|
|
35
|
-
//
|
|
39
|
+
catch (err) {
|
|
40
|
+
// Don't swallow: keep the real reason (AccessDenied / ExpiredToken / …) so
|
|
41
|
+
// the final error can be actionable. Then try the legacy path.
|
|
42
|
+
primaryError = err;
|
|
36
43
|
}
|
|
37
44
|
// Fallback: legacy separate parameter
|
|
38
45
|
const legacyPath = `/mesh-platform/${tenant}/${platformEnv}/platform-bastion`;
|
|
@@ -50,10 +57,24 @@ export async function getPlatformBastionInfo(tenant, platformEnv) {
|
|
|
50
57
|
}
|
|
51
58
|
return info;
|
|
52
59
|
}
|
|
53
|
-
catch (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
catch (legacyError) {
|
|
61
|
+
// Classify on the PRIMARY read's error (the meaningful one) — the legacy
|
|
62
|
+
// path is usually just ParameterNotFound and hides the real cause.
|
|
63
|
+
const cause = primaryError ?? legacyError;
|
|
64
|
+
const name = cause?.name ?? "";
|
|
65
|
+
const credsProblem = /Expired|UnrecognizedClient|InvalidClientTokenId|InvalidSignature|CredentialsProviderError|AccessDenied/i.test(name);
|
|
66
|
+
if (credsProblem) {
|
|
67
|
+
logError(`Could not read the platform bastion from ${platformPath} — AWS error: ${name}.`);
|
|
68
|
+
logInfo("This is almost always a CREDENTIALS problem, not a missing bastion.");
|
|
69
|
+
logInfo(" • The read uses the ambient AWS creds of this process; they must be valid AND able to read the HUB param above.");
|
|
70
|
+
logInfo(" • Check: `aws sts get-caller-identity` (ExpiredToken → refresh; AccessDenied → those creds lack hub read — use InfraAdmin-grade creds).");
|
|
71
|
+
logInfo(" • Stale creds often hide in the tmux GLOBAL env (`tmux show-environment -g | grep AWS_`); a per-shell `unset` won't clear them.");
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
logError(`Platform bastion not found in ${platformPath} or ${legacyPath}`);
|
|
75
|
+
logInfo("Make sure platformBastion is enabled in your platform config and deployed.");
|
|
76
|
+
}
|
|
77
|
+
throw cause;
|
|
57
78
|
}
|
|
58
79
|
}
|
|
59
80
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bastion.js","sourceRoot":"","sources":["../../../src/utils/bastion.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AA4BzD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAc,EACd,WAAmB;
|
|
1
|
+
{"version":3,"file":"bastion.js","sourceRoot":"","sources":["../../../src/utils/bastion.ts"],"names":[],"mappings":"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"}
|