Our quarterly access review process used to be a three-week odyssey of spreadsheets, manual verification, and stakeholder nagging. It was a classic case of a necessary control being so burdensome that it encouraged shortcuts. Since integrating Delinea's Secret Server and its PAM Command API into our CI/CD pipeline, we've transformed it into a largely automated, evidence-based workflow that completes in under 48 hours. The key shift was moving from asking "Who has access?" to continuously validating "Who *needs* this access, and can prove it?"
We built a system that treats access as ephemeral, requiring justification. The core of the automation is a Python service that, triggered by our scheduler, executes the following steps:
1. **Inventory & Correlation:** It pulls a current list of all non-personal secrets from Delinea's API, then correlates them with our CMDB and IAM systems to generate a matrix of `(secret, user/role, business_context)`.
2. **Ticket Generation:** For each unique `(user, business_context)` combination, it creates a ticket in Jira Service Management, assigned to the relevant application or team owner. The ticket contains specific secret names and a link to the automated justification portal.
3. **Justification Workflow:** The team owner accesses a simple internal portal. They must either:
* **Attest:** Select a pre-approved justification (e.g., "Production deployment service account," "Quarterly financial reconciliation") and specify a renewal period (1-4 quarters).
* **Revoke:** Initiate an immediate revocation, which triggers an automated API call to Delinea to remove the user/group from the secret's permissions.
4. **Evidence Capture & Enforcement:** All attestations are logged with timestamp, user, and selected justification in a read-only audit database. If a ticket lapses past the deadline with no action, the system escalates it and, if still unresolved, initiates a revocation workflow as a safety measure.
The critical technical component is Delinea's REST API, which allows us to manage permissions programmatically. A simplified version of our revocation script is below:
```python
import requests
from delinea_api import SecretServer # Internal wrapper class
def revoke_access(secret_id, user_principal):
ss = SecretServer()
# Fetch current secret permissions
secret = ss.get_secret(secret_id)
permissions = secret['permissions']
# Find and remove the specific user's permission entry
new_permissions = [
p for p in permissions
if not (p['userId']['username'] == user_principal or p['groupId']['name'] == user_principal)
]
# Update secret with revised permissions
if len(new_permissions) != len(permissions):
update_payload = {'permissions': new_permissions}
ss.update_secret(secret_id, update_payload)
log_audit_event(secret_id, "REVOKED", user_principal)
return True
return False
```
**Results & Pitfalls:**
* **Reduced Scope:** Over four quarters, we've reduced standing privileged access by approximately 65% by forcing the "why" conversation.
* **Audit Ready:** We now have a immutable audit trail linking every secret access to a business justification, not just an owner's signature on a spreadsheet.
* **Key Pitfall:** The initial mapping of secrets to business owners was a significant, manual effort. We underestimated the data hygiene required in our CMDB. Garbage in, garbage out.
* **Necessary Complement:** This works because Delinea is our system of record for *privileged* credentials. It does not replace our broader IGA tool for standard user account reviews. They are complementary processes.
This approach has shifted the cultural mindset. Access is now viewed as a temporary grant requiring periodic re-validation, not a permanent entitlement. The automation removes the toil, allowing our security team to focus on investigating anomalies rather than chasing down managers for signatures.
-- alex
This is fascinating! I've only ever seen access reviews done with huge spreadsheets. The jump from "who has it" to "who needs it and can prove it" is a game changer. Makes total sense.
Quick question about the ticket generation step: how do you handle it when the secret owner is ambiguous? Like, if a secret is shared between two teams? Do you have a fallback or does it require manual tagging first?
The ephemeral access model is solid. We tried something similar but had to harden the correlation step because our CMDB data was too stale to trust for automated justification. The system started generating tickets for decomissioned services, creating noise that made stakeholders ignore the whole process.
We fixed it by adding a verification gate that checks the last deployment date and monitoring alert volume for the associated service before ticket creation. If the service hasn't been deployed in over two quarters and has zero alerts, it routes to a security engineer for manual review instead of auto-generating a ticket. This cut our false-positive justification requests by about 70%.
Your point about shifting from "who has it" to "who needs it" is key, but the evidence chain is only as good as the data you're correlating against.