Stack Dashboard · Keeper Security · Operations Console

Keeper Operations Console

A real-time zero-trust operations dashboard for Keeper Security enterprise deployments. Surfaces KPIs, security event feeds, device inventory, incident queues, and API health — all wired to the Keeper Security Commander REST API v2.

File: stack-keeper.html Vendor: Keeper Security API Base: keepersecurity.com/api/rest/ Refresh: 30 sec auto DEMO MODE — MOCK DATA ACTIVE
01

What Is This Tool

The Keeper Operations Console is a standalone HTML dashboard for MSP engineers and security teams managing Keeper Security enterprise accounts. It replaces the need to navigate the Keeper Admin Console GUI for routine monitoring by presenting security events, device status, user activity, and platform health in a single continuously-refreshing view.

It is part of the KrawTech Stack Dashboard Suite — per-vendor dashboards sharing a common proxy-ready API wiring pattern, 30-second auto-refresh lifecycle, and design system. All dashboards run in DEMO mode (realistic mock data, no external calls) until a live API token is configured.

Primary Use Cases
Threat MonitoringMFA bypass, vault sharing, privilege escalation
Device OpsEnrollment status, compliance drift, risk scoring
User ActivityAuth events, session activity, admin actions
Incident QueueTriage open/ack/resolved security incidents
API HealthLatency monitoring of 6 Keeper service endpoints
Platform KPIsAssets, alerts, users, devices, health at a glance
Target Users & Context
PrimarySOC analysts, MSP security engineers
SecondaryIT admins managing Keeper enterprise tenants
DisplaySecondary monitor or NOC screen, 1080p+
Session TypePersistent open tab, auto-refreshing every 30s
AuthenticationService Account token — no interactive login
02

Integration Status

The dashboard runs in DEMO mode by default. No network calls are made. When DEMO_MODE is set to false and a valid API token is provided, the four live Keeper Commander REST API calls activate automatically.

Data Source Integration Matrix
Data SourceStatusReal API EndpointNotes
Enterprise SummaryPROXY READYPOST /api/public/v2/node/get_enterprise_nodeInclude nodes, users, teams, roles, licenses. Activates when proxy is live.
Security Events / AlertsPROXY READYPOST /api/public/v2/audit_log/get_audit_logPolling only — no streaming. Rate-limited. Activates when proxy is live.
Device InventoryPROXY READYPOST /api/public/v2/device/get_enterprise_devicesCompliance status derived client-side from device metadata. Activates when proxy is live.
Policy CountNO NATIVE ENDPOINTKeeper has no REST endpoint for policy counts. Demo data only — will not go live.
Events (Security Event Feed)AUDIT LOG ONLYPOST /api/public/v2/audit_log/get_audit_logBoth Alerts and Events come from the same audit_log endpoint filtered by type.
API HealthINFERREDLatency measured on authenticated callsKeeper has no /health ping endpoints. Health is inferred from response success & timing.
Team / DirectoryPROXY READYPOST /api/public/v2/team/get_teams_by_enterpriseActivates when proxy is live.
Enterprise UsersPROXY READYPOST /api/public/v2/user/get_enterprise_usersActivates when proxy is live.
03

Architecture

The console is a single-file static HTML application. All logic, styles, and mock data generators live in one file with no external dependencies beyond Google Fonts. The Keeper REST API requires a Bearer token — the file uses a configurable KEEPER_API_TOKEN constant. For production use, a local reverse proxy is recommended to avoid embedding credentials in browser-accessible files.

Demo Mode Data FlowCURRENT
Browser stack-keeper.html Mock Generators Rendered UI
DEMO_MODE = true · no network calls · boot() → loadDashboard() → refreshAll()
Live Mode Data FlowACTIVATES WITH TOKEN
Browser stack-keeper.html Local Proxy (opt.) Keeper REST API
DEMO_MODE = false · Authorization: Bearer token · POST JSON requests
Lifecycle Functions
boot()Entry point. Runs loading sequence animation, then calls loadDashboard()
loadDashboard()Master fetch + render. Calls refreshAll(), then all render*() functions
refreshAll()DEMO/live branch. Returns { summary, alerts, events, devices, apiHealth }
startAutoRefresh(30000)Wraps setInterval(loadDashboard, ms). Clears previous interval on re-call
keeperFetch(ep, body, gen)Proxy-ready POST wrapper. Commented live path above mock fallback
fetchAllAlias for loadDashboard() — backward compatibility
tickClock()Updates header timestamp and countdown timer every second
05

KPI Row

Six KPI tiles displayed in a grid below the section label. Each shows a primary value, sub-label, and a delta badge comparing the current value to the previous refresh cycle. Delta badges color-code intelligently — rising alerts are red (bad), rising health is green (good).

KPI Tile Reference
TileValue KeyFormatLive Source
Total Assetssummary.total_assetstoLocaleString()get_enterprise_node → node.number_of_users + devices
Active Alertssummary.active_alertsintegerget_audit_log → count of open security events
Critical Alertssummary.critical_alertsintegerget_audit_log → count filtered by high-severity types
System Healthsummary.system_healthvalue + "%"Derived metric — Keeper has no health score endpoint. Computed from API response rates.
Active Userssummary.active_userstoLocaleString()get_enterprise_users → users[].status = "active" count
Devices Onlinesummary.devices_onlinetoLocaleString()get_enterprise_devices → devices count
Delta Badges

Delta values compare each KPI to its value from the previous refresh cycle stored in prevKPIs. Alert/critical deltas invert color logic: +1 alert = red (down), -1 alert = green (up). Asset/user/device/health deltas follow standard direction: positive = green.

06

API Health Panel

The left panel in the middle row. Displays six Keeper service endpoints with latency, a proportional bar, and an OK/WARN/ERR status dot. Timestamp shows last check time.

Important: No Dedicated Health Endpoints

Keeper Security does not expose any /health or ping endpoints. In the original dashboard, the API health panel used six completely fabricated paths (/api/keeper/auth/health, etc.) that do not exist in Keeper's API. These have been corrected to the real authenticated endpoints. In DEMO mode, latency and status are randomized. In live mode, health is inferred from the success and response time of actual API calls.

Corrected API Health EndpointsPOST-AUDIT
Display NameReal Endpoint MonitoredMethod
Auth API/api/public/v2/auth/request_loginPOST
Admin API/api/public/v2/node/get_enterprise_nodePOST
Device API/api/public/v2/device/get_enterprise_devicesPOST
Events API/api/public/v2/audit_log/get_audit_logPOST
Directory API/api/public/v2/team/get_teams_by_enterprisePOST
Users API/api/public/v2/user/get_enterprise_usersPOST
07

Platform Summary Cards

Six cards in a 3-column grid in the right portion of the middle row. Each card shows an icon, label, primary value, two sub-metrics, and a fill bar. All cards share data from the renderPlatCards(summary, alerts, apiHealth) function.

Platform Card Reference
CardValue SourceSub-MetricsLive?
👥 Userssummary.active_usersAdmin count (demo-only), Provisioned = total_assetsPARTIAL — provisioned from live, admin count demo-only
💻 Devicessummary.devices_onlineCompliant = 94% of online, At Risk = 6% of onlinePROXY READY — percentages are approximations pending compliance field
📋 Policiesrnd(42,56) — MOCK ONLYActive, Violations — both mockNO KEEPER ENDPOINT — demo data only, always
🚨 Alertssummary.active_alertsCritical = summary.critical_alerts, Ack'd = count of ack'd in alerts arrayPROXY READY
📡 Eventsrnd(12,18) + "K"Auth, Policy — both demo-only countsDEMO — live value should come from audit_log total_count field
💚 Sys Healthsummary.system_health + "%"Uptime hardcoded 99.9%, APIs OK = computed from apiHealth arrayPARTIAL — APIs OK now computed live; health score is derived
08

Alert Strip

A horizontal strip showing the 6 most recent alerts from the alerts array. Each row is color-coded by severity on the left edge, and shows age, message text, source service name, and status pill.

Alert Strip Fields
Left color barSeverity: CRIT=red, HIGH=orange, MED=yellow, LOW=green
AgeComputed from inc.age_ms via ago() — "Ns ago", "Nm ago", "Nh ago"
Messageinc.title — truncated with text-overflow: ellipsis
Sourceinc.source — e.g. "Auth API", "Admin API" (from audit_log event_source in live mode)
Status pillinc.status — open / ack / resolved / closed with color class
Count shownTop 6 only (alerts.slice(0, 6))
Live sourcePOST /api/public/v2/audit_log/get_audit_log
09

Incident Table

The full incident/alert table with filter buttons and row count badge. Filterable by status: ALL / OPEN / ACK / RESOLVED. Clicking a filter re-renders the table in-place without a data refetch.

Table Columns
IDinc.id — format KPR-XXXX (demo) or audit event ID (live)
SEVCRIT / HIGH / MED / LOW badge with color fill
TITLE / USERinc.title truncated, inc.user in tooltip on hover
SOURCEinc.source — the Keeper service API that generated the event
STATUSopen / ack / resolved / closed pill
AGEago(inc.age_ms) — relative time string
ASSIGNEDinc.assigned — engineer name or "Unassigned"
Filter Behavior
State variablecurrentFilter — module-level string
Filter sourceallIncidents array — populated on each loadDashboard()
ALL buttonShows entire allIncidents array
OPEN/ACK/RESOLVEDFilters by i.status === filter value
Row countUpdated in #tableCount span on every filter apply
Live sourcePOST /api/public/v2/audit_log/get_audit_log
10

Event & Device Feeds

Two side-by-side panels in the bottom row. Left: Security Event Feed. Right: Device Status Overview. Both show the top 10 items from their respective arrays.

Security Event FeedLIVE READY
Count label"N recent" — events.length from generateEvents()
Timeev.time formatted via fmtTime() — HH:MM:SS
Messageev.msg — event description string
Type badgeev.type — auth / device / policy / admin / system with color class
Live sourcePOST /api/public/v2/audit_log/get_audit_log (same endpoint as alerts, filtered by event type)
Items shownTop 10 (events.slice(0,10)), sorted newest first
Device Status OverviewLIVE READY
Count label"N devices" — devices.length
Device Named.name — device model string
Userd.user — username@corp in muted style
OSd.os — OS name and version string
Statusd.status — online (green) / compliance_warn (yellow) / offline (dim)
Riskd.risk — Low (green) / Medium (yellow) / High (red)
Live sourcePOST /api/public/v2/device/get_enterprise_devices
Items shownTop 10 (devices.slice(0,10))
12

API Endpoints

All endpoints verified against the Keeper Security Commander REST API documentation at docs.keeper.io/secrets-manager/commander-cli/commander-rest-api. Six endpoints in the original file were completely fabricated — all have been replaced with verified paths.

Authentication

All Keeper REST API calls require Authorization: Bearer <session_token>. Session tokens are obtained via POST /api/public/v2/auth/request_login followed by POST /api/public/v2/auth/validate_auth_hash. For automated/service use, generate a Commander Service Account token from the Keeper Admin Console under Keeper Secrets Manager or via Commander CLI (keeper connect). All requests are POST with JSON body — Keeper's REST API does not use GET for data retrieval.

Verified Keeper REST API EndpointsPOST-AUDIT
PurposeEndpointRequest BodyKey Response Fields
Enterprise Node / SummaryPOST /api/public/v2/node/get_enterprise_node{"include":["nodes","users","teams","roles","licenses"]}node.number_of_users, node.number_of_devices, node.licenses
Security Audit Log (alerts + events)POST /api/public/v2/audit_log/get_audit_log{"limit":100,"filter":{"event_type":[...]}}audit_event[].event_type, .created, .username, .geo_location
Enterprise DevicesPOST /api/public/v2/device/get_enterprise_devices{}devices[].client_version, .os_version, .device_name, .username
Enterprise UsersPOST /api/public/v2/user/get_enterprise_users{"include_deleted":false}users[].username, .status, .node_id, .roles
Teams / DirectoryPOST /api/public/v2/team/get_teams_by_enterprise{}teams[].team_uid, .name, .users
Auth / Session TokenPOST /api/public/v2/auth/request_login{"username":"...","include":["keys"]}login_token (proceed with validate_auth_hash)
13

Vendor Limitations

These are genuine Keeper Security API constraints — not implementation gaps. All are documented in code comments in the dashboard file. These panels will remain on demo data even when the proxy is live.

No Policy Count Endpoint
Keeper Security does not expose a REST endpoint that returns a count of enforced policies. The Admin Console shows enforcement rules, but this data is not available in the Commander REST API as a numeric count. The Policies platform card will always show demo data. Workaround: parse enforcement flags from the enterprise node object, though this does not give a simple count.
No Health-Check Ping Endpoints
Keeper provides no /health, /ping, or status endpoints. The original dashboard used six completely fabricated paths (/api/keeper/auth/health etc.) that return 404 on any real Keeper instance. API health is now inferred from response success and latency on real authenticated calls. In DEMO mode, latency and status are randomized for display purposes.
No Real-Time Event Streaming
The Security Event Feed requires polling. Keeper's REST API does not provide a WebSocket, SSE stream, or push-based event feed. The 30-second refresh interval is the minimum recommended polling cadence to avoid rate limiting on get_audit_log. For near-real-time alerting, use Keeper's native webhook integration to push events to an intermediate aggregation service.
Audit Log Rate Limiting
The get_audit_log endpoint is rate-limited by Keeper. Do not reduce the refresh interval below 30 seconds when calling this endpoint. If both the Alerts and Events feed draw from the same endpoint (as they do in this dashboard), consider batching them into a single call with different type filters applied client-side.
Device Compliance Status is Derived, Not Native
The get_enterprise_devices endpoint does not return a compliance_warn or risk-level field directly. Compliance status must be derived client-side from device metadata — OS version, last-seen time, client version. The dashboard currently applies hardcoded 94%/6% compliant/at-risk ratios as approximations. A proper compliance engine requires additional business logic layered on top of the raw device data.
System Health Score is a Derived Metric
Keeper does not expose a system health score endpoint. The "System Health" KPI and platform card value is computed from API response success rates during each refresh cycle. In demo mode it is randomized around 99.1–99.9%. A production implementation should define explicit calculation logic (e.g., weighted average of API response success rates across the 30s window).
14

Config Fields

All configuration lives at the top of the <script> block in stack-keeper.html. No external config file required.

Top-Level Config Variables
// ── CONFIGURATION ───────────────────────────────────────── const DEMO_MODE = true; // Set false + fill fields below to go live const KEEPER_BASE_URL = 'https://keepersecurity.com/api/rest'; const KEEPER_API_TOKEN = ''; // Service Account token from Keeper Commander const REFRESH_INTERVAL = 30000; // ms — do not reduce below 30000 (rate limiting)
Configuration Reference
VariableTypeDefaultDescription
DEMO_MODEBooleantrueWhen true, all data comes from mock generators. Set false to activate keeperFetch() live path.
KEEPER_BASE_URLStringhttps://keepersecurity.com/api/restBase URL for Keeper Commander REST API. If using a local proxy, point to localhost proxy URL instead.
KEEPER_API_TOKENString''Bearer token from Keeper Commander Service Account. Only needed if not using a proxy that injects the header.
REFRESH_INTERVALNumber (ms)30000Auto-refresh interval. Do not set below 30000 — Keeper audit_log endpoint is rate-limited.
15

Proxy Activation Checklist

Complete in order to switch from DEMO to live Keeper data. No rendering or UI code changes required.

1. Generate a Keeper Commander Service Account token
In the Keeper Admin Console: go to Secrets Manager > Applications > Create New Application. Copy the generated token — shown once only. Alternatively, use keeper shell > connect to authenticate and retrieve a session token. Store in your credential vault.
2. Confirm API access from the machine running the dashboard
Test with: curl -X POST https://keepersecurity.com/api/rest/api/public/v2/node/get_enterprise_node -H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" -d '{"include":["nodes"]}'. Expect a JSON response with node data. A 401 means invalid token. A 403 means the service account lacks admin permissions.
3. Grant required permissions to the service account
The service account needs read access to: Enterprise Nodes, Users, Devices, Audit Log, and Teams. In Keeper Admin Console, assign the "Auditor" role or a custom role with equivalent read permissions. Write permissions are not required for this dashboard.
4. Set up a local reverse proxy if needed for CORS
Keeper's API may block cross-origin browser requests. Use nginx, Caddy, or a minimal Node.js proxy to relay requests and inject the Authorization header. Example nginx block:
location /api/ { proxy_pass https://keepersecurity.com/api/rest/api/; proxy_set_header Authorization "Bearer YOUR_TOKEN"; proxy_set_header Content-Type "application/json"; }
5. Edit the config block in stack-keeper.html
Set DEMO_MODE = false. Set KEEPER_BASE_URL to your proxy URL or https://keepersecurity.com/api/rest. Set KEEPER_API_TOKEN if not injecting via proxy header.
6. Uncomment the live fetch path in keeperFetch()
Find the // ── LIVE path ── comment block inside keeperFetch(). Uncomment the try/catch block and the fetch() call. Leave the mock fallback below it — it activates on fetch failure.
7. Verify field mapping for live API responses
Keeper's API response shapes may differ from the mock generator's field names. After first live load, open DevTools Network tab, inspect the actual response JSON from each endpoint, and update the render functions to access correct paths. Key fields to check: enterprise node structure, audit_log event fields, device object schema.
8. Verify the first live load
Open DevTools Network tab. On load, 3 POST requests should appear (enterprise_node, audit_log, enterprise_devices). All should return 200 with JSON. If the header label still shows "DEMO" after setting DEMO_MODE=false, clear cache and hard-refresh.
9. Accept that 3 panels remain on demo data
Policy count (no endpoint), Events feed aggregate count, and System Health score are permanently demo-derived. Document this clearly if the dashboard is used in a client-facing context. Consider adding a "⚠ ESTIMATED" badge to those specific cards.
16

Troubleshooting

Loading screen never disappears after opening the file
The boot() function ran but loadDashboard() threw an error. Open DevTools console — look for any JS syntax error or an unhandled promise rejection. In DEMO mode this should not happen. If it does, the mock generator threw an error — verify you haven't edited the generator functions. Hard-refresh with Ctrl+Shift+R to reset all module state.
In live mode: all API calls return 401 Unauthorized
The token is invalid or expired. Keeper session tokens have limited TTLs. Service Account tokens from Secrets Manager are longer-lived. Regenerate the token in Keeper Admin Console. Verify there is no trailing whitespace in KEEPER_API_TOKEN. If using a proxy, verify the proxy is injecting the Authorization header correctly on the POST request, not just on GET.
In live mode: CORS error in browser console
Keeper's API likely does not send Access-Control-Allow-Origin headers for browser requests from arbitrary origins. Set up the local reverse proxy (see checklist step 4) and point KEEPER_BASE_URL to your localhost proxy URL. The proxy adds the CORS header on responses without the browser ever seeing a cross-origin request.
KPI values show correct numbers but delta badges all show "+0"
This is expected on the first load — prevKPIs is empty so all diffs are zero. Delta values appear correctly starting from the second refresh cycle. If they remain +0 after multiple cycles, verify that prevKPIs[f.key] is being set at the bottom of renderKPIs() — this line runs after comparing but before storing the new value.
Incident table shows "No incidents match filter" even though the alert strip has rows
The filter is set to a status that none of the current incidents match. Click ALL to reset the filter. If ALL also shows nothing, allIncidents is empty — loadDashboard() may have silently failed on the alerts fetch and returned an empty array. Check the DevTools console for keeperFetch() warnings.
Auto-refresh stops after leaving the tab open for a long time
Browsers throttle setInterval timers in background tabs. Both startAutoRefresh() and tickClock() will drift when the tab is not in focus. Bring the tab back to the foreground — the next interval tick will resume. No data will be lost; the next refresh will fetch the current state. For always-on NOC use, consider a dedicated browser profile with tabs pinned and tab-sleeping disabled.
API Health panel shows all endpoints as "err" (red) in live mode
In live mode, the API health panel latency and status should be inferred from real call results. If all show err, the keeperFetch() calls are all failing — likely a token or CORS issue. The generateAPIHealth() fallback is still returning mock data but the status randomizer happened to generate "err" for all. This is a coincidence in demo data, not a real failure indicator. Check network requests in DevTools to confirm whether actual calls are succeeding.
footerCalls count grows faster than expected
In live mode, each loadDashboard() call makes 3 keeperFetch() calls (enterprise_node, audit_log, enterprise_devices), incrementing apiCallCount by 3 per refresh cycle. After 10 refreshes (5 minutes) the counter reads 30. This is correct behavior. In demo mode each refreshAll() call returns mock data directly without calling keeperFetch(), so the counter only increments on manual fetches triggered by boot().