Admin Controls
Audience: Management, support, engineering (super-admin operators) · Where in app: Admin → Identity (super-admin only) · Plan availability: All plans (graph gated by active subscription)
The Identity Graph is super-admin owned. Customers don't see configuration knobs by default — the graph runs invisibly behind the AI's context. There are two levels of control: global defaults that apply to every tenant, and per-company overrides that replace them for one tenant. A separate subscription gate disables the graph for lapsed tenants regardless of config.
What it does
- Lets super-admins set the global verification policy, which context sections appear, list caps, the custom intro, inbound-call verification, and form capture.
- Lets super-admins override any of those for a single tenant.
- Provides admin screens to browse Persons/Profiles/Form Submissions, inspect a session's assembled context, run maintenance sweeps, and work the CRM reconcile queue.
- Gates the whole graph on an active subscription at runtime.
How it works
Global defaults — IdentityGraphDefaultsModel
A singleton document (key: 'default') in the identity_graph_defaults collection, edited under Admin → Identity → Config.
| Field | What | Default (code) |
|---|---|---|
enabled | Master switch for the graph platform-wide | true |
enabled_sections[] | Which sections appear in the AI prompt (identity, suspected_identity, enrichment, company_contacts, engagement, current_session, recent_pages, past_conversations, behavioral_signals, crm_state, bookings, form_responses, extracted_facts). Empty array = the default set (ALL_SECTIONS), which excludes company_contacts — the Apollo colleague list is opt-in only. | [] (default set) |
custom_intro | Free-form paragraph prepended to the AI prompt's identity block | '' |
max_recent_pages | Cap on recent pages | 5 |
max_past_conversations | Cap on past conversations | 5 |
max_extracted_facts | Cap on extracted facts | 15 |
verification_policy | permissive / moderate / strict / regulated | strict |
accept_inbound_call_verification | Caller-ID matches phone → instant verify | true |
capture_website_forms | Run the form-intercept script on tenant sites | true |
updated_by | Last admin to edit | — |
Until the singleton is first saved, the service falls back to these same defaults (
IdentityGraphConfigService.FALLBACK_DEFAULTS). Defaults are cached 60s — edits take up to a minute to propagate.
Per-company override
companies.identity_graph_allowed: bool // super-admin gate: may this tenant use the graph at all?
companies.identity_graph_use_custom_config: bool // true = use the override below instead of global defaults
companies.identity_graph_config: {
enabled, enabled_sections, custom_intro,
max_recent_pages, max_past_conversations, max_extracted_facts,
verification_policy, accept_inbound_call_verification, capture_website_forms
}
When use_custom_config is false (the default), the global defaults apply. When true, the override is merged over the defaults — fields missing from the override fall back to the global value, so a partial override is safe.
Subscription gate — IdentityGraphSubscriptionGateService
Independent of policy; a runtime check on every read/write path:
- Tenant has an active, non-expired subscription → graph context assembled.
- Trial-expired / cancelled → context not assembled (AI sees only the current session).
- Cached 60s per company. Fail-open: if the subscription lookup itself errors, the gate returns available so a flaky read doesn't silently drop context for a paying customer.
Configuration & options
Admin screens (super-admin)
| Screen | What | Backend |
|---|---|---|
| Identity → Config | Edit global defaults | GET/PUT /admin/identity/config/defaults |
| Identity → Config Form (per-company) | Per-company override editor | PUT /admin/identity/config/company/:id |
| Identity → Persons | Browse global Persons (de-identified summary, searchable) | GET /admin/identity/persons |
| Identity → Person Detail | One Person's full view + merge tools | GET /admin/identity/persons/:id |
| Identity → PersonProfiles | Filter by company; view per-tenant slices | GET /admin/identity/person-profiles |
| Identity → Form Submissions | Audit log of captured forms (filter by type/source/company) | GET /admin/identity/form-submissions |
| Identity → Reconcile Conflicts | Review queue: first-party identity vs a real GHL contact we declined to overwrite | GET/POST /admin/identity/reconcile-conflicts* |
| Identity → Maintenance | Cleanup / normalize / name-moderation / IP-signal backfill / trim-session-events (resumable, NDJSON progress) / retry poisoned Apollo domains (cleanup-apollo-records) / unlink enrichment identities / backfill chat human-message flag sweeps — dry-run first, background mode + polling | POST /admin/identity/maintenance/* |
| Identity → Session Detail | One session's trust state, fingerprint + verified-signal display, suspected-identity markers | frontend/src/views/admin/identity/SessionDetail.vue |
| Session markdown preview | Inspect the assembled context for one session | GET /admin/identity/sessions/:id/markdown-preview |
Frontend repository: frontend/src/repositories/admin/identity.js; views under frontend/src/views/admin/identity/.
Default new-tenant posture
When a new company is created:
identity_graph_allowed: true(assuming the plan supports it)identity_graph_use_custom_config: false→ inherits global defaults- Default policy:
strict(≥80 score threshold) + direct triggers - All sections enabled (empty
enabled_sections) - Form capture on
Disabling per tenant
- Disable entirely:
identity_graph_allowed = false - Disable for ToS reasons:
identity_graph_config.enabled = falsewithuse_custom_config = true - Disable form intercept only:
identity_graph_config.capture_website_forms = false - Maximum strictness (regulated):
verification_policy = 'regulated'+accept_inbound_call_verification = false
Customer-side visibility
By default customer admins see nothing about the graph in their UI — it runs invisibly. A customer-facing Settings → Identity Graph screen exists and can be exposed for transparency (sections enabled, recent activity) if super-admin chooses; it is not on by default.
Behaviors & edge cases
- Changes apply to future sessions only. Already-assembled context isn't recomputed;
enabled_sectionschanges affect the next conversation, not historical ones. - 60s caches. Both the config defaults and the subscription gate cache for 60s — a freshly-cancelled tenant may briefly still get context, and a config edit may take up to a minute to show.
- Override is a whole-config switch.
use_custom_configreplaces the config wholesale (with merge-over-defaults for missing fields); there's no per-field "inherit vs override" toggle in the data model. - Reconcile queue. When a first-party identity conflicts with a real (non-enrichment) GHL contact, the system flags it (
reconcile_conflict_open) instead of overwriting; an admin overwrites, dismisses (optionally unlinking), or it auto-relinks if GHL's no-duplicate rule kicks in. All audited inidentity_events[]. - Maintenance sweeps are dry-run-first and resumable.
trim-session-eventsstreams NDJSON progress so a long apply doesn't hit the ingress idle timeout.
Plan & limits
All plans, gated by active subscription. Config is operational, not a paid tier. (Whether any plan tier restricts which sections/policies are allowed: verify with product.)
Technical implementation
- Models:
IdentityGraphDefaultsModel(identity_graph_defaultssingleton),companies.identity_graph_*fields. - Services:
IdentityGraphConfigService.getEffectiveConfig()(defaults overlaid with override, 60s cache),IdentityGraphSubscriptionGateService.isAvailable()(60s, fail-open). - Routes:
backend/app/routes/adminIdentityRoutes.js(passport-gated), controllerAdminIdentityController. - Frontend:
frontend/src/repositories/admin/identity.js, views infrontend/src/views/admin/identity/.
See Identity Graph (subsystem) for the resolution chain and how config feeds it.
What Nox can tell you
- Current policy + which company-specific overrides exist
- Whether a specific tenant is gated by the subscription check
- Section enablement
- Recent identity events (verifications, conflicts, merges)
Nox can't change settings — super-admin edits directly.
Related
- Identity Graph Overview
- Verification Policy
- Cross-Session Context — the sections this config governs
- Form Intercept — the
capture_website_formstoggle - Person vs Profile
- Identity Graph (engineering subsystem)
- CRM Integration