Note: This repository is a maintained fork of jaffster595/DB-Auto-Org-Chart.
SimpleOrgChart is a Flask application backed by Azure Active Directory (Entra ID) data that renders a fully interactive, client-side organisation chart. A static JavaScript front end (vanilla JS + D3) consumes cached Graph API data, offers rich filtering, and exposes an admin dashboard with compliance-friendly exports.
- Hardened security defaults: strict Content Security Policy, sanitized redirects, login isolation, and placeholder-secret protection.
- Modular front end: no inline scripts or styles; shared CSS variables power
configure,reports, and org chart experiences. - Daily automation: background scheduler refreshes Azure AD data (20:00 local time) and persists JSON caches under
data/. - Admin reporting: missing managers, filtered users, and last-login inactivity insights—each with one-click XLSX export.
- Export tooling: SVG/PNG/PDF org chart capture and server-backed XLSX generation for the current chart tree.
- Deployment ready: ships with Docker Compose and a Gunicorn configuration (
deploy/gunicorn.conf.py) for containerized hosting.
| Layer | Description |
|---|---|
Flask backend (simple_org_chart/ package) |
Serves templates/static assets, authenticates admin endpoints, manages schedulers, and stores cached Graph API responses. |
Static front end (static/*.js) |
Renders the D3 org chart, configuration UI, and reports dashboard using cached JSON. |
Data cache (data/*.json) |
Holds employee hierarchies, report snapshots, and last login activity to reduce Graph API calls. |
| Scheduler | Nightly job (20:00) refreshes employee data; manual refresh endpoints and CLI helpers are available. |
- Docker Desktop (or Docker Engine with the Compose plugin) for container-based deployment.
- An Azure AD tenant with privileges to create app registrations and grant Graph application permissions.
-
Create an App Registration
- Azure Portal ➜ Azure Active Directory ➜ App registrations ➜ New registration.
- Choose a name (for example,
SimpleOrgChart) and leave Redirect URI empty.
-
Assign Microsoft Graph Application Permissions
User.Read.AllLicenseAssignment.Read.All(required for licensing insights and admin reports)AuditLog.Read.All(required for last sign-in metrics and disabled-user audit timestamps)MailboxSettings.Read(enables mailbox-type metadata used by last sign-in filters; without it, all mailboxes are treated as standard users)- Grant admin consent for the tenant.
-
Create a Client Secret
- Certificates & secrets ➜ New client secret.
-
Capture Identifiers
- Application (client) ID →
AZURE_CLIENT_ID - Directory (tenant) ID →
AZURE_TENANT_ID
- Application (client) ID →
Copy the template and fill in your secrets.
cp .env.template .env
# edit .env with tenant/client IDs, secret, admin password, etc.Required values
AZURE_TENANT_ID– Directory (tenant) ID.AZURE_CLIENT_ID– Application (client) ID.AZURE_CLIENT_SECRET– Client secret value.TOP_LEVEL_USER_EMAIL– Email for the org chart root user.ADMIN_PASSWORD– Protects/configureand/reports.SECRET_KEY– 64+ character random string for Flask sessions.
Generate a strong secret key:
python -c "import secrets; print(secrets.token_hex(32))"Optional values
TOP_LEVEL_USER_ID– Explicit Graph object ID for the root user.CORS_ALLOWED_ORIGINS– Comma-separated list of allowed cross-origin hosts.RUN_INITIAL_UPDATE– Set tofalseto skip automatic data refresh at startup.APP_PORT– Port the application listens on (defaults to5000).
docker compose pull
docker compose up -d- Default port:
APP_PORT(defaults to5000). Override it in.envto change container and host bindings. - Persistent data resides in the
orgchart_datavolume. Remove it to rebuild caches from scratch. - Local execution outside Docker is not supported; use the provided container workflow for development and production.
- Interactive D3 Org Chart: Pan, zoom, and expand/collapse hierarchies with persistent hidden subtrees.
- Search & Discovery: Real-time directory search, quick navigation helpers, and configurable filters for guests/disabled users.
- Configuration UI (
/configure): Adjust styling, filtering, export columns, and scheduling without editing files. - Admin Reports (
/reports):- Missing managers
- Users by last sign-in activity
- Employees hired in the last 365 days
- Users hidden by filters
- Export Options: SVG/PNG/PDF snapshots and XLSX exports for reports and chart data.
- Caching & Scheduling: JSON caches regenerate nightly; manual refresh endpoints keep data current on demand.
data/employee_data.json– Full org hierarchy.data/missing_manager_records.json– Missing manager snapshot.data/disabled_user_records.json– Disabled users enriched with license and sign-in metadata.data/last_login_records.json– Active users with last sign-in timestamps.- Additional files exist for filtered/disabled-with-license/hiring reports.
If a cache is missing or stale, hit Refresh Data on the reports page or start the app with RUN_INITIAL_UPDATE=true.
- Store secrets in Azure Key Vault or your host’s secret manager; never commit
.envfiles. - Restrict
/configureand/reportsbehind reverse-proxy auth if deployed on the public internet. - Monitor
AuditLog.Read.Allusage—limit consent scope to required admins. - Rotate
AZURE_CLIENT_SECRETregularly and update the environment accordingly.
- Graph permission errors: Ensure admin consent is granted; check logs for 403 responses when fetching
signInActivity. - Stale data: Run
curl -X POST http://<host>/api/update-now(with admin auth) or remove thedata/*.jsoncaches and restart. - Export failures: Confirm
openpyxlis installed (bundled viarequirements.txt). The API returns a 500 with JSON error details if export dependencies are missing. - Missing logos: Upload custom branding via
/configure; static assets persist indata/.
Issues and pull requests are welcome. Please document new locale strings in static/locales/en-US.json, update report caches when introducing routes, and include manual validation steps if automated tests are not available.
SimpleOrgChart keeps your organisation chart and admin insights in sync with Azure AD while staying lightweight, portable, and secure.