> Saved a surprising amount just by turning those off.
That's the easy win. It's also the first step towards breaking something critical next month.
Your Netskope report shows what it sees. It doesn't see desktop app logins, API jobs, or contractor traffic using a VPN. You'll catch the obvious dead wood now and feel smart, right up until you kill the one Figma license your entire design team actually uses because it only connects through a client app. Ask me how I know.
Build your alert, sure. But make the rule that it only creates a ticket for a human to cross-check against IdP logs. Don't let it auto-disable anything.
-- old school
The IdP cross-check is just shifting the problem. It still misses service accounts, API keys, and any app that doesn't enforce SSO.
What's your plan for decommissioning an S3 bucket that's only accessed by a Lambda function? Your IdP has nothing on that. Blindly trusting IdP logs gives you false confidence.
Don't panic, have a rollback plan.
That point about personal credentials on company licenses is something I've been trying to get a handle on. How do you even start tracking that, beyond just enforcing SSO? If a dev is using their personal GitHub account for a Copilot seat we pay for, is that purely a policy gap, or are there technical signals you can watch for?
Nice approach, and 90 days is a good starting filter. We did something similar but used a GitHub Actions workflow to trigger the Netskope API report, then automatically open a draft PR for review. The PR description template forces us to note the IdP check and attach screenshots before merging.
That way the deprovisioning request is tied to our gitops repo, and we have a clear audit trail in the commit history. Have you thought about automating the alert into a ticketing system, or are you keeping it manual for now?
git push and pray
Integrating it with a gitops repo is clever for audit trails, but you're shifting the automation risk upstream. What happens when the PR auto-generation breaks because Netskope's API changes its pagination or rate limiting? You've now hidden the failure mode inside a CI/CD pipeline instead of a manual script.
We tried a similar Jira auto-ticket setup and had to abandon it. The false positive rate from relying solely on Netskope's API data was high enough that the ticket queue became noise and humans started ignoring it. Automation only works if the source signal is clean, and in identity management, it rarely is.
Your PR template forcing the IdP check is good. But does it also require a check against service account registries or API key logs? If not, you're still building a confidence bubble that's going to pop.
—davidr
You've nailed the core tension with any automation project: cleaning the source signal. We learned this the hard way with our first pass at automated Slack deprovisions.
We built alerts, but they were pure noise until we layered in a second check from our MDM to see if the user's company laptop had even been online in the last 90 days. Without that, we'd flag every employee on parental leave or long-term sick leave as "inactive".
The Jira queue becoming ignored is the exact failure state everyone wants to avoid. It erodes trust in the entire process. That's why, even with our current gitops flow, the final "merge" step is gated on a manual check against our internal service account registry. It's slow, but it prevents the bubble from popping.
Your point about API changes breaking the pipeline is a good one. How do you handle monitoring for that kind of upstream schema drift? We've had some luck with simple canary checks, but it's not foolproof.
The 90-day filter you've implemented is a sensible starting point, though I'd be curious about your traffic classification. Netskope's default app recognition can be broad, and for cost savings, you need to differentiate between, say, a 'Salesforce' instance used by the sales team and a 'Salesforce Marketing Cloud' instance used by a single marketer. Are you segmenting by sub-app or instance ID in your report? Without that, you risk conflating active and unused services within the same vendor umbrella, which could lead to over-provisioning the wrong licenses while still missing the true orphans.
Data doesn't lie, but folks sometimes do.
Nice to see someone else diving into the data this way. The 90-day filter is a great start, but I'd add a second layer: watch for *tiny* amounts of traffic.
We caught a few "unused" accounts that had like, two HTTP requests total in that 90-day window from some automated health check or a forgotten bookmark. That's functionally dead but could slip through a simple "zero traffic" rule.
Did you consider adding a low-threshold filter, maybe under 10 requests, to catch those zombie sessions? It cleaned up another chunk of licenses for us.
pipeline all the things