OAuthTriage is a local-first CLI for triaging risky third-party OAuth grants in Google Workspace.
It scans active users, lists their OAuth grants, enriches them with recent token activity when available, ranks risky grants first, and exports a CSV you can review before revoking access.
Security tooling loses trust fast when it asks admins to paste powerful tokens into a hosted website.
OAuthTriage starts with a simpler and safer model:
- Run locally
- Keep the access token on the operator's machine
- Export a plain CSV
- Make revocation an explicit separate command
Required Google scopes:
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.user.security
https://www.googleapis.com/auth/admin.reports.audit.readonly
The Reports scope is optional, but without it last_activity_at will often be blank.
Run directly with npx:
npx oauthtriage sample --out oauthtriage-sample.csvOr install globally:
npm install -g oauthtriage
oauthtriage sample --out oauthtriage-sample.csvGOOGLE_ACCESS_TOKEN="ya29..." npx oauthtriage scan --out oauthtriage.csvUseful options:
GOOGLE_ACCESS_TOKEN="ya29..." npx oauthtriage scan --max-users 25 --out oauthtriage-test.csv
GOOGLE_ACCESS_TOKEN="ya29..." npx oauthtriage scan --no-audit --out oauthtriage.csvRevoke one grant after review:
npx oauthtriage revoke \
--token "ya29..." \
--user founder@example.com \
--client 1234567890-abc.apps.googleusercontent.com \
--yesThe Next.js app is included as a local-only companion UI.
npm install
npm run devOpen http://localhost:3000.
Do not deploy the scanner UI as a public hosted service unless you are ready to do proper OAuth verification, secure token storage, audit logging, and customer-facing trust work.
The CSV is optimized for one job: deciding what to revoke first.
Important columns:
risk_level,risk_scoreactionapp_name,client_id,user_emailsensitive_scopeslast_activity_atrevoke_command
Admin token
-> local CLI / local UI
-> Google Directory API (users + tokens)
-> Reports API token activity
-> risk scoring
-> CSV
Core modules:
src/lib/scan-options.ts: normalize and validate external inputssrc/lib/google-http.ts: Google API request wrapper with bounded retriessrc/lib/google.ts: Workspace scan orchestration and audit enrichmentsrc/lib/risk.ts: risk scoring heuristicssrc/lib/csv.ts: CSV serializationcli/oauthtriage.ts: CLI entrypoint
npm install
npm test
npm run buildPackage dry-run:
npm pack --json --dry-runThis repository is set up for tag-based GitHub releases.
- Push a tag like
v0.1.0 - GitHub Actions runs tests and builds the package
- The workflow creates a GitHub Release and attaches the npm tarball
- npm publish is prepared for trusted publishing when an npm account is connected
Things this project intentionally does:
- Fail early on missing required input
- Bound retries for transient Google API failures
- Continue scanning without audit enrichment if the Reports API is unavailable
- Keep revoke as an explicit command instead of an automatic side effect
Things this project intentionally does not do:
- Host your token
- Auto-revoke grants
- Hide what scopes it needs
- Publish internal go-to-market or private ops notes in the public repo
This repo is safe to open-source only if you keep it free of:
- Real tokens
- Private customer data
- Local absolute paths that reveal personal environment details
- Internal-only pricing, outreach, or unpublished business notes
That content belongs outside the public repository.