Skip to content

02 Authentication

RemyDuijkeren edited this page Jun 19, 2026 · 14 revisions

Authentication

Flowline delegates all authentication to PAC CLI. No credentials are stored in Flowline config files. Set up auth once via pac auth create — Flowline reads the PAC profile and derives credentials automatically.


PAC profile types

PAC CLI stores auth state in profiles. Flowline reads these profiles to connect to Dataverse.

Kind Created by What it stores When to use
UNIVERSAL pac auth create --environment <url> User identity, MSAL token cache Interactive developer — personal credentials, browser sign-in
ServicePrincipal pac auth create --applicationId <id> --tenant <tenant> App registration ID and tenant CI/CD pipelines, headless automation

Run pac auth list to see all profiles. The * marker shows which profile is active for its kind.


Setup — interactive developer (UNIVERSAL)

Authenticate once against your DEV environment:

pac auth create --environment https://yourorg-dev.crm4.dynamics.com --name "Dev"

Flowline reuses the PAC token cache — no extra auth step needed.

Multiple environments

Create one profile per environment and switch as needed:

pac auth create --environment https://yourorg-dev.crm4.dynamics.com --name "Dev"
pac auth create --environment https://yourorg-test.crm4.dynamics.com --name "Test"
pac auth create --environment https://yourorg.crm4.dynamics.com --name "Prod"
pac auth list
pac auth select --index 2

Tokens are cached and refreshed automatically. Re-authenticate when a token expires (typically after a password change or 90 days of inactivity):

pac auth create --environment https://yourorg-dev.crm4.dynamics.com

Setup — service principal for CI/CD

PAC CLI is a hard requirement — add it to your pipeline image. Authenticate with a service principal before running any Flowline commands:

pac auth create --applicationId $CLIENT_ID --tenant $TENANT_ID --name "CI"

Store CLIENT_ID and TENANT_ID as pipeline variables. The client secret is not passed to pac auth create — it is passed to Flowline via an environment variable (see below).

Why AZURE_CLIENT_SECRET must be an env var

Never store the client secret in .flowline or pass it as a CLI argument.

  • CLI args are visible in process lists. On Linux and Mac, any user on the machine can read running process arguments via ps. On Windows, tools like Process Explorer expose them. A secret passed as --secret <value> is world-readable for the lifetime of the process.
  • Env vars are masked in CI logs. GitHub Actions, Azure Pipelines, and most CI systems automatically redact secret environment variables from log output. A --secret flag does not get this treatment.

Set the secret as a pipeline secret variable and export it to the environment:

# GitHub Actions
- run: flowline generate
  env:
    AZURE_CLIENT_SECRET: ${{ secrets.DATAVERSE_CLIENT_SECRET }}
# Azure Pipelines
- task: Bash@3
  env:
    AZURE_CLIENT_SECRET: $(DataverseClientSecret)
  inputs:
    script: flowline generate

Flowline reads AZURE_CLIENT_SECRET from the process environment automatically when an SP profile is active.


Setup — manual SP override on generate

Use --client-id and --secret to pass SP credentials directly to generate when no PAC SP profile is available. The PAC profile is still read for environment URL resolution — these flags only affect the credentials forwarded to the generator subprocess.

# --secret alone: PAC SP profile supplies client ID and tenant; flag overrides the secret
flowline generate --secret $MY_SECRET

# --client-id + --secret together: override both credential values
flowline generate --client-id <app-id> --secret <secret>

Rules:

  • --secret alone requires an SP (ServicePrincipal) profile — error if the active profile is UNIVERSAL.
  • --client-id without --secret is an immediate error.
  • For CI, prefer AZURE_CLIENT_SECRET env var over --secret (see above).

Generator auth path matrix

Flowline supports three generators. Each derives auth differently.

Generator UNIVERSAL — Windows UNIVERSAL — Linux/Mac ServicePrincipal
PAC (pac modelbuilder build) PAC CLI handles its own auth — no extra setup PAC CLI handles its own auth PAC CLI handles its own auth
XrmContext v4 DefaultAzureCredentialSharedTokenCacheCredential finds PAC MSAL cache automatically DefaultAzureCredential → falls through to AzureCliCredential or InteractiveBrowserCredential AZURE_CLIENT_ID + AZURE_TENANT_ID injected from PAC profile; AZURE_CLIENT_SECRET from env var
XrmContext3 (bridge, Windows only) Browser OAuth via PAC CLI App ID — browser opens once, ADAL caches the token for subsequent runs Not supported ClientSecret method using ApplicationId from profile + AZURE_CLIENT_SECRET env var (see note below)

XrmContext3 SP in non-interactive mode: the ClientSecret path is pending verification (Q1 in the implementation plan). If it does not work, XrmContext3 cannot be used for SP auth in CI — upgrade to XrmContext v4, which has full SP support on all platforms.

PAC CLI App ID for XrmContext3

XrmContext3 uses the PAC CLI App ID (51f81489-12ee-4a9e-aaae-a2591f45987d) for browser OAuth. This is a Microsoft-registered multi-tenant app with Dataverse permissions pre-consented in Microsoft tenants. No custom app registration is required. XrmContext3 is a bridge generator being phased out — use XrmContext v4 for new setups.


Profile resolution order

When Flowline connects to a Dataverse environment, it selects a PAC profile in this order:

  1. URL match — find all profiles whose environment URL matches the target.
  2. Active preference — prefer the profile PAC has marked as active (Current[Kind] in the profile store). This is the same profile pac push would use.
  3. UNIVERSAL fallback — if no URL-specific profile matches, fall back to the active UNIVERSAL profile.
  4. Ambiguous picker — if multiple profiles match and none is active:
    • Interactive mode: a profile picker lists all candidates (name, kind, URL). Select one.
    • Non-interactive mode: error with the candidate list; run pac auth select to set one active.
  5. Error — if no profile matches at all (see troubleshooting below).

Flowline always shows which profile was selected before connecting:

Using PAC profile 'Dev' (UNIVERSAL)
Using PAC profile (unnamed, ServicePrincipal) — https://yourorg-dev.crm4.dynamics.com/

Platform notes

Windows

  • XrmContext v4 UNIVERSAL: DefaultAzureCredential uses SharedTokenCacheCredential, which finds PAC CLI's MSAL token cache automatically. Zero extra setup required after pac auth create.
  • XrmContext3 UNIVERSAL: opens a browser once via ADAL OAuth. ADAL caches the token; subsequent runs are silent.

Linux and Mac

  • XrmContext v4 UNIVERSAL: SharedTokenCacheCredential is Windows-only. DefaultAzureCredential falls through to AzureCliCredential (requires az login) or InteractiveBrowserCredential (opens a browser).
  • XrmContext3: only supported on Windows.
  • PAC generator and XrmContext v4 — SP profile: works the same across platforms — inject AZURE_CLIENT_SECRET and the generator handles it. XrmContext3 has no Linux/Mac support at all.

Troubleshooting

No PAC auth profile found for <url>

No PAC profile matches the target environment URL. Create one:

pac auth create --environment https://yourorg-dev.crm4.dynamics.com --name "Dev"

The suggested profile name in the error message is derived from the URL host segment (yourorg-dev.crm4.dynamics.comYourorg-Dev). You can use any name you like.


Multiple PAC profiles match <url> (non-interactive)

Multiple profiles are registered for the same URL and none is marked active. Set one as active:

pac auth list
pac auth select --index <n>

Then re-run the Flowline command.


AZURE_CLIENT_SECRET is required

An SP profile is active but no client secret was found. Resolve via env var (recommended for CI):

export AZURE_CLIENT_SECRET=<your-secret>   # Linux/Mac
$env:AZURE_CLIENT_SECRET = "<your-secret>"  # PowerShell

Or pass it inline for a single run (avoid in CI — visible in process lists):

flowline generate --secret <your-secret>

--secret requires a service principal profile

--secret was passed but the active PAC profile is UNIVERSAL (not SP). Either:

  • Switch to an SP profile: pac auth select --index <n>
  • Or pass --client-id alongside --secret to supply full SP credentials directly: flowline generate --client-id <app-id> --secret <secret>

PAC profile '<Name>' token may be expired

Flowline detected that the profile's token expiry is in the past. It will still attempt to connect (PAC may refresh the token silently), but if the connection fails this is the likely cause. Refresh the profile:

pac auth create --environment <url>

PAC CLI version error

If the PAC profile file is missing, unreadable, or has an unexpected format, Flowline shows the PAC CLI version and asks you to update:

dotnet tool update --global Microsoft.PowerApps.CLI.Tool
# or
winget upgrade Microsoft.PowerAppsCLI

If updating does not help, open an issue and include the PAC CLI version shown in the error message.


See also

Clone this wiki locally