Cloud Flows: Security, Errors & Child Flows
Harden your cloud flows for production. Learn to secure sensitive data, handle errors with try/catch patterns, build reusable child flows, and use Azure Key Vault and service principals.
Production-grade flows
Think of hardening a flow like childproofing a house.
A flow that works in testing is like a house with no safety features. To make it production-ready, you need: locks on cabinets (secure sensitive data), smoke alarms (error handling β know when things go wrong), instruction manuals (child flows β reusable steps anyone can follow), and spare keys with trusted neighbours (service principals β flows that work even when the builder leaves).
Securing sensitive data
Secure inputs and outputs
By default, flow run history shows every input and output value. For sensitive data (passwords, tokens, personal info), this is a security risk.
Secure Inputs: Hides the actionβs input values in run history. Secure Outputs: Hides the actionβs output values in run history.
Enable them in the actionβs Settings tab. When enabled, run history shows βContent not shown due to security configurationβ instead of the actual values.
Azure Key Vault integration
For secrets that flows need (API keys, connection strings, certificates), use Azure Key Vault instead of hardcoding values.
Pattern:
- Store the secret in Azure Key Vault
- Add the βAzure Key Vaultβ connector to your flow
- Use the βGet secretβ action to retrieve the value at runtime
- Enable Secure Outputs on the Get secret action (so the value does not appear in run history)
| Method | Hardcoded in Flow | Environment Variable | Azure Key Vault |
|---|---|---|---|
| Security | Visible in flow definition | Visible in admin centre | Encrypted, access-controlled |
| Rotation | Edit every flow that uses it | Update the variable value | Update in Key Vault β flows get new value automatically |
| Audit trail | No | No | Yes β Key Vault logs every access |
| Best for | Never β do not hardcode secrets | Non-sensitive config (URLs, emails) | Secrets (API keys, passwords, tokens) |
Error handling patterns
The Scope pattern (try/catch/finally)
Power Automate does not have native try/catch, but you can build it with Scopes:
Scope: Try
βββ Action 1 (call API)
βββ Action 2 (process result)
βββ Action 3 (update Dataverse)
Scope: Catch (Configure Run After = "has failed", "has timed out")
βββ Log error to Dataverse
βββ Send alert email
Scope: Finally (Configure Run After = "is successful", "has failed", "has timed out", "is skipped")
βββ Clean up temporary data
Configure Run After is the key: by default, each action runs only after the previous one succeeds. To create a βcatchβ block, configure the Catch scope to run after the Try scope has failed or timed out.
Error handling best practices
- Always wrap critical logic in a Try scope β unhandled errors leave flows in a βFailedβ state with no recovery
- Log errors to a Dataverse table β not just email notifications (emails get lost)
- Include context in error logs β which record, which step, what error message
- Use the result() function to get error details:
result('Try_Scope')[0]?['error']?['message']
Child flows
Child flows are reusable flows called by parent flows. They accept inputs and return outputs.
When to use child flows
- Same logic in multiple flows β βSend formatted notificationβ used by 5 parent flows
- Complex flows that are hard to read β break into logical child flows for clarity
- Different teams own different parts β one team owns the child flow, parent flows just call it
Creating a child flow
Important: Child flows must be created inside a solution. Both parent and child flows should be in the same solution for the βRun a Child Flowβ action to work.
- Open your solution in make.powerautomate.com β Solutions
- Create a new cloud flow with the βManually trigger a flowβ trigger
- Define input parameters (text, number, yes/no, file, email)
- Build the logic
- End with a βRespond to a PowerApp or flowβ action to return outputs
- In the parent flow (also in the solution), use βRun a Child Flowβ action
Scenario: Elena builds reusable error handling
Elena creates a child flow called βLog Integration Errorβ that:
Inputs: ErrorSource (text), ErrorMessage (text), RecordId (text), Severity (text) Logic:
- Creates a record in the Integration_Log table with all input details + timestamp
- If Severity = βCriticalβ, sends a Teams message to the IT Ops channel
- If Severity = βCriticalβ and it is outside business hours, sends an SMS via the Twilio connector
Now every parent flow in the organisation calls this child flow in its Catch scope. One place to maintain error handling logic, consistent logging, and automatic escalation.
Service principals for flows
A service principal is an application identity (not tied to a person) used for flow connections.
Why service principals matter
- User leaves β Flows using their connection break. Service principal connections persist.
- Licence changes β User loses Power Automate licence β their flows stop. Service principal is independent.
- Security audit β Service principal permissions are clearly defined and auditable.
Setting up a service principal connection
- Register an application in Microsoft Entra ID
- Create a client secret or certificate
- Create an application user in Dataverse with appropriate security roles
- In Power Automate, create a connection using the service principal credentials
- Map connection references to this connection in your solutions
A flow retrieves an API key from Azure Key Vault and uses it to call an external service. After running, the API key is visible in the flow run history. What should the developer do?
Next up: Publishing Dataverse Events β sending events to external systems with webhooks, Service Bus, and Event Hub.