Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IdentityTide (AccessDrift)

Provider-agnostic identity observability for detecting identity control drift, privilege creep, and related risky access patterns over time.

IdentityTide’s core engine is never aware of the identity provider. Provider-specific logic lives behind adapters (e.g., Entra ID / Microsoft Graph).

What this tool does

Identity systems evolve: temporary access becomes permanent, roles accumulate, offboarding is incomplete, and “emergency” elevation persists. IdentityTide tracks identity/entitlement/assignment state over time and produces:

  • Snapshots of identities, entitlements, assignments, and (optionally) activity
  • Time-series change events between snapshots (added/removed/updated)
  • Drift findings (MVP)
    • Privilege creep (privileged entitlement count increased since last snapshot)
    • Dormant privileged identities (privileged but no recent activity)
  • Explainable risk scoring (deterministic, auditor-friendly)
  • Policy-as-code evaluation (JSON policies; violations are explicit)

Repository layout

cli/        # CLI entrypoints
core/       # Provider-agnostic models + drift/risk/policy engines
providers/  # Provider adapters (entra/, okta/, google_workspace/, mock/)
storage/    # Local snapshot + event storage (default location)
policies/   # Policy-as-code JSON
tests/      # Minimal unit tests

Canonical identity model

The engine operates on a canonical model independent of providers:

  • Identity: id, type (user/service/admin), display_name, manager_id, status, source
  • Entitlement: id, name, category (role/group/permission), privilege_level, scope
  • Assignment: identity_id, entitlement_id, assigned_at, expires_at, assignment_type, justification, source_ticket
  • ActivityEvent: identity_id, occurred_at, action

Provider adapters map native objects (Graph/Okta/etc.) into this model.

Quickstart

Requirements

  • Python 3.12+

No external Python dependencies are required for the MVP (the Entra adapter uses the standard library urllib).

Run with the mock provider (no credentials)

python -m cli scan --provider mock --out "storage\\report.json"

You should see a brief summary printed and a full JSON report written to storage/report.json.

Using Entra ID (Microsoft Graph)

The Entra adapter uses client credentials to call Microsoft Graph.

1) Create an Entra app registration

Create an app registration and a client secret, then grant the app the permissions required to read:

  • Users
  • Groups
  • Directory roles
  • (Optional) Audit logs for activity telemetry

Exact permissions depend on tenant policy; the adapter will return empty activity if audit log access is not granted.

2) Set environment variables

$env:AZURE_TENANT_ID="<tenant-guid>"
$env:AZURE_CLIENT_ID="<app-client-id>"
$env:AZURE_CLIENT_SECRET="<client-secret>"

3) Run a scan

python -m cli scan --provider entra --out "storage\\entra-report.json"

## Using Okta

The Okta adapter uses the Okta Core API with an API token.

### 1) Set environment variables

```powershell
$env:OKTA_ORG_URL="https://your-org.okta.com"
$env:OKTA_API_TOKEN="<api-token>"

2) Run a scan

python -m cli scan --provider okta --out "storage\\okta-report.json"

Notes:

  • Groups and group memberships are collected via /api/v1/groups and related membership endpoints.
  • Okta admin roles are inferred via per-user role listings (/api/v1/users/{id}/roles) and represented as canonical entitlements.
  • Activity is best-effort via the System Log (/api/v1/logs); if it fails/permissioned out, activity will be empty.

Using Google Workspace

The Google Workspace adapter uses the Admin SDK Directory API and expects an OAuth access token.

1) Set environment variables

$env:GOOGLE_WORKSPACE_ACCESS_TOKEN="<oauth-access-token>"
# Optional (defaults to my_customer)
$env:GOOGLE_WORKSPACE_CUSTOMER_ID="my_customer"

2) Run a scan

python -m cli scan --provider google --out "storage\\google-report.json"

Notes:

  • Users, groups, and group memberships are collected from the Directory API.
  • Admin roles and role assignments are best-effort (require additional scopes); if not available, those portions will be skipped.

## CLI

### `scan`

Fetches provider data, persists a snapshot, diffs against the last snapshot (if any), and returns a report containing drift findings, risk scores, and policy violations.

Common flags:

- `--provider entra|okta|google|mock`
- `--storage-dir <path>` (default: `storage`)
- `--policy <path>` (default: `policies/default.json`)
- `--no-policy` (skip policy evaluation)
- `--out <path>` (write full JSON report)

Examples:

```powershell
python -m cli scan --provider mock --storage-dir storage --policy policies\\default.json --out storage\\report.json
python -m cli scan --provider mock --no-policy

Storage format

IdentityTide stores data locally by default:

  • Snapshots: storage/snapshots/<provider>/<timestamp>.json
  • Event log: storage/events.jsonl (one JSON object per line)
  • State: storage/state.json (tracks last snapshot per provider)

This enables historical analysis and audit evidence without relying on a vendor-specific database.

Drift findings (MVP)

The drift engine currently detects:

  1. Privilege creep: privileged entitlement count for an identity increased compared to the previous snapshot.
  2. Dormant privileged identity:
    • If activity telemetry exists: privileged identity’s last activity is older than dormant_privileged_days.
    • If no activity telemetry exists: identity is flagged as "no activity telemetry" (lower confidence).

Configuration (defaults) is in core/drift/detectors.py.

Explainable risk scoring

Risk scoring is deterministic and returns a breakdown per identity:

privileged_roles(count)*30 + days_active(days)/10 + emergency_access(count)*25

Weights and thresholds can be tuned in core/risk/scoring.py.

Policy-as-code

Policies are simple JSON.

Default policy: policies/default.json

Supported policy controls (MVP):

  • privileged_threshold (default 70)
  • max_privileged_roles (max privileged entitlements per identity)
  • require_expiration_for_emergency (if true, flags emergency assignments without expires_at)

Provider adapters

  • providers/mock: deterministic sample data useful for local testing
  • providers/entra: Entra ID / Microsoft Graph adapter
  • providers/okta: Okta adapter (Core API + best-effort System Log)
  • providers/google_workspace: Google Workspace adapter (Directory API)

Provider contract: providers/base.py.

Development

Run tests

python -m unittest discover -s tests

Syntax check

python -m compileall .

Notes / limitations (current MVP)

  • Activity collection is best-effort and depends on tenant permissions; drift detections that rely on activity may be lower confidence when activity is unavailable.
  • Assignments are currently treated as set membership by (identity_id, entitlement_id, assignment_type) for diffing.
  • The engine currently persists to local JSON/JSONL; pluggable storage can be added later behind the same interface.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages