arazzo: 1.0.1 info: title: Microsoft Entra Rotate Application Secret summary: Add a fresh client secret to an app, then remove the old one. description: >- Performs a zero-downtime client secret rotation for an application registration in Microsoft Entra ID. A new password credential is added first (the response carries the secretText that is only ever returned at creation time), and only then is the previous secret removed by keyId so callers always have at least one valid credential during the swap. Every request is written inline so the rotation reads end to end. version: 1.0.0 sourceDescriptions: - name: graphIdentityApi url: ../openapi/microsoft-entra-graph-identity-openapi.yml type: openapi workflows: - workflowId: rotate-application-secret summary: Add a new client secret then revoke the prior secret by keyId. description: >- Adds a new password credential to an application and removes the old credential, ensuring continuous coverage during the rotation. inputs: type: object required: - accessToken - applicationId - newSecretDisplayName - oldKeyId properties: accessToken: type: string description: OAuth 2.0 bearer token with Application.ReadWrite.All. applicationId: type: string description: Object id of the application (not the appId). newSecretDisplayName: type: string description: Friendly name for the new password credential. endDateTime: type: string description: Expiry timestamp for the new secret (ISO 8601 date-time). default: "2027-01-15T10:30:00Z" oldKeyId: type: string description: keyId of the existing password credential to remove. steps: - stepId: addSecret description: >- Add a new password credential to the application and capture the one-time secretText from the response. operationId: addApplicationPassword parameters: - name: Authorization in: header value: "Bearer $inputs.accessToken" - name: application-id in: path value: $inputs.applicationId requestBody: contentType: application/json payload: displayName: $inputs.newSecretDisplayName endDateTime: $inputs.endDateTime successCriteria: - condition: $statusCode == 200 outputs: newKeyId: $response.body#/keyId secretText: $response.body#/secretText - stepId: removeOldSecret description: >- Remove the prior password credential by keyId now that the replacement is in place. operationId: removeApplicationPassword parameters: - name: Authorization in: header value: "Bearer $inputs.accessToken" - name: application-id in: path value: $inputs.applicationId requestBody: contentType: application/json payload: keyId: $inputs.oldKeyId successCriteria: - condition: $statusCode == 204 outputs: removeStatus: $statusCode outputs: newKeyId: $steps.addSecret.outputs.newKeyId secretText: $steps.addSecret.outputs.secretText