Repo Secret Provisioner
On service-account creation in Azure AD, retrieves the target repo's public key via Get A Repository Public Key, encrypts a generated secret with it, and POSTs it so GitHub Actions is pre-wired with the needed secret.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
FlowLibs - Repo Secret Provisioner is a daily-scheduled Power Automate Cloud Flow that automatically pre-wires newly created service accounts into a target GitHub repository as Actions secrets. It enumerates an Entra ID security group, filters members created inside a configurable lookback window, generates a random credential for each new account, encrypts it against the repository's public key, and pushes it to GitHub so downstream CI/CD workflows are ready to run the moment they reference the new secret.
The flow is architecturally complete and ships in the Stopped state. Activating it requires only (1) authorizing the three connection references, (2) setting the environment variable defaults for your tenant/repo, and (3) deploying the companion LibSodium encryption Azure Function (since Power Automate has no native sealed-box primitive).
Use Case
When a new service-account identity is provisioned in Entra ID for a GitHub Actions workflow, there is almost always a paired step where a human operator hand-creates a matching repository secret to carry that account's credential. That step is manual, error-prone, and a common bottleneck during onboarding. This flow closes the loop: as soon as the service account appears in the designated security group, it becomes a named GitHub secret (e.g., SA_CREDENTIAL_ALICE_SMITH) with a freshly generated value, a daily summary email is sent to the admin, and the workflow author can reference the secret by name without any backend coordination.
Flow Architecture
Daily Recurrence 9am Eastern
RecurrenceA standard Recurrence trigger that fires once per day at 09:00 Eastern Standard Time.
Environment Variable Binding (Steps 1-7)
Initialize variable (x7)Seven Initialize Variable actions hydrate local variables from solution environment variables: Service Account Group ID, Lookback Hours, GitHub Owner, GitHub Repository, Secret Name Prefix, Encryption Function URL, and Admin Email.
Compute Created-After Cutoff
ComposeComputes the ISO cutoff timestamp as addHours(utcNow(), mul(-1, int(variables('varNewAccountLookbackHours')))) so the downstream filter knows which accounts count as 'recent'.
Initialize Counters
Initialize variable (x2)varProvisionedCount (integer) and varProvisionedAccountsLog (HTML string fragment) are initialized for the email summary.
Get Service Account Group Members
Azure AD - Get group membersRetrieves up to 999 members of the configured Entra ID security group.
Filter Recently Created Service Accounts
Filter arrayNarrows the group to members whose createdDateTime is greater than or equal to the computed cutoff.
For Each New Service Account
Apply to eachFor every filtered member: (1) Get Repository Public Key via shared_github/GetRepositoryPublicKey to retrieve the current public key and key ID; (2) Compose Generated Secret Value by concatenating two GUIDs; (3) Encrypt Secret Via LibSodium Function with an HTTP POST to varEncryptionFunctionUrl, body {publicKey, keyId, secretValue}; (4) Parse Encryption Response against schema {encrypted_value, key_id}; (5) Compose Secret Name For Service Account from the UPN using toUpper(concat(prefix, replace(replace(first(split(UPN,'@')), '.', '*'), '-', '*'))); (6) Provision Secret In GitHub Repo via shared_github/CreateUpdateRepositorySecret with body/encrypted_value and body/key_id; (7) Increment varProvisionedCount and append an HTML <tr> row to varProvisionedAccountsLog.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_ServiceAccountGroupId | String | 00000000-0000-0000-0000-000000000000 | Object ID of the Entra ID security group that contains service accounts. |
| flowlibs_NewAccountLookbackHours | String | 24 | Hours back from the run time used to classify a member as 'recently created'. |
| flowlibs_GitHubOwner | String | <configure> | GitHub organization or user that owns the target repository. Set to your GitHub org/user login. |
| flowlibs_GitHubRepository | String | <configure> | Target repository name (without owner prefix). Set to the repo that should receive the secrets. |
| flowlibs_SecretNamePrefix | String | SA_CREDENTIAL_ | Prefix for generated secret names - combined with the normalized UPN. |
| flowlibs_EncryptionFunctionUrl | String | <configure> | HTTPS endpoint of the companion LibSodium encryption Azure Function. Deploy the Node 18 tweetsodium/libsodium-wrappers function and paste its full invoke URL (including code query string) here. |
| flowlibs_AdminEmail | String | <configure> | Recipient of the daily provisioning summary email. Set to an admin or distribution list address. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure AD | shared_azuread | GetGroupMembers |
| GitHub | shared_github | GetRepositoryPublicKey CreateUpdateRepositorySecret |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
| HTTP | built-in | HTTP (Direct Azure Function call for LibSodium encryption) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Changing the schedule
- Edit the Daily Recurrence 9am Eastern trigger in the designer. The Recurrence action supports any frequency (Minute / Hour / Day / Week / Month) and any time zone.
- Changing the lookback window
- Update the default value of flowlibs_NewAccountLookbackHours. For example, set 168 to scan the last 7 days, or 1 for the last hour (pair this with a more frequent recurrence).
- Targeting a different repo
- Update flowlibs_GitHubOwner and flowlibs_GitHubRepository defaults in the solution. No flow JSON edits needed.
- Changing the secret naming scheme
- Update flowlibs_SecretNamePrefix for a different prefix, or edit the Compose Secret Name For Service Account expression to change the UPN normalization rules (e.g., swap . separators for -, keep the domain, etc.).
- Different secret value source
- Replace the Compose Generated Secret Value action with any secret source (Key Vault Get secret, HTTP call to an internal credential API, etc.). Downstream actions only require the plaintext secret at that step.
- Multiple repositories
- Wrap the existing For Each New Service Account body in an outer For each over a list of repo names (stored in an array variable) to provision the same secret across multiple repos.
- Companion Azure Function
- Because Power Automate has no native LibSodium sealed-box primitive, this flow delegates the actual encryption to an external Azure Function. A minimal Node 18 implementation using the tweetsodium or libsodium-wrappers package is sufficient; it accepts {publicKey, keyId, secretValue} and returns {encrypted_value, key_id}. The Function URL is referenced exclusively via the flowlibs_EncryptionFunctionUrl environment variable, so swapping implementations requires no flow changes.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Compute Created After Cutoff
Subtracts the configured lookback hours from the current UTC time to produce the 'recently created' threshold.
EXPR.02Filter Recently Created Service Accounts (where clause)
Filter Array where clause - keeps only group members whose createdDateTime is at or after the cutoff.
EXPR.03Compose Generated Secret Value
Builds a random credential by concatenating a GUID with a hyphen-stripped GUID.
EXPR.04Compose Secret Name For Service Account
Derives a valid GitHub Actions secret name from the UPN: strips the domain, replaces '.' and '-' with '*', uppercases the result, and prepends the configured prefix.
EXPR.05Append To Provisioned Accounts Log
Appends an HTML table row (display name + generated secret name) to the running summary log used in the admin email.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.