Skip to content

feat: Allow syncEnvVars to mark variables as non-secret #3484

@theramjad

Description

@theramjad

Is your feature request related to a problem? Please describe.

I sync env vars from Infisical into Trigger.dev using the syncEnvVars build extension. The setup looks like this:

import { defineConfig } from "@trigger.dev/sdk/v3";
import { syncEnvVars } from "@trigger.dev/build/extensions/core";
import { InfisicalSDK } from "@infisical/sdk";

export default defineConfig({
  build: {
    extensions: [
      syncEnvVars(async (ctx) => {
        const client = new InfisicalSDK({ siteUrl: "https://app.infisical.com" });
        await client.auth().universalAuth.login({
          clientId: ctx.env.INFISICAL_CLIENT_ID,
          clientSecret: ctx.env.INFISICAL_CLIENT_SECRET,
        });
        const { secrets } = await client.secrets().listSecrets({
          environment: ctx.environment,
          projectId: ctx.env.INFISICAL_PROJECT_ID,
          secretPath: "/",
        });
        return secrets.map((s) => ({ name: s.secretKey, value: s.secretValue }));
      }),
    ],
  },
});

This works, but every variable synced this way is stored as a secret on the Trigger.dev side, regardless of whether it actually is one. Looking at the type:

export type SyncEnvVarsBody =
  | Record<string, string>
  | Array<{ name: string; value: string; isParentEnv?: boolean }>;

…there is no field to control secret vs. plain visibility.

The practical pain:

  • Non-sensitive values (public URLs, product IDs, region names, feature flags, bucket names) all show up masked in the Trigger.dev dashboard.
  • When debugging a failing run, I can't quickly verify what value was actually synced — I have to go back to Infisical to read it.
  • It removes the ability for Trigger.dev's UI to be a useful "what is this deployment configured with?" view, because everything is ••••••••.

Infisical itself distinguishes secret vs. non-secret values, so the information is available at the source — it's just lost in transit to Trigger.dev.

Describe the solution you'd like to see

Add an optional isSecret (or type: "secret" | "plain") field to the array form of SyncEnvVarsBody:

export type SyncEnvVarsBody =
  | Record<string, string>
  | Array<{
      name: string;
      value: string;
      isParentEnv?: boolean;
      isSecret?: boolean; // defaults to true for backwards compatibility
    }>;

Usage:

syncEnvVars(async () => [
  { name: "STRIPE_SECRET_KEY", value: "sk_live_…" },                   // secret (default)
  { name: "NEXT_PUBLIC_APP_URL", value: "https://app.example.com", isSecret: false },
  { name: "R2_PUBLIC_URL", value: "https://cdn.example.com", isSecret: false },
])

For Infisical specifically, the SDK already returns enough metadata to drive this — e.g. mapping secretType === "shared" or a tag/folder convention to isSecret: false.

Describe alternate solutions

  1. Read non-secret values directly from the source (Infisical/Vercel) at runtime instead of syncing — defeats the purpose of syncEnvVars and adds latency / extra auth surface.
  2. Maintain two separate stores (Trigger.dev plain env for non-secrets, Infisical for secrets) — splits the source of truth and is exactly what syncEnvVars is meant to avoid.
  3. Prefix-based hack on the consumer side (e.g. only treat SECRET_* as masked) — not viable because Trigger.dev controls dashboard rendering.

Additional information

Source pointer: packages/build/src/extensions/core/syncEnvVars.ts — the change would be additive to SyncEnvVarsBody and to the upload call that creates the env vars on the platform side. Default isSecret: true keeps existing behavior.

The same flag would also be useful for syncVercelEnvVars, where Vercel already distinguishes type: "encrypted" | "plain" and that information is currently discarded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions