@cfxlabsinc/b2b-services
    Preparing search index...

    Module @cfxlabsinc/nx-secrets

    @cfxlabsinc/nx-secrets

    Workspace-internal Nx plugin that infers the secrets-run, secrets-serve and secrets-build targets.

    Configuration Source
    local (default) dev's SSM parameters, then the project's committed <projectRoot>/local.env, then the ambient environment; empty final values removed
    local-offline the project's committed <projectRoot>/local.offline.env of dummies in place of SSM, then local.env, then the ambient environment; the app gets dummy AWS keys
    dev / prod the app's config namespaces and /cfx/secrets/<app>/ in SSM, read by tools/secrets/run.ts

    Every configuration runs the inner command through the wrapper:

    bun tools/secrets/run.ts --app <slug> --config <local|local-offline|dev|prod> [--env-file <path>] [--offline-env-file <path>] -- <cmd…>
    

    The wrapper reads, for each namespace in the app's config list (WORKLOAD_CONFIGS in workloadConfig.ts), every parameter directly under /cfx/secrets/<ns>/ and /cfx/stack/<stage>/<ns>/ (stage dev for local), then under /cfx/secrets/<slug>/ for the keys the app still holds there; a later path wins, and a slug with no config list (ci) reads only its own path. Every read is non-recursive (branch configs sit one level deeper) and keeps the key's full name, so a local.env works unchanged. It uses the workload-dev (local, dev) or workload-prod profile (always that profile, whatever AWS_PROFILE the shell exports; the run fails if the parameters it returns are not in that configuration's account), sets NX_LOAD_DOT_ENV_FILES=false so an inner nx loads no dotenv files, and spawns the command with inherited stdio. It propagates the exit code and SIGINT / SIGTERM. An empty path is not an error.

    For local the order is SSM < local.env < the ambient environment, and then every key whose final value is the empty string is removed, so KEY= in a local.env unsets a dev key. A missing --env-file is not an error. A local run needs aws sso login --sso-session cfx. local-offline reads local.offline.env instead of SSM and fails when the file is missing (see docs/SECRETS.md). For dev and prod the stored values win over the ambient environment and no file is read.

    local.env is committed and holds only non-secret local overrides (localhost URLs, ports, flags). It must never hold a secret: tools/ci/env-local.test.ts fails on a secret-named key with a value (DB_PASSWORD excepted) and on a URL with credentials for a non-local host. It is not named .env.local because nx, Next and bun load that name on their own, into dev and prod runs too.

    <slug> is the project name by default (secretsApp: "{projectName}"). A project whose SSM path differs sets secretsApp in its own project.json — db → aurora-db, fed-directory-services → fed-directory-api, solana-services → solana-api, and the services that run in the worker → temporal-worker.

    Inferred for any project whose scripts/ directory holds at least one .ts / .mts / .mjs / .js file:

    bun nx secrets-run <pkg> --args.script=<file>            # dev (default)
    bun nx secrets-run <pkg> --args.script=<file> -c local # local | local-offline | dev | prod

    The command is bun {projectRoot}/scripts/{args.script}. A project without a scripts/ directory has nothing it could run, so it gets no target.

    Both wrap an existing target — nx serve <pkg> and nx build <pkg> — so each is inferred only where that target exists:

    bun nx secrets-build <pkg>           # local (default)
    bun nx secrets-build <pkg> -c prod # local | local-offline | dev | prod

    secrets-serve also sets SENTRY_ENVIRONMENT=local. The variable comes from each stack's pulumi program rather than from the secrets, and the services' Sentry gates report when it is unset, so without it a laptop run with a SENTRY_DSN lands in the production issue stream.

    An Nx plugin cannot see another plugin's inferred targets, so the presence check has three branches:

    Source of build / serve How it is detected
    @cfxlabsinc/nx-lambda isLambdaProject() — src/lambda.ts + src/main.ts
    @cfxlabsinc/nx-open-next isOpenNextProject() — open-next.config.ts
    the project's own project.json reading targets[<name>]

    The dashboards declare serve in project.json purely to override the port, so the last branch alone would infer secrets-serve and miss secrets-build.

    Registered in workspace nx.json, excluding the vendored Pulumi provider SDKs:

    {
    "plugin": "@cfxlabsinc/nx-secrets",
    "options": {},
    "exclude": ["packages/pulumi/sdks/*/**"]
    }

    A targetDefaults entry for these targets would outrank the inferred target and clobber it. See @cfxlabsinc/nx-lambda.

    Resolves through the workspace dependency in the root package.json:

    "@cfxlabsinc/nx-secrets": "workspace:*"
    
    NxSecretsPluginOptions
    createNodes