The fastest way to turn Power Platform from an asset into a liability is to let everyone build whatever they like in the default environment, edit it live, and call that "agile." Low-code doesn't exempt you from application lifecycle management — it makes ALM more important, because the people building are often not developers. Here's the governance and ALM model that keeps a tenant healthy.

Environments: your first governance lever

An environment is an isolated container for apps, flows, connections, and (optionally) a Dataverse database. Treat environments as your dev/test/prod boundary:

Stop building business apps in the default environment. It has no separation of duties, broad maker access, and no clean promotion path. Create dedicated Dev / Test / Prod environments and restrict who can create environments at the tenant level.

Solutions: the unit of deployment

A solution is the package that carries your apps, flows, tables, and choices between environments. This is the heart of Power Platform ALM, and the managed/unmanaged distinction is the part everyone gets wrong at first:

UnmanagedManaged
Where it belongsDev onlyTest & Prod
Editable in placeYesNo (locked)
Clean uninstallNoYes — removes its components
Think of it asSource codeThe compiled build

You author in an unmanaged solution in Dev, export it as managed, and import that managed build into Test and Prod. Never develop directly in downstream environments.

Solution promotion pipeline
Dev

Unmanaged · author here

Test

Managed · validate

Prod

Managed · release

The golden path: author unmanaged in Dev, export managed, import to Test then Prod.

Publishers and prefixes

Every solution belongs to a publisher, which stamps a customization prefix (e.g. contoso_) onto the schema names of everything you create — contoso_contract, contoso_status. Set a meaningful publisher up front; the default crxxx_ prefix is ugly and permanent once components are created under it.

Environment variables & connection references

The reason "it works in Dev but breaks in Prod" is almost always hard-coded, environment-specific values. Two solution components fix this:

// In Dev — define, don't hard-code:
Environment variable  "ContractsSiteUrl"  = https://contoso.sharepoint.com/sites/dev
// At Prod import — supply the prod value:
Environment variable  "ContractsSiteUrl"  = https://contoso.sharepoint.com/sites/contracts
Connection references and environment variables are what make a managed solution truly portable. Without them, every promotion means manually re-pointing connections and editing URLs — exactly the error-prone, "who changed prod?" work ALM exists to eliminate.

Automating promotion

Two supported ways to move solutions, depending on maturity:

# Power Platform CLI — the building blocks behind a pipeline
pac solution export   --name ContractMgmt --managed false --path ./src
pac solution unpack   --zipfile ./src/ContractMgmt.zip --folder ./src/ContractMgmt
# ...commit ./src to Git, then in the pipeline:
pac solution pack     --folder ./src/ContractMgmt --zipfile ./out/ContractMgmt_managed.zip --packagetype Managed
pac solution import   --path ./out/ContractMgmt_managed.zip --environment {prod-url}

Guardrails: DLP and managed environments

Governance isn't only about promotion — it's about what makers can do:

Start governance on day one, not after the sprawl. A simple baseline — dedicated Dev/Test/Prod environments, one tenant-wide DLP policy, solutions for everything, and the CoE kit for visibility — prevents 90% of the messes I get called in to untangle.

The takeaway

Power Platform ALM is the same discipline you'd apply to any software: isolate environments, package work in solutions, author unmanaged in Dev and ship managed to Prod, parameterise the environment-specific bits, and automate promotion. Layer on DLP, Managed Environments, and the CoE kit for guardrails and visibility. None of it requires heavy code — but all of it requires the engineering mindset that "it works on my screen" is the beginning of the job, not the end.

DS

Dhaval Shah

Cloud Solution Architect — 18+ years across SharePoint, Microsoft 365, and Azure AI.