EntraID Secrets Renewal Automation
Overzicht
Deze Ansible playbook hernieuwt secrets en certificaten voor EntraID App Registrations, getriggerd via Ivanti ITSM taken. De automatisering is ontworpen voor proactieve credential lifecycle management, waarbij verlopende secrets en certificaten tijdig worden vernieuwd voordat ze expireren. Dit voorkomt downtime in geautomatiseerde processen en services die afhankelijk zijn van deze credentials.
De playbook ondersteunt twee credential types: - Secrets: Eenvoudige wachtwoorden met 365 dagen geldigheid - Certificaten: X.509 certificaten gegenereerd via PKI infrastructure met self-service rotation (addKey API)
High-Level Flow
- Ivanti Task Processing: Ontvang en verwerk Ivanti Service Request Task met AppID en SecretType parameters
- EntraID Credentials Ophalen: Authenticatie credentials ophalen uit Passwordstate voor de juiste tenant
- App Registration Info Lookup: Application details ophalen via Microsoft Graph API
- Tenant Switching: Indien onderwijs tenant, switch naar andere Azure subscription en tenant
- Credential Type Routing:
- Voor Secrets: Nieuwe password genereren via Azure RM module
- Voor Certificaten: Volledig PKI workflow met certificate generation en addKey API
- Passwordstate Update: Nieuwe credential opslaan in Passwordstate met metadata
- Task Completion: Ivanti task afsluiten met status en notities
Sequence Diagram
sequenceDiagram
participant Scan as Scanning Playbook
participant Ivanti as Ivanti ITSM
participant Ansible as Ansible Tower
participant PWS as Passwordstate
participant Azure as EntraID/Graph API
participant PKI as PKI Infrastructure
Note over Scan,Ivanti: Scheduled scanning identifies expiring credentials
Scan->>Ivanti: Create Service Request Task<br/>(AppID, SecretType, Days)
Note over Ivanti,Ansible: Renewal automation triggered
Ivanti->>Ansible: Task available for processing
Ansible->>Ivanti: Retrieve Task details (verwerk_task)
Ivanti-->>Ansible: Task info (AppID, SecretType)
Ansible->>PWS: Get EntraID API credentials
PWS-->>Ansible: Graph API credentials
Ansible->>Azure: Get App Registration info
Azure-->>Ansible: App details (app_id, object_id, display_name)
alt Secret Renewal
Ansible->>PWS: Check Passwordstate entry exists
PWS-->>Ansible: Entry found (or not)
alt Entry exists
Ansible->>Azure: Create new password (azure_rm_adpassword)
Azure-->>Ansible: New secret value + metadata
Ansible->>PWS: Update Passwordstate entry
PWS-->>Ansible: Update success
Ansible->>Ivanti: Close task (success)
else Entry not found
Ansible->>Ivanti: Assign to Systeemsoftware + Add Note
Ivanti-->>Ansible: Task assigned
end
else Certificate Renewal
Ansible->>PWS: Get PKI credentials
PWS-->>Ansible: PKI service account
Ansible->>PWS: Check certificate entry exists
PWS-->>Ansible: Certificate entry + GenericField7 JSON
alt Onderwijs tenant special handling
Ansible->>PWS: Check for alternative cert name<br/>(without _OND suffix)
PWS-->>Ansible: Alternative cert found
Ansible->>Ivanti: Assign to Systeemsoftware<br/>(manual upload required)
end
Ansible->>PWS: Get OLD certificate PFX document
PWS-->>Ansible: PFX file + password
Ansible->>PKI: Generate NEW certificate<br/>(pki_certificate role)
PKI-->>Ansible: New PFX file + PublicKey
Note over Ansible: Self-service rotation with addKey API
Ansible->>Ansible: Generate client_assertion JWT<br/>(OLD certificate)
Ansible->>Azure: Get access token<br/>(certificate authentication)
Azure-->>Ansible: Access token
Ansible->>Ansible: Generate PoP token<br/>(Proof-of-Possession)
Ansible->>Azure: POST /applications/{id}/addKey<br/>(New cert + PoP token)
alt addKey Success
Azure-->>Ansible: Certificate added (200 OK)
Ansible->>PWS: Update certificate entry<br/>(new PFX document)
Ansible->>Ivanti: Close task (success)
else addKey Failure
Azure-->>Ansible: Error response
Ansible->>Ivanti: Assign to Systeemsoftware + Add Note
end
end
Components
1. Ivanti ITSM Integration
- Collection:
d09.ivanti_itsm - Roles/Modules:
verwerk_task: Retrieve task details from Service Request (pws_list_id: 8620)assign_task: Assign failed tasks to Systeemsoftware teamadd_note: Add status updates to tasks (success/failure)close_task: Close successfully completed tasks
Task Input Parameters (servicereq_params):
- AppID: EntraID Application (Client) ID to renew credentials for
- SecretType: Type van credential (Secret of Certificaat/Cert)
2. Passwordstate Integration
- Collection:
d09.passwordstate - Password Lists:
- 8620: Systeem Accounts (PKI credentials, Ansible credentials)
- 6691: Certificaten > EntraID ServicePrincipal Certificaten
- 7651: Systeem_EntraID_AppReg_PR (production secrets)
- 8633: Systeem_Azure_OND_Admin (onderwijs secrets)
Key Operations: - Retrieve EntraID API credentials (Sys_Azure_AppRegs_PR / Sys_Azure_OND_Admin) - Retrieve PKI service account (sys_srvaapwin_pki) - Check Passwordstate entry exists for App Registration - Update Passwordstate with new secret/certificate values - Retrieve and upload PFX documents
3. EntraID / Microsoft Graph API
- Collection:
azure.azcollection - Modules:
azure_rm_adapplication_info: Retrieve App Registration detailsazure_rm_adpassword: Create new secret for App Registration
Manual API Calls:
- Certificate Authentication: POST /oauth2/v2.0/token with client_assertion JWT
- addKey API: POST /applications/{id}/addKey with Proof-of-Possession token
4. PKI Certificate Generation
- Role:
d09.certificates.pki_certificate - Target System: srvaapwinpr01.gentgrp.gent.be (Windows PKI server)
- Default Template:
_D09-CA2-SHA256-EntraID - Output: New PFX file with certificate + private key uploaded to Passwordstate
5. Tenant Configuration
Production Tenant (default):
- Tenant ID: {{ azure_tenant }}
- Subscription ID: Default subscription
- Passwordstate List: 7651 (Systeem_EntraID_AppReg_PR)
Onderwijs Tenant (onderwijs flag set):
- Tenant ID: Switched via conditional
- Subscription ID: Switched via conditional
- Passwordstate List: 8633 (Systeem_Azure_OND_Admin)
- Special handling voor certificaten (naam zonder _OND suffix)
Renewal Process Details
Secret Renewal (Secrets)
- Passwordstate Validation: Check of Passwordstate entry bestaat voor App Registration naam
- Azure RM Password Creation:
- Module:
azure.azcollection.azure_rm_adpassword - Validity: 365 dagen (
days_secret_validvariable) - Output:
secret_value,key_id,end_date - Passwordstate Update: Update GenericField6 met JSON metadata:
- Task Closure: Ivanti task sluiten met resolution note
Failure Handling: - Als Passwordstate entry niet bestaat → Assign to Systeemsoftware - Bij Azure RM fouten → Rescue block vangt error op
Certificate Renewal (Certificaten)
- PKI Credentials: Ophalen service account (sys_srvaapwin_pki) uit Passwordstate list 8620
- Certificate Entry Validation: Check Passwordstate entry in list 6691
- Title format:
Certificaat {AppDisplayName} - GenericField7 bevat JSON met certificaat metadata (UsedTemplate)
- Onderwijs Special Handling:
- Check voor alternatieve certificaat entry zonder
_ONDsuffix - Als gevonden → Assign to Systeemsoftware (manual upload required)
- OLD Certificate Retrieval:
- Query SQL database voor PFX DocumentID via
win_powershell(SQL query) - Download OLD PFX document uit Passwordstate
- NEW Certificate Generation:
- Role:
d09.certificates.pki_certificate - Template uit GenericField7 of default
_D09-CA2-SHA256-EntraID - Output: Nieuwe PFX file geupload naar Passwordstate
- Self-Service Rotation (addKey API):
- Step 1: Generate
client_assertionJWT met OLD certificate- Script:
generate_jwt_token.py(TOKEN_TYPE=client_assertion) - Claims: aud, iss, sub, jti, exp
- Script:
- Step 2: Get access token via certificate authentication
- Endpoint:
POST /oauth2/v2.0/token - Body: client_id, client_assertion, grant_type=client_credentials
- Endpoint:
- Step 3: Generate Proof-of-Possession (PoP) token
- Script:
generate_jwt_token.py(TOKEN_TYPE=pop) - Claims: sub, iss (beide object_id), aud=00000002-0000-0000-c000-000000000000
- Script:
- Step 4: Call addKey API
- Endpoint:
POST /applications/{object_id}/addKey - Headers:
Authorization: Bearer {access_token} - Body:
keyCredential(new cert public key) +proof(PoP token)
- Endpoint:
- Success/Failure Handling:
- Success (200 OK): Update Passwordstate + Close task
- Failure: Assign to Systeemsoftware + Add error note
Failure Scenarios: - Passwordstate entry niet gevonden → Assign to Systeemsoftware - Alternatieve EDU cert gevonden → Manual upload required - addKey API fout (bijv. PoP validation failed) → Assign to Systeemsoftware
Error Handling
Rescue Block
- Vangt alle errors tijdens secret/certificate renewal proces
- Set
secret_renewal.success = false - Set
noteErrormet error details
Always Block (Cleanup/Finalization)
Executed regardless of success/failure:
1. Set success flag: secret_renewal_success = true (only if renewal succeeded)
2. Extract error message: Set noteError from secret_renewal.error
3. Add failure note: If secret_renewal_success == false, add note to Ivanti task
4. Assign to team: If failed, assign task to Systeemsoftware for manual intervention
5. Close task: If successful, close Ivanti task with resolution
Python Script Requirements
generate_jwt_token.py
Purpose: Generate JWT tokens voor EntraID certificate authentication
Token Types:
- client_assertion (Client Authentication JWT):
- Environment variables: TOKEN_TYPE, PFX_PATH, PFX_PASSWORD, TENANT_ID, CLIENT_ID
- Claims: aud, iss, sub (CLIENT_ID), jti, exp
- Signing: Privésleutel uit OLD PFX file
-
Usage: Authenticate App Registration met certificate
-
pop (Proof-of-Possession Token):
- Environment variables: TOKEN_TYPE, PFX_PATH, PFX_PASSWORD, TENANT_ID, SUB_ID, ISS_ID, AUD
- Claims: sub (object_id), iss (object_id), aud (Graph API resource: 00000002-0000-0000-c000-000000000000), jti, exp
- Signing: Privésleutel uit OLD PFX file
- Usage: Prove ownership van OLD certificate voor addKey API authorization
Script Location: Must be accessible from Ansible control node (localhost delegation)
Ivanti Integration Details
Input (Service Request Task Parameters)
task_info.servicereq_params:
AppID: "12345678-1234-1234-1234-123456789abc"
SecretType: "Secret" # or "Certificaat" / "Cert"
Output Actions
Success Scenario:
- Close Task: d09.ivanti_itsm.close_task
- Resolved by: Ansible API user
- Resolution: "Secret/Certificate renewed successfully for {AppDisplayName}"
- Time spent: 1 minuut
Failure Scenario:
- Assign Task: d09.ivanti_itsm.assign_task → Systeemsoftware team
- Add Note: d09.ivanti_itsm.add_note
- Subject: "Secret/Certificaat renewal failed"
- Body: Error details (Passwordstate entry not found, addKey failure, etc.)
- Category: Status Update
- Time spent: 1 minuut
Benefits
- Proactieve Credential Management: Voorkomt service downtime door automatische renewal voordat credentials expireren
- Self-Service Certificate Rotation: addKey API elimineert handmatige interventie voor certificaat renewal
- Multi-Tenant Support: Seamless ondersteuning voor production én onderwijs tenants
- Passwordstate Integration: Centrale credential storage met automatische updates
- Ivanti Workflow: Volledige traceability via Service Request Tasks met status updates
- Error Handling: Robuuste rescue/always blocks zorgen voor proper task status updates bij failures
- Security: Certificate-based authentication (client_assertion + PoP tokens) voor Graph API calls
- Audit Trail: Alle acties gelogd in Ivanti met timestamps en team assignments