Skip to content

πŸ”— E8-UQB Integration Architecture

MVP Scope: Simple database lookups for pre-filling E8 questions from existing policy/insurance answers Post-MVP: ML-based confidence scoring, intelligent inference, predictive analytics

Executive Summary

The Essential Eight (E8) assessment framework integrates with the Unified Question Bank (UQB) to deliver a board-friendly compliance experience while leveraging our "answer once, use everywhere" philosophy. This integration enables 85% pre-completion through simple database lookups (not ML inference) that match E8 questions to existing answers from policies, insurance questionnaires, and other assessments.

MVP Implementation: Pre-fill uses direct field mappings (e.g., "MFA required" in password policy β†’ E8 MFA question). Confidence is binary: either we have a mapped answer (100% confidence) or we don't (0% confidence).

Integration Overview

Core Principles

  1. E8 as Board Initiative: Present E8 as a distinct feature while leveraging UQB infrastructure
  2. Role-Based Delegation: Automatically route ~35 technical questions to IT, ~5 governance questions to board
  3. Triple Crossover (MVP): Pre-fill from policies (45%), insurance (30%), and other assessments (10%) using simple field lookups
  4. Two-Phase Process: Discovery (IT) β†’ Decision (Board)

MVP Pre-Fill Approach

The "intelligent" crossover is actually simple database joins:

-- Example: Pre-fill E8 MFA question from password policy
SELECT policy_fields.value as prefill_value,
       'password-authentication-policy' as source
FROM policy_fields
WHERE policy_fields.org_id = $1
  AND policy_fields.field_name = 'mfa_admin_required'
  AND policy_fields.policy_type = 'password-authentication-policy';

No ML inference, no AI, just structured data lookups.

Architecture Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    E8 Assessment Module                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   E8 UI     β”‚  β”‚ E8 Question  β”‚  β”‚   E8 Maturity    β”‚  β”‚
β”‚  β”‚  Component  β”‚  β”‚   Router     β”‚  β”‚   Calculator     β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚                 β”‚                    β”‚            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚              E8 Service Layer                         β”‚  β”‚
β”‚  β”‚  β€’ Pre-fill Engine  β€’ Role Mapper  β€’ Board Presenter β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                    β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
                    β”‚    UQB    β”‚
                    β”‚   Core    β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Model Extensions

E8Question Interface

interface E8Question extends UnifiedQuestion {
  // E8-specific metadata
  e8Id: string // E8_STRATEGY_NNN format
  boardTranslation: string // Plain English version
  quickWin: boolean // Can be completed quickly
  estimatedTime: string // e.g., "30 seconds"

  // Role routing
  primaryRole: UserRole
  delegationPath: string[] // Delegation hierarchy

  // E8 mappings
  e8Strategy: E8Strategy // One of 8 strategies
  controlMappings: string[] // ACSC control IDs
  maturityImpact: {
    ML0: string[] // Answers that indicate ML0
    ML1: string[] // Answers that indicate ML1
    ML2: string[] // Answers that indicate ML2
    ML3?: string[] // Answers that indicate ML3
  }

  // Crossover sources
  crossoverSources: CrossoverSource[]
}

interface CrossoverSource {
  type: 'policy' | 'insurance' | 'assessment'
  id: string // Source identifier
  field?: string // Specific field in source
  confidence: number // 0-1 confidence score
}

enum E8Strategy {
  APPLICATION_CONTROL = 'application_control',
  PATCH_APPLICATIONS = 'patch_applications',
  OFFICE_MACROS = 'office_macros',
  USER_HARDENING = 'user_hardening',
  ADMIN_PRIVILEGES = 'admin_privileges',
  PATCH_OS = 'patch_os',
  MFA = 'mfa',
  REGULAR_BACKUPS = 'regular_backups',
}

Role-Based Routing

interface RoutedQuestions {
  assigned: E8Question[] // Questions for current user
  delegated: DelegatedQuestion[] // Questions delegated to others
  completed: CompletedQuestion[] // Pre-filled questions
  visibility: E8Question[] // Questions user can see but not answer
}

interface DelegatedQuestion extends E8Question {
  delegatedTo: string // Role or specific user
  reason: string // Why delegated
  dueDate?: Date // When needed by
}

interface CompletedQuestion extends E8Question {
  preFilledValue: any // The pre-filled answer
  preFilledFrom: string // Source description
  confidence: number // Confidence in pre-fill
  lastUpdated: Date // When source was updated
  requiresVerification: boolean // Needs human review
}

Integration Components

1. E8 Pre-Fill Engine

Leverages UQB to pre-fill E8 questions from existing data:

class E8PreFillEngine {
  constructor(
    private uqb: UnifiedQuestionBank,
    private policyService: PolicyService,
    private insuranceService: InsuranceService
  ) {}

  async preFillAssessment(orgId: string): Promise<PreFillResult> {
    const e8Questions = await this.loadE8Questions()
    const results: PreFilledQuestion[] = []

    for (const question of e8Questions) {
      // Try each crossover source in order of confidence
      const sources = question.crossoverSources.sort(
        (a, b) => b.confidence - a.confidence
      )

      for (const source of sources) {
        const value = await this.extractFromSource(source, orgId)

        if (value !== undefined) {
          results.push({
            questionId: question.id,
            value,
            source,
            confidence: source.confidence,
          })
          break // Use first available source
        }
      }
    }

    return {
      total: e8Questions.length,
      preFilled: results.length,
      percentage: (results.length / e8Questions.length) * 100,
      bySource: this.groupBySourceType(results),
      estimatedTimeSaved: this.calculateTimeSaved(results),
    }
  }

  private async extractFromSource(
    source: CrossoverSource,
    orgId: string
  ): Promise<any> {
    switch (source.type) {
      case 'policy':
        return this.policyService.getFieldValue(orgId, source.id, source.field)

      case 'insurance':
        return this.insuranceService.getAnswer(orgId, source.id)

      case 'assessment':
        return this.uqb.getAnswer(orgId, source.id)

      default:
        return undefined
    }
  }
}

2. Role-Based Question Router

Routes questions based on user role and delegation model:

class E8QuestionRouter {
  private delegationRules = {
    board: {
      delegates: ['executive', 'it_manager'],
      keepQuestions: (q: E8Question) =>
        q.primaryRole === 'board' ||
        q.e8Strategy === E8Strategy.REGULAR_BACKUPS, // Board cares about recovery
    },
    executive: {
      delegates: ['it_manager', 'admin'],
      keepQuestions: (q: E8Question) =>
        q.primaryRole === 'executive' || q.importance === 'critical',
    },
    it_manager: {
      delegates: ['admin', 'staff'],
      keepQuestions: (q: E8Question) =>
        q.domain === 'security' || q.domain === 'technical',
    },
  }

  routeQuestions(
    questions: E8Question[],
    userRole: UserRole,
    preFilled: Set<string>
  ): RoutedQuestions {
    const result: RoutedQuestions = {
      assigned: [],
      delegated: [],
      completed: [],
      visibility: [],
    }

    for (const question of questions) {
      // Already answered via pre-fill
      if (preFilled.has(question.id)) {
        result.completed.push(question)
        continue
      }

      // Check delegation rules
      const rules = this.delegationRules[userRole]

      if (rules.keepQuestions(question)) {
        result.assigned.push(question)
      } else if (this.canDelegate(userRole, question.primaryRole)) {
        result.delegated.push({
          ...question,
          delegatedTo: question.primaryRole,
          reason: this.getDelegationReason(userRole, question),
        })
      } else {
        result.visibility.push(question)
      }
    }

    return result
  }
}

3. Board Experience Presenter

Creates the simplified board view:

class E8BoardPresenter {
  async presentToBoard(
    orgId: string,
    assessmentId: string
  ): Promise<BoardE8View> {
    const assessment = await this.getAssessment(assessmentId)
    const maturity = await this.calculateMaturity(assessment)

    return {
      // The one number that matters
      currentLevel: maturity.overall,

      // Visual representation
      maturityRadar: {
        strategies: maturity.byStrategy,
        benchmark: await this.getIndustryBenchmark(orgId),
        minimum: this.getRegulatedMinimum(orgId),
      },

      // Clear decision options
      targetOptions: [
        {
          level: 1,
          label: 'Basic Protection',
          description: 'Stops opportunistic attacks',
          suitable: 'Small businesses without sensitive data',
          investment: { cost: '$50k', time: '6 months' },
        },
        {
          level: 2,
          label: 'Industry Standard',
          description: 'Expected by boards and insurers',
          suitable: 'Most businesses with customer data',
          investment: { cost: '$150k', time: '9 months' },
          recommended: true,
        },
        {
          level: 3,
          label: 'Advanced Protection',
          description: 'Nation-state level defense',
          suitable: 'Critical infrastructure, major banks',
          investment: { cost: '$300k', time: '18 months' },
        },
      ],

      // Work completed summary
      delegationSummary: {
        totalQuestions: 40,
        answeredByIT: 35,
        answeredByManagement: 3,
        remainingForBoard: 2,
        percentComplete: 95,
      },

      // Clear next steps
      boardActions: [
        'Review current maturity level',
        'Compare to industry benchmark',
        'Select target maturity level',
        'Approve budget and timeline',
      ],
    }
  }
}

Implementation Flow

Phase 1: Discovery (IT/Management)

async function runE8Discovery(orgId: string): Promise<DiscoveryResult> {
  // 1. Load E8 questions into UQB format
  const e8Questions = await loadE8Questions()

  // 2. Pre-fill from existing sources
  const preFillResult = await preFillEngine.preFillAssessment(orgId)

  // 3. Route remaining questions
  const unanswered = e8Questions.filter(
    (q) => !preFillResult.preFilled.find((p) => p.questionId === q.id)
  )
  const routed = await router.routeQuestions(unanswered, 'it_manager')

  // 4. IT completes technical questions
  const answers = await collectAnswers(routed.assigned)

  // 5. Calculate current maturity
  const maturity = await calculator.calculateMaturity({
    preFilled: preFillResult.preFilled,
    answered: answers,
  })

  return {
    currentLevel: maturity.overall,
    strategies: maturity.byStrategy,
    completion: {
      preFilled: preFillResult.percentage,
      answeredByIT: routed.assigned.length,
      total: 40,
    },
    readyForBoard: true,
  }
}

Phase 2: Board Decision

async function presentE8ToBoard(
  orgId: string,
  discoveryResult: DiscoveryResult
): Promise<BoardDecision> {
  // 1. Create board-friendly view
  const boardView = await presenter.presentToBoard(orgId, discoveryResult)

  // 2. Board reviews and decides
  const decision = await boardInterface.collectDecision({
    current: boardView.currentLevel,
    options: boardView.targetOptions,
    recommendation: getRecommendation(orgId, boardView),
  })

  // 3. Create implementation plan
  if (decision.approved) {
    await createE8Plan({
      target: decision.targetLevel,
      timeline: decision.timeline,
      budget: decision.budget,
      owner: decision.delegatedTo,
      milestones: generateMilestones(decision),
    })
  }

  return decision
}

Success Metrics

Technical Metrics

  • Pre-fill accuracy: > 85%
  • Question routing accuracy: > 95%
  • Time to complete assessment: < 25 minutes
  • Board decision time: < 5 minutes

Business Metrics

  • Board satisfaction: "Finally understand our cyber position"
  • IT efficiency: 75% reduction in assessment time
  • Compliance coverage: Maps to multiple frameworks
  • Implementation success: 80% achieve target within timeline

Audit Export Architecture (MVP)

Overview

Instead of building a full 152-control management UI, we provide an export function that generates audit-ready reports from our 40-question assessment.

Key Design Decision: Serve the 5% use case (external audits) without gold-plating the 95% use case (board decisions).

Control Reference Data

Store all 152 ACSC controls as read-only reference data:

interface ACSCControlReference {
  id: string // ML2-RA-04
  strategy: E8Strategy // admin_privileges
  maturityLevel: 'ML1' | 'ML2' | 'ML3'
  description: string // Full ACSC requirement text
  questionMapping: string // E8_AP_003 (which question covers this)
  displayOrder: number
}

This data is populated once from official ACSC documentation, never modified by users.

Question-Level Evidence & Exceptions

Extend question model to support evidence and exceptions:

interface E8QuestionAnswer {
  id: string
  assessmentId: string
  questionId: string
  selectedOption: string

  // Evidence fields (NEW)
  evidence: {
    files: AttachedFile[] // Policy docs, screenshots, configs
    notes: string // Free-text explanation
    lastUpdated: Date
    updatedBy: string
  }

  // Exception fields (NEW)
  exception: {
    isException: boolean
    justification: string // Why this exception exists
    compensatingControls: string // What we do instead
    riskAcceptance: string // Who approved the risk
    reviewDate: Date // When to re-assess
    boardApprovalDate: Date // Governance trail
  }
}

Evidence and exceptions are collected at the question level, then flow to all controls covered by that question.

Export Generation Logic

async function generateAuditExport(assessmentId: string): Promise<ExportData> {
  // 1. Load assessment with all question answers
  const assessment = await db.e8_assessments.findById(assessmentId)
  const answers = await db.e8_question_answers.findByAssessment(assessmentId)

  // 2. Load all 152 ACSC controls from reference data
  const allControls = await db.e8_control_reference.findAll()

  // 3. Map each control to its source question
  const controlRows = allControls.map((control) => {
    const sourceAnswer = answers.find(
      (a) => a.questionId === control.questionMapping
    )

    return {
      control_id: control.id,
      control_description: control.description,
      strategy: control.strategy,
      maturity_level: control.maturityLevel,
      status: inferControlStatus(control, sourceAnswer),
      source_question_id: control.questionMapping,
      source_question_text: getQuestionText(control.questionMapping),
      evidence_summary: formatEvidence(sourceAnswer?.evidence),
      exception_justification: sourceAnswer?.exception?.justification,
      last_assessed: assessment.completedAt,
    }
  })

  // 4. Generate Excel/CSV
  return {
    filename: `${org.name}-e8-audit-report-${date}.xlsx`,
    format: 'excel',
    data: controlRows,
    metadata: {
      organizationName: org.name,
      assessmentDate: assessment.completedAt,
      overallMaturity: calculateOverallML(answers),
      totalControls: 152,
      implementedControls: controlRows.filter((c) => c.status === 'implemented')
        .length,
    },
  }
}

function inferControlStatus(
  control: ACSCControlReference,
  answer: E8QuestionAnswer
): ControlStatus {
  // Exception takes precedence
  if (answer?.exception?.isException) {
    return 'documented_exception'
  }

  // Check if answer indicates this control is implemented
  const maturityMapping = getMaturityMapping(control.questionMapping)
  const controlImplemented = maturityMapping[control.maturityLevel]?.includes(
    answer?.selectedOption
  )

  if (controlImplemented) {
    return 'implemented'
  } else if (answer?.selectedOption?.includes('Partially')) {
    return 'partially_implemented'
  } else {
    return 'not_implemented'
  }
}

Export Output Format

Excel/CSV Structure:

Column Description Example
control_id ACSC control ID ML2-RA-04
control_description Full requirement text "Privileged access disabled after 45 days..."
strategy One of 8 strategies Admin Privileges
maturity_level ML1, ML2, or ML3 ML2
status Implementation status implemented
source_question_id Covering question E8_AP_003
source_question_text Question asked "Are admin accounts auto-disabled?"
evidence_summary Files + notes "password-policy.pdf; Quarterly reviews"
exception_justification If exception, why "Legacy systems require manual review"
last_assessed Assessment date 2025-10-13

Progressive Disclosure

Three Levels of Detail (no control-level UI, just export):

  1. Board View (Primary UI)

  2. 8 strategy-level summaries

  3. Overall maturity level
  4. Target vs current gaps
  5. 2-3 minute experience

  6. Management View (Assessment UI)

  7. 40 questions with answers

  8. Evidence upload per question
  9. Exception documentation per question
  10. Delegation and routing

  11. Audit Export (Generated Artifact)

  12. 152 controls with status
  13. Evidence per control (inherited from questions)
  14. Exception justifications
  15. Audit-ready Excel/CSV

Integration with UQB

The audit export leverages UQB's "answer once, use everywhere" philosophy:

// Question answered once
E8_MFA_001: "Is MFA mandatory for admin accounts?"
Answer: "Yes"
Evidence: "password-auth-policy.pdf"

// Flows to multiple controls in export
ML1-MF-01: "MFA for online services" β†’ implemented (from E8_MFA_001)
ML2-MF-01: "MFA for privileged users" β†’ implemented (from E8_MFA_001)
ML2-MF-07: "MFA uses something you have + know" β†’ implemented (from E8_MFA_001)

This maintains the UQB principle while serving audit needs without UI complexity.

Post-MVP Future Enhancements

Phase 2: Continuous Monitoring (After MVP + 20 customers)

  • Real-time maturity tracking
  • Automated evidence collection
  • Alert on maturity degradation
  • Quarterly board updates

Trigger: Customer demand + stable MVP platform

Phase 3: Control Management UI (Only if customers demand)

  • Full 152-control management interface
  • Per-control evidence workflows
  • Real-time control status tracking
  • Control implementation workflows
  • Integration with vulnerability scanners

Trigger: >50% customers using export monthly + >3 customers requesting in-platform control management

Don't build if: Export satisfies audit needs and customers prefer simple board interface

Phase 4: Predictive Analytics (Year 2+)

  • ML-based maturity predictions
  • Cost optimization recommendations
  • Peer benchmarking insights
  • Risk-adjusted target recommendations

Trigger: Sufficient data (100+ assessments) + ML infrastructure budget

Conclusion

The E8-UQB integration transforms a complex 152-control framework into a streamlined board decision while maintaining technical rigor. By leveraging the UQB's "answer once, use everywhere" philosophy, we deliver immediate value through pre-filling while positioning E8 as a distinct board initiative.

The audit export bridges board simplicity with audit compliance, serving the 5% use case (external audits) without gold-plating the 95% use case (board governance). This pragmatic approach validates demand for full control management before committing significant development resources.