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?
🎬 Video coming soon
Next up: Publishing Dataverse Events — sending events to external systems with webhooks, Service Bus, and Event Hub.