The problem this solves

Budget vs actual variance analysis is one of the highest-frequency reporting tasks in any FP&A function. A regional CFO needs to know, at any point in the quarter: which entities are running ahead of plan, which are behind, and by how much across the income statement. Building that view from Oracle EPM Planning data today means either maintaining a static Oracle Analytics dashboard (expensive to build, slow to update) or extracting data to Excel and building pivot charts manually (hours of work per period).

The Planning Analytics Dashboard answers those variance questions through a natural language query, rendered as an interactive KPI dashboard with eight chart types. The same question that would take an OAC dashboard developer two days to configure takes this demo 4 seconds to generate.

Audience

Regional CFOs, finance business partners, and management reporting teams who need fast BvA analysis across entities, regions, and periods. EPM architects exploring whether to add an analytics layer above an existing EPM Planning deployment before committing to Oracle Analytics Cloud licences.

Natural language dashboard queries

Input is a plain-text analytics question. The NLQ parser extracts the analysis intent and translates it into a dashboard configuration:

Intent typeExample queryChart output
Regional comparison"Compare APAC vs EMEA revenue FY26"Bar chart, side-by-side regions
Trend over time"APAC FY26 revenue trend line chart"Line chart, Q1โ†’Q4
BvA waterfall"Waterfall bridge plan vs actual FY26"Waterfall, plan baseline + variances
Mix analysis"Revenue mix by region doughnut"Doughnut chart, 4 regions
Entity ranking"Rank all entities by revenue"Horizontal bar, 44 entities sorted
Stacked breakdown"Revenue by channel type stacked"Stacked bar, Store/Digital/Wholesale
Dual-axis combo"Revenue and margin combo chart EMEA"Bar (revenue) + Line (margin %)
Radar profile"APAC region performance radar"Radar, multi-metric by entity

An interactive KPI dashboard

The output is a live, interactive analytics dashboard rendered in the browser:

  • 4 KPI cards: Total Revenue, Budget vs Actual variance ($ and %), Net Margin %, and a primary period metric โ€” each with trend direction arrow
  • Regional breakdown table: 4 regions ร— Plan + Actual + Variance columns, colour-coded variance cells
  • Main chart: one of 8 chart types based on query intent or user selection
  • Entity ranking table: all 44 entities ranked by revenue, colour-coded by region

All chart types are selectable via chip buttons after initial render โ€” the user can switch from bar to waterfall to combo without re-querying.

In your EPM reporting stack

The Planning Analytics Dashboard sits above EPM Planning data and below a full enterprise BI layer. It is designed for the read-heavy, high-frequency analytical questions that don't justify Oracle Analytics Cloud build time but are too complex for ad-hoc SmartView grids.

  • Monthly business review: CFO views regional BvA waterfall for the closed month before the deck is published
  • In-meeting analysis: Finance business partner answers a variance question on the spot without leaving the meeting room to "pull the data"
  • Period-end close triage: Controller checks which entities are furthest from plan before deciding where to focus close investigations
  • Executive self-service: C-suite executives ask revenue questions in plain language without training on any EPM or BI tool

The numbers

8
Chart types
4
KPI cards
44
Entities ranked
4
Regions compared
$0.0003
Per dashboard query
Chart.js
Viz engine
Chart typeBest for
BarRegional comparison, period-over-period
LineTrend analysis Q1โ†’Q4
DoughnutRevenue mix, share of total
RadarMulti-metric entity profile
WaterfallBvA bridge, plan โ†’ actual with variance bars
StackedRevenue by channel type (Store/Digital/Wholesale)
RankingAll 44 entities sorted by revenue (horizontal bar)
ComboDual-axis: revenue bars (left) + net margin % line (right)

The honest checklist

  • โœ“You need fast BvA variance analysis across regions/entities without Oracle Analytics Cloud build time
  • โœ“Your executives ask ad-hoc EPM questions in meetings that currently require an analyst to "pull the data later"
  • โœ“You have EPM Planning with a consistent revenue and income statement data model
  • โœ“You want 8 chart types selectable dynamically โ€” not a fixed dashboard layout
  • โœ—You need row-level drill-through to transaction data โ€” this dashboard operates at EPM member level, not GL detail
  • โœ—You need pixel-perfect print-ready dashboards โ€” the output is browser-rendered, not PDF-optimised
  • โœ—You need multi-user concurrent sessions with user-level entitlement โ€” the demo is single-tenant on the cookie gate

Try it now

The live demo renders all 8 chart types against pre-loaded EPM demo data with a real DeepSeek LLM call for query intent parsing.

Launch Analytics Dashboard โ†’ Start a Lab engagement

Sample queries to try

  • "APAC FY26 revenue trend line chart"
  • "Compare plan vs actual EMEA waterfall"
  • "Rank all entities by revenue"
  • "Revenue and margin combo chart FY26"
HOW WE BUILT IT

The cost of a dashboard

A typical Oracle Analytics Cloud dashboard project for EPM data takes 4โ€“8 weeks and costs $40Kโ€“$80K in consulting time. It produces a fixed set of visualisations that answer the questions the project team predicted โ€” not the questions executives actually ask in the next quarter.

The NLQ analytics approach is not a replacement for enterprise BI โ€” it is an answer to the question that comes before the enterprise BI project: "Is EPM analytics useful enough to our executives to justify the investment?" The Planning Analytics Dashboard lets you prove that in 4 hours of setup time and ~$9/month in LLM costs, using pre-loaded demo data, before you commit to the full OAC project.

Intent-to-dashboard pipeline

User query (analytics question)
1
Intent Parser
DeepSeek V3
{ chartType, metric, entity, scenarios[], year, periods[], groupBy }
  • Detects: chart type, metric, entity, scenario, year, period, comparison axis
2
Data Aggregator
analytics.html
  • KPI cards: revenue, variance, margin
  • Regional table: 4 regions × Plan + Actual + Variance
  • Chart dataset builder (per chart type)
  • Entity ranking: 44 entities sorted
3
Chart.js Renderer
  • 8 chart types, shared canvas element
  • Chart type toggle (no re-query)
  • Responsive, theme-aware colours

App UI โ€” Dashboard component layout

ComponentContent
Query barPlain-text analytics question, Enter to run, 500-char max
Chart type chips8 buttons (Bar/Line/Doughnut/Radar/Waterfall/Stacked/Ranking/Combo) โ€” switch chart without re-query
KPI card row4 cards: Total Revenue ยท BvA $ variance ยท BvA % ยท Net Margin %. Each shows current period value + direction arrow.
Regional breakdown tableNA / EMEA / APAC / LAD rows ร— Plan + Actual + $ Var + % Var columns
Main chartChart.js canvas โ€” switches to selected type on chip click
Entity ranking tableAll 44 entities sorted by revenue, colour-coded dot by region, actual vs plan columns

What each KPI card shows and why

KPICalculationWhy this metric
Total RevenueSum of all entity revenues for selected period(s) and scenarioThe top-line anchor โ€” everything is measured against this
BvA $ VarianceActual Revenue โˆ’ Plan RevenueThe absolute gap โ€” most relevant when entities have different size profiles
BvA % Variance(Actual โˆ’ Plan) / |Plan| ร— 100The relative gap โ€” enables comparison across entities of different sizes
Net Margin %Net Income / Total Revenue ร— 100The profitability check โ€” revenue above plan with margin below plan is a warning sign

Each card shows a direction arrow (โ†‘ green / โ†“ red) based on the sign convention: revenue and margin variance up is favourable, so โ†‘ is green. For cost accounts the sign is inverted โ€” cost variance up is unfavourable. The current demo uses revenue sign convention throughout.

How each of the 8 chart types is built

TypeDataset shapeKey Chart.js config
Bar4 regions, Plan + Actual bars side-by-sidetype:'bar', grouped, colour by region
LineQ1โ†’Q4, one line per scenario or regiontype:'line', tension:0.4, pointRadius:5
DoughnutRevenue by region as % of totaltype:'doughnut', cutout:'55%', legend inside
Radar5 metrics (Revenue, Margin, Growth, BvA%, ROI) per regiontype:'radar', normalised 0โ€“100 scale
WaterfallPlan baseline + per-region variance bars โ†’ Actual totaltype:'bar', floating bars, transparent base bars
StackedRevenue by channel type (Store/Digital/Wholesale) per regiontype:'bar', stacked:true, 3 datasets
Ranking44 entities sorted by revenue, horizontaltype:'bar', indexAxis:'y', colour by region group
ComboRevenue bars (left Y) + Net Margin % line (right Y)Mixed type:'bar'+'line', dual yAxes

All 8 chart types share a single <canvas> element. Switching type destroys the existing Chart.js instance and creates a new one with the same data โ€” no re-query to the LLM or data layer.

Analytics intent extraction

The analytics prompt is more intent-focused than the FP&A prompt. Instead of extracting dimension values, it extracts the analytical question type and maps it to a chart type:

// Analytics output schema
{
  "chartType": "bar"|"line"|"doughnut"|"radar"
              |"waterfall"|"stacked"|"ranking"|"combo",
  "metric": "revenue"|"margin"|"variance"|"growth",
  "entity": "TotalEntity"|"NA"|"EMEA"|"APAC"|"LAD"|<specific>,
  "scenarios": ["Plan","Actual"],
  "year": "FY26",
  "periods": ["Q1","Q2","Q3","Q4"],
  "groupBy": "region"|"entity"|"period"|"productType"
}

Chart type inference rules (few-shot examples)

  • "trend", "over time", "quarterly" โ†’ line
  • "waterfall", "bridge", "variance breakdown" โ†’ waterfall
  • "rank", "ranking", "all entities", "top/bottom" โ†’ ranking
  • "mix", "share", "breakdown by type" โ†’ doughnut or stacked
  • "combo", "dual axis", "revenue and margin" โ†’ combo
  • "profile", "radar", "multi-metric" โ†’ radar
  • Default (comparison, regional, BvA) โ†’ bar

Cost per dashboard render

ComponentDetailCost
LLM input tokens~850 tokens (analytics system prompt is shorter than FP&A)$0.000119
LLM output tokens~120 tokens (JSON with chart intent is compact)$0.000034
Chart.js renderingClient-side (browser) โ€” zero server cost$0
Chart type switchNo LLM call on chart type toggle โ€” zero marginal cost$0
Total per dashboard~$0.000153
With 2ร— safety margin~$0.0003

Cost model โ€” At-scale projections

ScaleDashboards/dayMonthly costvs OAC licence
Executive team (5 users)25$0.23$0.23 vs $3,750/month (OAC)
Management (50 users)200$1.80$1.80 vs $37,500/month
Finance dept (200 users)1,000$9$9 vs $150,000/month

OAC Oracle Analytics Cloud estimates use published list prices for the Analytics Cloud Enterprise edition. NLQ analytics does not replace OAC for complex multi-subject-area reporting, drill-through, or pixel-perfect formatted output โ€” it competes with OAC for the high-frequency, low-complexity BvA questions that are 80% of what executive users actually ask.

Key files

FileRole
epm-nlq-src/pages/analytics.htmlFull dashboard UI: KPI cards, regional table, chart canvas, entity ranking, chart type chip strip, buildMainChart() function with 8 chart type branches
functions/api/nlq-query.jsShared NLQ endpoint. Analytics uses SCHEMA.chartTypes extended with stacked/ranking/combo. System prompt branch on mode:'analytics'.
epm-nlq-src/assets/epm-data.jsRegional and entity revenue data. Analytics reads ENTITY_REVENUES and REGIONAL_DATA objects for aggregation.

The waterfall chart implementation

Waterfall charts in Chart.js require floating bars โ€” each bar is defined by [start, end] rather than a single value. The plan baseline is a solid bar; each regional variance is a floating bar above or below it; the final actual total is a different colour. The transparent "base" bars that position each variance column are rendered first with backgroundColor:'transparent' and borderWidth:0.

Tech stack โ€” Every tool in this build

LayerToolWhy
LLMDeepSeek V3Intent classification, JSON mode, low cost
ChartsChart.js 4.x8 chart types, floating bar waterfall, dual-axis combo, tree-shakeable
Edge runtimeCloudflare Pages FunctionsShared with all 4 use cases โ€” one endpoint, mode parameter controls prompt branch
Data layerepm-data.jsRegional and entity aggregations pre-computed โ€” no chart-time aggregation cost
BuildEleventy v3.1.5Static site pipeline; analytics.html copied to _site/ verbatim
Auth30-day cookie + D1Middleware gates the analytics page; quick-access sets cookie on hub modal submit

Known attack surfaces

ThreatMitigation
Chart type injectionLLM output chartType is validated against the known 8-value enum before calling buildMainChart(). Unknown values default to bar.
Metric hallucinationKPI values are computed from DIMENSION_MEMBERS, not from LLM output. LLM only sets intent; all numbers come from the validated data layer.
Client-side data exposureDIMENSION_MEMBERS is loaded client-side (public demo data). Production: replace with server-side EPM API call; client never sees raw data object.
Rate abuse100 req/hour/IP rate limit at Cloudflare edge. Chart type switches cost zero โ€” no rate limit concern for interactive exploration.

Guardrails โ€” What prevents bad dashboards

  • Chart type validation: Only the 8 known types are allowed. LLM attempting a novel chart type falls back to bar.
  • KPI null guard: If revenue data for the selected entity/period/scenario is zero or missing, KPI cards show "โ€”" rather than $0 or a division-by-zero margin.
  • Waterfall balance check: If the sum of regional variances doesn't equal total BvA variance within a rounding threshold, a notice is shown โ€” the chart is still rendered but flagged as approximate.
  • Ranking minimum: Ranking chart requires at least 4 entities. If the entity selection resolves to fewer, the chart type falls back to bar.
  • Out-of-scope guard: Non-analytics questions (FP&A statements, SmartView grids) return the scoped error message with sample analytics queries.

Who is asking, and what are they allowed to see?

The demo answers neither question — it has a cookie gate and no notion of a user. In production these are the two questions everything else rests on, and they have different answers: authentication is who you are, authorization is what you may see. Corporate SSO settles the first. Only Oracle EPM Cloud can settle the second, and the single most important rule in this section is that this application must never become the place where that decision is made.

The rule that governs every choice below: a user must see exactly what they would see by logging into Oracle EPM Cloud directly — no more, and no less. If this tool can surface a number the user could not retrieve themselves, it has become a privilege-escalation path, and it will be found in the first access review.

9.1 · The identity chain, end to end

Finance user opens the tool in a browser — no local account, no password held here
1
Corporate identity provider
Entra ID · Okta · OCI IAM
OIDC Authorization Code + PKCE  (or SAML 2.0)
  • MFA and Conditional Access are enforced here — device compliance, location, risk signals
  • Returns an ID token (who the user is) and an access token (what they may call)
  • Group membership arrives as a claim; the application never handles a password
2
Application session
validate, never trust
  • Verify signature, issuer, audience and expiry against the IdP’s published keys
  • Read the group claims — there is no local user table and no local role table
  • Short-lived access token with refresh-token rotation; session timeout set to the data classification
Pattern A — identity propagation
OAuth 2.0 token exchange (on-behalf-of)
  • The API is called as the user
  • EPM enforces its own security natively
  • Audit trail names the real user
  • Preferred where the API supports it
Pattern B — service account + filtering
one read-only integration account
  • The application becomes the enforcement point
  • Entitlements fetched separately, applied in one audited place
  • Simpler and cacheable — and a filtering bug is a data breach
3
EPM identity domain
roles + dimension security
  • Roles: Service Administrator, Power User, User, Viewer — assigned to groups, never to individuals
  • Data level: Planning access permissions on Entity — and, critically, applied before aggregation rather than after
  • Group → role mapping lives in the platform, not in this application
Result, filtered to this user
analytics.html
  • The user sees exactly what they would see logging into the source system directly — no more
  • Every query logged against the real end user, never a shared account

9.2 · Federating the corporate identity provider

Oracle EPM Cloud does not replace your directory — it trusts it. The EPM Cloud identity domain is federated with the corporate IdP so authentication happens where it already happens, under policies security has already written.

Identity providerProtocolNotes
Microsoft Entra ID (formerly Azure AD)SAML 2.0 or OIDCThe common case. Conditional Access, MFA and device compliance are enforced at Entra and inherited automatically. On-premises Active Directory federates through Entra Connect rather than being integrated directly.
OktaSAML 2.0 or OIDCSame pattern; Okta groups drive EPM roles through SCIM provisioning.
OCI IAM (identity domains)NativeAlready present with Oracle EPM Cloud. Can be the primary IdP for a smaller estate, or a federated spoke of Entra/Okta for a larger one.
AD FSSAML 2.0Still seen where the estate is not yet cloud-first. Works, but you inherit the on-premises availability of the token service — if AD FS is down, nobody logs in.

For the browser application itself, use OIDC Authorization Code flow with PKCE. Not the implicit flow, which is deprecated and leaks tokens through the URL, and never a resource-owner password grant — a finance tool should not be capable of handling a password at all.

9.3 · From group membership to EPM roles

Roles are granted to groups, never to individuals, and the groups come from the directory. That one discipline is what makes joiner/mover/leaver work without anyone having to remember this application exists.

Entra ID group                    โ†’  EPM role / entitlement
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
FIN-EPM-Analysts                  โ†’  Planning User
FIN-EPM-Controllers-EMEA          โ†’  Power User + EMEA data scope
FIN-EPM-Admins                    โ†’  Service Administrator
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Provisioned by SCIM. Remove the user from the group and the
entitlement disappears on the next sync โ€” including here.

For this use case the relevant native entitlement is: Planning User with access to the Financials cube.

9.4 · The architectural decision: who enforces?

This is the choice that determines whether the deployment is defensible. Both patterns appear in the diagram above; the difference is where the security boundary actually sits.

Pattern A — identity propagationPattern B — service account + filtering
HowThe user’s token is exchanged (OAuth 2.0 on-behalf-of) for one scoped to the EPM API; calls are made as the userA single read-only integration account calls the API; the application filters the results
Enforcement pointOracle EPM CloudThis application
Audit trail showsThe real end userThe service account — you must log the real user separately
Failure modeToken plumbing is more complex; per-user rate limits applyA filtering bug is a data breach, and the entitlement copy drifts from reality
VerdictPrefer this wherever the API supports user-token authenticationAcceptable with discipline: narrowest possible service account, filtering centralised in one tested place, real user in every log line

The shortcut to refuse. Pattern B built with a Service Administrator account and no filtering at all is the most common way this gets delivered, because it works perfectly in UAT — testers are usually over-entitled, so nobody notices that everyone can see everything. It fails at the first access review, and by then it is in production with real users depending on it.

9.5 · Data-level security is the part that matters

Role membership decides whether a user can open the application. It does not decide which rows they get back, and confusing the two is the most expensive mistake available here.

  • For this use case: Planning access permissions on Entity — and, critically, applied before aggregation rather than after.
  • Apply it before aggregation, not after. Filtering a total that has already been computed across entities the user cannot see still leaks the total.
  • The NLQ layer needs its own check. Layer 4 already validates that the resolved point of view uses approved members; production adds a second test — that the resolved POV sits inside this user’s scope — and it runs before the data call, not after. A natural-language interface is very good at asking for things politely; the authorization check must not care how the question was phrased.
  • Fail closed. If entitlements cannot be resolved, return nothing and say so. An empty result is a support ticket; a permissive default is an incident.

9.6 · Provisioning, sessions and the leaver problem

  • SCIM provisioning from Entra or Okta into the EPM Cloud identity domain (OCI IAM, formerly IDCS), covering joiner, mover and leaver. The mover is the case people forget — somebody changing region should lose the old scope, not accumulate both.
  • No local user store. If this application keeps its own copy of who may do what, a leaver keeps access until somebody remembers to update it. Nobody ever does.
  • Short-lived access tokens with refresh-token rotation; align session timeout with the data classification rather than with convenience.
  • MFA and Conditional Access at the IdP — not reimplemented here. Device compliance and location policy come free with federation.
  • Quarterly recertification of both the groups that grant access and the service account’s own entitlements, evidenced and signed.
  • Break-glass access is a named, monitored, time-boxed account — never a shared credential in a password manager.

9.7 · What this means for Planning Analytics

ConcernAnswer for this use case
Native entitlement requiredPlanning User with access to the Financials cube
Data-level controlPlanning access permissions on Entity — and, critically, applied before aggregation rather than after
Use-case-specific sensitivityCross-entity rankings are the leak here. A ranked list of 44 entities shown to someone entitled to three of them discloses the other 41 by inference, even without exact figures. Aggregate only within the permitted entity set, and suppress rankings when that set is too small to anonymise.

9.8 · Security configuration checklist

  • ✓Oracle EPM Cloud federated with the corporate IdP over SAML 2.0 or OIDC; the cookie gate removed entirely
  • ✓Browser app uses OIDC Authorization Code + PKCE — no implicit flow, no password grant
  • ✓MFA and Conditional Access enforced at the IdP, not reimplemented in the application
  • ✓Roles granted to directory groups, never to individuals; SCIM covers joiner, mover and leaver
  • ✓Enforcement pattern chosen deliberately — Pattern A where the API supports it, or Pattern B with filtering centralised and tested
  • ✓Data-level security applied before aggregation, and the resolved POV checked against the user’s scope before the data call
  • ✓No local user table and no local role table anywhere in the application
  • ✓Every query logged against the real end user, even when a service account makes the call
  • ✓Authorization failures fail closed and are logged as security events rather than swallowed
  • ✓Quarterly recertification of access groups and of the service account’s own entitlements
Talk through your identity model → Back to the demo

From demo to a governed enterprise deployment

Everything above runs on synthetic data, a public LLM API key, a cookie gate, and no audit trail — deliberately, so the mechanics are inspectable. Taking Planning Analytics to production is not a rewrite; the 4-layer pipeline and the data-layer contract survive intact. It is a controlled-change program across six workstreams: architecture, LLM platform, security, SOX/audit, environment promotion, and operations. This section is the checklist we run with clients.

The one rule that matters most for this use case: the demo already sends only the schema and the user’s words to the LLM — never the financial values. Production must preserve that boundary exactly: the model resolves what to fetch, the EPM REST API fetches it under the user’s own security, and no cell value is ever part of a prompt.

10.1 · Production reference architecture

Finance user · corporate SSO (OIDC/SAML + MFA) · EPM role claims
1
Edge / API Gateway
WAF · rate limit · identity
  • Terminates SSO, validates the session, attaches the user’s EPM groups to the request
  • Rate limits per user, blocks anonymous access, scrubs PII patterns before anything reaches the orchestrator
2
NLQ Orchestrator
the 4-layer pipeline, hardened
L1 guardrails → L2 grounding → L3 LLM adapter → L4 eval + fallback
  • L2 grounding reads dimension metadata from EPM on a schedule — not a hardcoded schema
  • Only the schema + user query go to the model; financial values never leave the data layer
  • L4 rejects anything outside the approved member lists and falls back to the deterministic parser
Oracle OCI Generative AI
same tenancy as EPM Cloud
  • Data stays inside the OCI boundary
  • Natural fit when EPM is already in OCI
Azure OpenAI / AWS Bedrock / Vertex AI
private endpoint, zero retention
  • Use the hyperscaler the org already governs
  • Enterprise DPA, no training on prompts
Self-hosted open weights
VPC / air-gapped
  • For regulated or sovereign data
  • Highest control, highest run cost
3
EPM Data Layer
Oracle EPM REST API
  • Oracle EPM Planning — regional and entity aggregates via REST data slices (or a nightly extract to a reporting store with a TTL cache for dashboard latency)
  • Least-privilege service account (read-only role, one app, one pod) with the token in a vault and rotated
  • Results filtered to the requesting user’s EPM security before rendering
4
Audit & Observability
append-only
  • Every query logged: user, timestamp, raw query, parsed intent JSON, model + prompt version, POV returned, latency, cost
  • Exported to the SIEM; retained per the SOX evidence schedule
  • Dashboards for fallback rate, eval pass rate, guardrail hits, p95 latency, spend
Rendered result + evidence trail
analytics.html
  • The parsed JSON is shown to the user as the explanation (“AI: entity · year · scenario — 93% confident”) — the same line the demo prints today
  • Every number on screen traces to an EPM cell intersection an auditor can reproduce

10.2 · Choosing the LLM platform

The demo’s DeepSeek call is a placeholder for a single adapter, callLLM(system, user), behind Layer 3. Swapping the provider changes one function and zero business logic. Pick the platform the organisation already governs — the security and procurement review is the long pole, not the integration.

OptionChoose whenData posture
Oracle OCI Generative AI (Cohere Command, Llama)EPM Cloud already lives in OCI; you want one cloud boundary and one contractPrompts stay in the OCI tenancy; no training on customer data; dedicated AI clusters available for isolation
Azure OpenAI ServiceMicrosoft-first finance estate (Entra ID, Purview, Sentinel already in place)Private endpoint, regional deployment, zero-retention by default under the enterprise agreement
AWS Bedrock (Claude, Titan) / Google Vertex AI (Gemini)The org’s landing zone is AWS or GCP; VPC endpoints and IAM already auditedVPC/PSC private access, no data used for training, CloudTrail/Cloud Audit Logs integration
Direct enterprise API (Anthropic, OpenAI)Fastest model access; acceptable when a zero-data-retention agreement and DPA are signedZDR endpoint, SSO-managed keys, SOC 2 report on file
Self-hosted open weights (Llama, Mistral, Qwen via vLLM)Sovereign or air-gapped requirements; regulated data classification forbids any external inferenceFull control; you own patching, eval, and capacity — budget for an MLOps owner

Put a model gateway in front of whichever you choose (Azure API Management, OCI API Gateway, Kong AI Gateway, LiteLLM, or Portkey): it owns key custody, per-team spend caps, routing and fallback between models, prompt/response logging, and lets you retire a deprecated model without touching the application.

10.3 · Security controls

ControlImplementation
Identity & accessCovered in full in section 09 — corporate SSO, group-to-role mapping, and the decision about who enforces data-level security. Listed here because it is a production gate, not because it is optional.
Service accountOne read-only EPM service account per application per pod, least-privilege role, no interactive login, credential in a vault (OCI Vault, Azure Key Vault, HashiCorp Vault), rotated on a schedule and on staff change.
Secrets & configNo secrets in code or build artifacts; environment-specific config injected at deploy; .dev.vars-style files never leave a developer machine.
NetworkPrivate endpoints to the LLM provider and to EPM where the platform supports them; egress allow-list so the orchestrator can reach exactly two hosts; TLS 1.2+ everywhere.
Prompt-injection & input guardrailsLayer 1 (already in the demo) blocks instruction-override patterns, enforces length and scope; extend with a classifier on the gateway and log every rejection.
Output guardrailsLayer 4 (already in the demo) validates every returned member against the approved lists and strips unexpected keys; production adds a policy check that the resolved POV is inside the user’s security scope before the data call.
Data minimisationPrompts contain metadata and the user’s query only. No cell values, no employee names, no free-text comments from EPM. Logged prompts are classified and retained accordingly.
EncryptionIn transit (TLS) and at rest (provider-managed KMS); audit logs on immutable storage with customer-managed keys where policy requires.

10.4 · SOX, audit, and model-risk controls

A read-only NLQ layer does not change a financial-reporting control, but it is an interface to a SOX-relevant system and lands squarely in ITGC scope. Treat prompts, schemas, and eval sets as code — that single decision satisfies most of what an auditor will ask for.

RequirementHow it is satisfied
Complete, immutable audit trailAppend-only log of user, timestamp, raw query, parsed JSON, model and prompt version hash, POV returned, and row count — WORM storage, retained for the evidence period (typically 7 years), exported to the SIEM.
Change managementPrompt templates, few-shot examples, approved-member schema, and code are version-controlled; every change follows ticket → peer review → test evidence → CAB approval → deploy. A prompt edit is a code change.
Segregation of dutiesDevelopers cannot deploy to production; the service-account owner is not a developer; production secrets are held by platform operations.
Access recertificationQuarterly review of who can use the tool and of the service account’s EPM roles, evidenced and signed.
Testing evidenceA golden-query regression suite (the few-shot examples plus a larger labelled set) runs in CI before every release; pass rate and diffs are archived as release evidence.
Model risk managementAn inventory entry (intended use, limitations, owner, validation date) in the model-risk register — the SR 11-7 pattern for financial services; periodic re-validation when the model or prompt changes.
Reproducibility & lineageEvery displayed number traces to an EPM POV and a consolidation/calculation timestamp; an auditor can re-query the same intersection in EPM and match it.
ExplainabilityThe parsed intent JSON is the explanation and is shown to the user on every response — no hidden reasoning between the query and the data call.

10.5 · Dev → Test → Prod promotion

EnvironmentEPM targetDataGate to leave
DevEPM Test pod (developer slice)Synthetic or maskedUnit tests on the data layer; lint; eval suite ≥ threshold against the Test LLM deployment
Test / UATEPM Test pod (full refresh)Masked copy of productionBusiness UAT sign-off on the golden queries; security scan; performance run (p95 latency, fallback rate)
ProdEPM Production podLiveChange ticket approved; deploy in window; smoke test; hypercare with rollback ready
  • Promoted artifacts: application build, prompt templates (versioned), approved-member schema snapshot, eval set, infrastructure config (IaC) — all from the same Git tag.
  • Pipeline: branch → PR review → CI (tests + evals) → deploy to Test → UAT sign-off → CAB → deploy to Prod → smoke test. Hosting can stay on Cloudflare Pages/Workers or move to OCI Functions + API Gateway or the org’s standard platform — the code does not care.
  • Configuration: per-environment secrets and endpoints injected at deploy; the same build runs in every environment.
  • Metadata sync: a scheduled job refreshes dimension metadata into Layer 2 grounding with change detection, so a new entity or account appears in the approved lists without a code release.
  • Rollback: previous build and previous prompt version retained; rollback is a redeploy, and because prompts are versioned it also reverts a prompt regression.

10.6 · Operating it

  • SLOs: p95 latency, availability of the read path (the deterministic fallback keeps it alive when the LLM is down — already built), fallback rate as a quality signal, eval pass rate per release.
  • Cost governance: per-user and per-team token budgets at the gateway; alert on anomalies; the unit-cost model earlier in this kit is the baseline.
  • Model lifecycle: providers retire models on a schedule — re-run the eval suite on the successor before switching, and record the switch as a change.
  • Incident runbook: LLM outage → fallback parser; EPM API outage → cached metadata with a stale banner; guardrail spike → review logs for injection attempts.

10.7 · What changes for Planning Analytics

ConcernProduction answer
System of recordOracle EPM Planning — regional and entity aggregates via REST data slices (or a nightly extract to a reporting store with a TTL cache for dashboard latency)
Read/write postureRead-only. Aggregations are display-level; variance math must match Planning’s own BvA members.
Use-case-specific controlCross-entity rankings leak scope: restrict the ranking view to users whose EPM security already spans those entities, or aggregate only within the user’s permitted entity set.

10.8 · Production readiness checklist

  • ✓LLM platform selected from the governed list, DPA / zero-retention terms on file, gateway in front of it
  • ✓SSO integrated; authorisation derived from EPM security groups; cookie gate removed
  • ✓Read-only EPM service account per pod, credential in a vault, rotation scheduled
  • ✓Prompts, schema, and eval set version-controlled and under change management
  • ✓Append-only audit log wired to the SIEM with the agreed retention
  • ✓Golden-query eval suite passing in CI; results archived as release evidence
  • ✓Dev / Test / Prod pipeline with gates, IaC, and a rehearsed rollback
  • ✓Model-risk register entry and owner named; first re-validation date set
  • ✓Metadata refresh job scheduled with change detection
  • ✓SLOs, cost caps, and the incident runbook agreed with platform operations
Plan a production rollout with us → Back to the demo