Skip to main content

In this article

Security Assurance Case and Security Model

Executive Summary

HVE Core is an enterprise prompt engineering framework for GitHub Copilot consisting of:

  • Markdown-based prompt artifacts (instructions, prompts, agents, skills)
  • PowerShell automation scripts for linting and validation
  • GitHub Actions CI/CD workflows
  • VS Code extension packaging utilities
  • The Mural skill runtime: a Python CLI with an OAuth client, local token store, and outbound HTTP egress to Mural and Azure Blob endpoints
  • The GitLab skill runtime: a Python REST CLI with public-client OAuth, a fixed loopback callback, a local profile store, and explicit legacy PAT support
  • The Jira skill runtime: a Python REST CLI with environment credentials and scoped routing to Atlassian's resource API

Most of the repository contains no runtime services, databases, or user data storage and is targeted primarily by supply chain and developer workflow threats. The Mural, GitLab, and Jira skills are runtime exceptions. Mural holds OAuth tokens in the OS keyring or a mode-0600 plaintext file fallback. GitLab holds profile-bound OAuth access and refresh tokens in an owner-only POSIX local store and fails closed for OAuth persistence on Windows. Jira reads expiring Cloud API tokens or Data Center PATs from the environment without persistence. Threats specific to these runtimes are analyzed in the OAuth Authentication Threats, Jira Credential Threats, GitLab Credential Threats, and Mural Skill Runtime Hardening sections. Security relies on defense-in-depth with 25+ automated controls validated through CI/CD pipelines.

Security Posture Overview

CategoryStatusControl CountAutomated
Supply Chain SecurityStrong9 controls100%
Code QualityStrong9 controls100%
Access ControlStrong4 controls100%
Vulnerability ManagementStrong3 controls100%
Total25+25100%

Contents

System Description

Components

HVE Core contains seven primary component categories:

  1. Prompt Engineering Artifacts (.github/instructions/, .github/prompts/, .github/agents/, .github/skills/)

    • Markdown files with YAML frontmatter
    • Consumed by GitHub Copilot during development sessions
    • No executable code execution within prompts
  2. PowerShell Scripts (scripts/)

    • Linting and validation utilities
    • CI/CD automation support
    • No external network connections except documented tool downloads
  3. GitHub Actions Workflows (.github/workflows/)

    • PR validation pipeline
    • Security scanning (CodeQL, dependency review)
    • Release automation
  4. VS Code Extension (extension/)

    • Packaging configuration
    • Extension manifest
    • No telemetry or data collection
  5. Mural Skill Runtime (.github/skills/experimental/mural/)

    • Python CLI dispatched through argparse; an agent caller invokes it through a terminal tool, so stdout and stderr are captured into agent context
    • OAuth 2.0 Authorization Code + PKCE client with per-user on-disk token cache (mode 0600)
    • Outbound HTTPS to the Mural REST API; trust posture detailed in Mural Skill Runtime Hardening and OAuth Authentication Threats
  6. GitLab Skill Runtime (.github/skills/project-planning/gitlab/)

    • Public-client PKCE and human-assisted device authorization
    • Fixed loopback callback, owner-only OAuth profile store, and HTTPS no-redirect API egress
  7. Jira Skill Runtime (.github/skills/project-planning/jira/)

    • Environment-only Cloud API token or Data Center PAT
    • HTTPS no-redirect routing to a validated Jira origin or the fixed Atlassian resource origin

Data Flow

Security Inheritance from GitHub Copilot

HVE Core artifacts are consumed by GitHub Copilot, which provides foundational security:

Inherited ControlProviderHVE Core Responsibility
LLM input/output filteringGitHub CopilotNone; artifacts are Copilot inputs
Token encryption in transitGitHub CopilotNone; handled by Copilot infrastructure
Organization policy enforcementGitHub CopilotDocument compatible policy options
Audit loggingGitHub CopilotNone; uses Copilot audit streams
SOC 2 Type II complianceGitHubNone; infrastructure control

Trust Boundaries

Boundary Diagram

┌──────────────────────────────────────────────────────────────────────────────┐
│ TRUST BOUNDARY: Repository Contents │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Controlled Artifacts │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │ │
│ │ │ Prompts │ │ Scripts │ │ Workflows │ │ Documentation │ │ │
│ │ │ .md files │ │ .ps1 files │ │ .yml files │ │ .md files │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ └────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────▼────────────────────────────────────┐ │
│ │ TRUST BOUNDARY: CI/CD Pipeline │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │ │
│ │ │ PR Valid. │ │ CodeQL │ │ Dep Review │ │ Release │ │ │
│ │ │ Workflow │ │ Analysis │ │ Workflow │ │ Workflow │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ └────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────┼──────────────────────────────────┐
│ ▼ │
│ TRUST BOUNDARY: External Dependencies │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────────┐ │
│ │ npm │ │ GitHub │ │ PowerShell │ │ Third-party │ │
│ │ Packages │ │ Actions │ │ Gallery │ │ MCP Servers │ │
│ └────────────┘ └────────────┘ └────────────┘ └──────────────┘ │
└────────────────────────────────────────────────────────────────────┘

Boundary Descriptions

BoundaryAssets ProtectedControls Enforced
Repository ContentsSource code, prompts, scriptsCODEOWNERS, branch protection, PR review
CI/CD PipelineBuild artifacts, security scan resultsMinimal permissions, dependency pinning
External Dependenciesnpm packages, Actions, MCP serversDependency review, staleness monitoring
Dev ContainerDevelopment environment, toolingSHA256 verification, first-party features
Mural Skill RuntimeOAuth tokens, Mural API egressOS keyring / 0600 token cache, PKCE, loopback redirect URI
GitLab Skill RuntimeOAuth/PAT credentials, GitLab egressPKCE/device flow, fixed callback, owner-only store, no-redirect
Jira Skill RuntimeAPI token/PAT, Jira egressEnvironment-only credentials, scoped destination binding, no-redirect

Security Model

This section documents threats using STRIDE methodology (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege), supplemented with AI-specific and Responsible AI threat categories.

STRIDE Threats

S-1: Compromised GitHub Action via Tag Substitution

FieldValue
CategorySpoofing
AssetCI/CD pipeline integrity
ThreatAttacker compromises upstream Action repository and replaces tag with malicious code
LikelihoodMedium (documented supply chain attacks exist)
ImpactHigh (full CI/CD compromise, secret exfiltration)
MitigationsDependency pinning for all Actions, staleness monitoring, CodeQL scanning
Residual RiskLow (SHA immutable; requires GitHub infrastructure compromise)
StatusMitigated

S-2: npm Package Substitution Attack

FieldValue
CategorySpoofing
AssetBuild dependencies
ThreatMalicious package published with same name or typosquatting
LikelihoodMedium (common attack vector)
ImpactMedium (limited runtime exposure; primarily build-time)
MitigationsPackage-lock.json integrity, npm audit, dependency review
Residual RiskLow
StatusMitigated

T-1: Unauthorized Modification of Security Controls

FieldValue
CategoryTampering
AssetWorkflow files, security scripts
ThreatAttacker with write access disables security checks
LikelihoodLow (requires compromised maintainer account)
ImpactHigh (security controls bypassed)
MitigationsCODEOWNERS enforcement, branch protection, PR review requirements
Residual RiskLow
StatusMitigated

T-2: Malicious Prompt Injection via PR

FieldValue
CategoryTampering
AssetPrompt artifacts
ThreatContributor submits prompt with hidden malicious instructions
LikelihoodMedium (social engineering possible)
ImpactMedium (affects Copilot behavior for consumers)
MitigationsPR review, CODEOWNERS, frontmatter validation
Residual RiskMedium (semantic analysis not automated)
StatusPartially Mitigated

T-3: Script Injection via Workflow Inputs

FieldValue
CategoryTampering / Elevation of Privilege
AssetGitHub Actions run: and github-script steps
ThreatA workflow input interpolated directly into a shell command can alter command structure and execute unintended instructions on the workflow runner
LikelihoodLow (fork execution requires maintainer approval; the reachable payload is a directory name rather than reviewable code)
ImpactLow (the reachable jobs already execute the pull request's own code under contents: read with no secrets, so injection grants no privilege the actor lacks)
MitigationsEnvironment-variable isolation of every input not declared type: boolean (CQ-6); repository-derived project-path validation at all three project-discovery steps (CQ-7); deviation detection in the blocking dangerous-workflow gate (CQ-8); fork workflow approval (CQ-9)
Residual RiskLow
StatusMitigated
SourceNIST SP 800-53 SI-10, SA-15; CWE-94; GitHub Actions secure use reference
Trust Boundary CrossedRepository Contents ↔ GitHub Actions Runner
Detectiondangerous-workflow/direct-input-interpolation findings in PR validation and the Security tab
Traced path

The reachable instance of this threat ran from repository content to a shell context in three hops. A project discovery step enumerated directories containing pyproject.toml from the checked-out pull-request head and published the directory names as a JSON matrix through GITHUB_OUTPUT. fromJson decoded that output into matrix.directory, which was forwarded as the working-directory input to five reusable workflows. Those workflows interpolated the input inside run: blocks, including single-quoted PowerShell assignments and a Bash command substitution writing to GITHUB_OUTPUT. A contributor therefore controlled the value by adding a directory whose name contained a shell metacharacter. JSON encoding protected the output write but decoded before the downstream interpolation, so it did not protect the consuming step.

Control layering and its boundaries

CQ-6 is the control that holds on the pull-request path, because an input read from a step-level environment variable reaches the shell as data and is never parsed as command structure. CQ-7 rejects the hostile value earlier and is authoritative on merged-content paths, but on a pull request the guard is part of the contributor's own checkout and is therefore a fail-fast signal and a review artifact rather than a boundary against that contributor. CODEOWNERS review of /scripts/ and /.github/ (AC-2) prevents a weakened guard from reaching the default branch. CQ-9 prevents an unapproved fork pull request from executing at all, but it binds outside contributors only and reviews a code diff, which is a weak signal against a payload carried in a directory name.

Detection boundary

CodeQL's actions/code-injection query models untrusted sources as github.event.* values and did not report this pattern, so CQ-1 is not credited with T-3 coverage. CQ-8 closes that gap for direct input interpolation. Neither control performs general taint analysis, so an indirect derivation through matrix, needs, steps, or env remains undetected by design.

Latent surface (sub-case)

footer-exclude-paths, dependency-types, and the numeric fuzz-runs are declared and interpolated but are supplied by no current caller. They were unreachable by wiring rather than by control, and a future caller passing a tainted value would have activated them. All three are now covered by CQ-6 and CQ-8: the gate exempts only an input declared type: boolean, so a number declaration is reported like any other non-boolean type rather than trusted.

R-1: Untraceable Configuration Changes

FieldValue
CategoryRepudiation
AssetRepository configuration
ThreatAdmin makes security-impacting changes without audit trail
LikelihoodLow (GitHub provides audit logs)
ImpactMedium (accountability gap)
MitigationsGitHub audit log, branch protection audit events
Residual RiskLow
StatusMitigated

I-1: Secret Exposure in Logs or Artifacts

FieldValue
CategoryInformation Disclosure
AssetRepository secrets, tokens
ThreatSecrets accidentally logged or included in build artifacts
LikelihoodLow (minimal secret usage)
ImpactHigh (credential compromise)
MitigationsGitHub secret masking, GitHub secret scanning, minimal secret usage
Residual RiskLow
StatusMitigated

I-2: Sensitive Information in Prompt Artifacts

FieldValue
CategoryInformation Disclosure
AssetPrompt files, documentation
ThreatInternal URLs, API keys, or proprietary patterns exposed in prompts
LikelihoodLow (review process catches obvious cases)
ImpactMedium (information leakage)
MitigationsPR review, GitHub secret scanning, documentation guidelines
Residual RiskLow
StatusMitigated

D-1: CI/CD Resource Exhaustion

FieldValue
CategoryDenial of Service
AssetGitHub Actions minutes, runner availability
ThreatMalicious PR triggers expensive workflows repeatedly
LikelihoodLow (requires PR creation privileges)
ImpactLow (billing impact, temporary delays)
MitigationsWorkflow approval for first-time contributors, concurrency limits
Residual RiskLow
StatusMitigated

D-2: Dependency Confusion Blocking Builds

FieldValue
CategoryDenial of Service
AssetBuild pipeline
ThreatAttacker publishes conflicting package preventing clean builds
LikelihoodLow
ImpactMedium (build failures)
MitigationsPackage-lock.json, scoped packages
Residual RiskLow
StatusMitigated

E-1: Workflow Token Abuse

FieldValue
CategoryElevation of Privilege
AssetGitHub Actions tokens
ThreatCompromised workflow step uses GITHUB_TOKEN beyond intended scope
LikelihoodLow (minimal permissions declared)
ImpactMedium (depends on token permissions)
MitigationsMinimal permissions pattern, persist-credentials: false, inline comments on elevated permissions
Residual RiskLow
StatusMitigated with Documentation
Accepted Risk: Token-Permissions Alerts

The Mitigated with Documentation status above carries this documented acceptance. The threat-model spec uses the same term because the Microsoft Threat Modeling Tool recognizes a fixed state vocabulary that has no "accepted risk" value; see the state-mapping table in the threat-models README.

OpenSSF Scorecard Token-Permissions flags security-events: write as overly broad across workflow files. This permission is required for github/codeql-action/upload-sarif and github/codeql-action/analyze to upload SARIF results to the repository Security tab. The security-events scope grants access only to code scanning alert data and cannot modify repository content, settings, or secrets.

Scorecard's own scorecard.yml requires the same permission to publish results, creating a circular dependency in the token-permissions check.

Affected workflow jobs:

WorkflowJob
release-stable.ymldependency-pinning-scan
release-stable.ymlgitleaks-scan
pr-validation.ymldependency-pinning-check
pr-validation.ymlworkflow-permissions-check
pr-validation.ymlgitleaks-scan
pr-validation.ymlcodeql
security-scan.ymlcodeql
weekly-security-maintenance.ymlvalidate-pinning
weekly-security-maintenance.ymlcodeql-analysis

Defense-in-depth controls:

  • Workflows declare a top-level permissions: block, and every job under a populated block declares its own permissions rather than inheriting implicitly; Test-WorkflowPermissions.ps1 enforces both
  • persist-credentials: false set on all checkout steps
  • Inline YAML comments document each security-events: write declaration
  • SARIF upload is the only write operation performed under this permission

E-2: Branch Protection Bypass

FieldValue
CategoryElevation of Privilege
AssetProtected branches
ThreatAdmin bypasses branch protection to merge unauthorized changes
LikelihoodLow (requires admin access and intentional bypass)
ImpactHigh (security controls circumvented)
MitigationsBranch protection rules, audit logging, "Do not allow bypassing"
Residual RiskLow
StatusMitigated

Dev Container Threats

These threats address risks in the development container configuration used for Codespaces and local container development.

DC-1: Feature Tag Substitution Attack

FieldValue
CategorySpoofing
AssetDev container configuration
ThreatMalicious update to a feature version tag introduces compromised tooling
LikelihoodLow (first-party Microsoft features only)
ImpactMedium (development environment compromise)
MitigationsFirst-party features only, PR review of devcontainer.json changes
Residual RiskLow (Microsoft-maintained features with release controls)
StatusMitigated

DC-2: Lifecycle Script Tampering

FieldValue
CategoryTampering
AssetContainer initialization scripts
ThreatAttacker modifies on-create.sh or post-create.sh to inject code
LikelihoodLow (requires PR approval, CODEOWNERS protection)
ImpactHigh (arbitrary code execution in dev environment)
MitigationsCODEOWNERS, PR review, branch protection
Residual RiskLow
StatusMitigated

DC-3: External Binary Download Compromise

FieldValue
CategorySpoofing
AssetExternal tools (gitleaks, shellcheck)
ThreatCompromised download source serves malicious binary
LikelihoodVery Low (SHA256 verification enforced)
ImpactHigh (malicious tooling in dev environment)
MitigationsSHA256 checksum verification in on-create.sh
Residual RiskVery Low (cryptographic verification prevents substitution)
StatusMitigated

AI-Specific Threats

These threats address risks specific to AI/ML systems as documented by OWASP LLM Top 10 and MITRE ATLAS.

AI-1: Prompt Injection via Artifact Content

FieldValue
CategoryLLM01: Prompt Injection (OWASP)
AssetCopilot behavior, downstream code generation
ThreatMalicious instructions embedded in prompt artifacts manipulate Copilot
LikelihoodMedium
ImpactMedium (affects code generation quality and safety)
MitigationsPR review, CODEOWNERS, clear artifact structure guidelines
Residual RiskMedium (inherent to prompt-based systems)
StatusPartially Mitigated

AI-2: Insecure Output Handling

FieldValue
CategoryLLM02: Insecure Output Handling (OWASP)
AssetGenerated code
ThreatCopilot generates insecure code patterns based on prompt guidance
LikelihoodMedium
ImpactVariable (depends on consumer's review practices)
MitigationsSecurity-focused prompts, consumer code review responsibility
Residual RiskMedium (HVE Core provides guidance, not enforcement)
StatusAccepted with Documentation

AI-3: Training Data Poisoning (Indirect)

FieldValue
CategoryLLM03: Training Data Poisoning (OWASP)
AssetCopilot model behavior
ThreatMalicious patterns in HVE Core influence Copilot training
LikelihoodVery Low (Copilot training controlled by GitHub)
ImpactLow (HVE Core is small input to large training corpus)
MitigationsOut of scope; GitHub controls training pipeline
Residual RiskVery Low
StatusAccepted (Outside Control)

AI-4: Model Denial of Service

FieldValue
CategoryLLM04: Model Denial of Service (OWASP)
AssetCopilot availability
ThreatCrafted prompts cause excessive resource consumption in Copilot
LikelihoodVery Low
ImpactLow (Copilot has rate limiting)
MitigationsCopilot's built-in rate limiting and resource management
Residual RiskVery Low
StatusAccepted (Outside Control)

AI-5: Supply Chain Vulnerabilities (LLM-Specific)

FieldValue
CategoryLLM05: Supply-Chain Vulnerabilities (OWASP)
AssetMCP server integrations
ThreatCompromised MCP server provides malicious context to Copilot
LikelihoodLow (first-party servers) to Medium (third-party)
ImpactMedium (affects code generation context)
MitigationsMCP server trust analysis, documentation of trust levels
Residual RiskLow to Medium depending on server
StatusMitigated with Documentation

See Mural Skill Runtime Hardening for Mural-skill-specific OAuth credential and token-cache leakage controls.

AI-6: Sensitive Information Disclosure

FieldValue
CategoryLLM06: Sensitive Information Disclosure (OWASP)
AssetUser context, code patterns
ThreatPrompt artifacts cause Copilot to expose sensitive patterns
LikelihoodLow
ImpactMedium
MitigationsNone enforced by this repository. Prompt authoring guidance discourages embedding sensitive data, and the consumer organization owns the decision about what enters a prompt. This is a risk transfer supported by documentation, not a control
Residual RiskMedium (no enforced control; the outcome depends on consumer practice)
StatusMitigated with Documentation

AI-7: Insecure Plugin Design

FieldValue
CategoryLLM07: Insecure Plugin Design (OWASP)
AssetMCP server integrations, VS Code extension
ThreatExtension or MCP server allows unauthorized operations
LikelihoodLow (extension has no sensitive operations)
ImpactLow to Medium
MitigationsNone enforced. The extension ships minimal functionality by design and MCP server trust is documented in the MCP Server Trust Analysis, but nothing verifies or enforces that minimality
Residual RiskLow (bounded by the extension's actual capability rather than by a control)
StatusMitigated with Documentation

AI-8: Excessive Agency

FieldValue
CategoryLLM08: Excessive Agency (OWASP)
AssetAutonomous Copilot operations
ThreatPrompts grant Copilot excessive autonomous capabilities
LikelihoodLow (prompts are guidance, not permissions)
ImpactVariable
MitigationsCopilot's built-in guardrails and tool confirmation dialogs. This control is owned and operated by GitHub and Microsoft, not by this repository. HVE Core neither implements nor enforces it, and cannot verify its continued presence
Residual RiskLow (the control is effective but external; this repository has no means to assure it)
StatusMitigated (Copilot Controls)

AI-9: Overreliance

FieldValue
CategoryLLM09: Overreliance (OWASP)
AssetCode quality, developer decision-making
ThreatDevelopers accept Copilot output without verification
LikelihoodMedium
ImpactVariable (depends on context)
MitigationsDocumentation emphasizing review, security-focused prompts
Residual RiskMedium (behavioral, not technical)
StatusAccepted with Documentation

AI-10: Model Theft (N/A)

FieldValue
CategoryLLM10: Model Theft (OWASP)
AssetN/A
ThreatHVE Core does not host or distribute models
LikelihoodN/A
ImpactN/A
MitigationsN/A
Residual RiskN/A
StatusNot Applicable

AI-11: AML.T0043 Craft Adversarial Data (MITRE ATLAS)

FieldValue
CategoryMITRE ATLAS AML.T0043
AssetPrompt artifacts
ThreatAdversary crafts prompt content to cause model misbehavior
LikelihoodMedium
ImpactMedium
MitigationsPR review process, CODEOWNERS, artifact structure validation
Residual RiskMedium
StatusPartially Mitigated

AI-12: AML.T0048 Evade ML Model (MITRE ATLAS)

FieldValue
CategoryMITRE ATLAS AML.T0048
AssetSecurity recommendations in prompts
ThreatPrompts designed to cause Copilot to bypass security guidance
LikelihoodLow
ImpactMedium
MitigationsPartially enforced. Branch-protection-required pull-request review (AC-3) and CODEOWNERS ownership of protected paths (AC-2) place a human between an authored prompt and its merge. Security-first prompt design principles are authoring guidance with no automated enforcement
Residual RiskMedium (review catches what a reviewer notices; no automated detection of security-guidance evasion exists)
StatusPartially Mitigated

For runtime supply-chain posture of locally executed MCP servers, see the MCP Server Trust Analysis runtime trust table.

Responsible AI Threats

These threats address ethical and responsible AI considerations aligned with Microsoft's Responsible AI principles.

Representation in the machine-readable spec. docs/planning/threat-models/hve-core-comprehensive.yaml encodes this model for the Microsoft Threat Modeling Tool, and that schema requires every threat to name a component (target_ref) and a data flow (interaction_ref).

Five entries in this section meet that requirement and are encoded: RAI-1, RAI-3, RAI-3a, RAI-4, and RAI-13.

Nine do not and are deliberately absent: RAI-2, RAI-5, RAI-6, RAI-7, RAI-8, RAI-9, RAI-10, RAI-11, and RAI-12. Their assets are organizational or societal conditions such as developer autonomy, user agency, organizational trust, developer skill development, and compute resources; none names a trust boundary or an adversary acting on a modeled connector. Assigning them a component and a flow would fabricate traceability rather than record it.

AI-10 is excluded for a different reason: it is an explicit not-applicable placeholder recording that HVE Core neither hosts nor distributes models, and encoding a documented non-applicability as a threat would misrepresent it.

The exclusion is by kind, not by oversight. This section remains the authoritative record for all fourteen Responsible AI entries.

RAI-1: Fairness - Biased Code Generation Patterns

FieldValue
CategoryFairness (Responsible AI)
AssetGenerated code quality across contexts
ThreatPrompts inadvertently favor certain coding styles or exclude accessibility
LikelihoodMedium
ImpactMedium (affects inclusivity of generated code)
MitigationsInclusive language guidelines, accessibility-aware prompts
Residual RiskMedium
StatusPartially Mitigated

RAI-2: Reliability - Inconsistent Prompt Behavior

FieldValue
CategoryReliability & Safety (Responsible AI)
AssetPrompt consistency
ThreatSame prompt produces significantly different outputs
LikelihoodMedium (inherent to LLMs)
ImpactLow to Medium
MitigationsStructured prompts, explicit instructions, testing guidance
Residual RiskMedium (LLM behavior inherently variable)
StatusAccepted with Documentation

RAI-3: Privacy - Context Leakage via Prompts

FieldValue
CategoryPrivacy & Security (Responsible AI)
AssetDeveloper context, code patterns
ThreatPrompts cause Copilot to surface or infer private information
LikelihoodLow
ImpactMedium
MitigationsNone enforced by this repository. Privacy-conscious prompt design and consumer guidelines are documentation; no control prevents a prompt from eliciting private context
Residual RiskMedium (no enforced control; depends on prompt authoring practice)
StatusMitigated with Documentation

RAI-3a: Privacy - M365 Transcript Data Materialization

FieldValue
CategoryPrivacy & Security (Responsible AI)
AssetMeeting transcripts, customer confidential data, PII
ThreatThe meeting-analyst agent retrieves M365 transcripts containing sensitive data and writes them to local files in .copilot-tracking/. Data may be exposed through accidental commits (git add -f), gitignore misconfiguration, shared Codespaces, CI/CD logs, or unencrypted disk access.
LikelihoodMedium (users may not recognize transcript sensitivity; gitignore is the only barrier)
ImpactHigh (customer confidential data, PII, trade secrets)
MitigationsGitignore for .copilot-tracking/, agent-level data sensitivity notice and pre-flight classification prompt, anonymization guidance in agent instructions, data retention cleanup at handoff, documentation in threat model and agent catalog
Residual RiskMedium (gitignore is not a security control; user awareness is behavioral)
StatusPartially Mitigated with Documentation

RAI-4: Inclusiveness - Exclusionary Language in Artifacts

FieldValue
CategoryInclusiveness (Responsible AI)
AssetPrompt artifacts, documentation
ThreatLanguage in prompts excludes or marginalizes user groups
LikelihoodLow (writing style guidelines address this)
ImpactMedium (affects adoption and trust)
MitigationsInclusive writing guidelines, spell check, PR review
Residual RiskLow
StatusMitigated

RAI-5: Transparency - Undocumented Prompt Behavior

FieldValue
CategoryTransparency (Responsible AI)
AssetUser understanding of system behavior
ThreatPrompts cause unexpected Copilot behavior not explained to users
LikelihoodMedium
ImpactLow to Medium
MitigationsClear documentation, explicit prompt descriptions in frontmatter
Residual RiskLow
StatusMitigated

RAI-6: Accountability - Unclear Responsibility for Generated Code

FieldValue
CategoryAccountability (Responsible AI)
AssetLiability and responsibility clarity
ThreatAmbiguity about who is responsible for Copilot-generated code issues
LikelihoodMedium (common confusion)
ImpactMedium
MitigationsDocumentation clarifying HVE Core provides guidance only
Residual RiskLow
StatusMitigated with Documentation

RAI-7: Human Oversight - Automated Changes Without Review

FieldValue
CategoryHuman Oversight (Responsible AI)
AssetCode quality, security
ThreatPrompts encourage accepting Copilot suggestions without review
LikelihoodLow (prompts emphasize review)
ImpactVariable
MitigationsPrompts include review reminders, security-conscious patterns
Residual RiskLow
StatusMitigated

RAI-8: Value Alignment - Prompts Conflicting with Organizational Values

FieldValue
CategoryValue Alignment (Responsible AI)
AssetOrganizational trust
ThreatPrompt artifacts conflict with consumer organization's values
LikelihoodLow
ImpactMedium (reputational)
MitigationsGeneral-purpose prompts, customization guidance for consumers
Residual RiskLow
StatusMitigated with Documentation

RAI-9: Proportionality - Overly Aggressive Automation

FieldValue
CategoryProportionality (Responsible AI)
AssetDeveloper autonomy
ThreatPrompts push Copilot toward excessive automation reducing human judgment
LikelihoodLow
ImpactMedium
MitigationsHuman-in-the-loop design patterns in prompts
Residual RiskLow
StatusMitigated

RAI-10: Contestability - No Mechanism to Challenge AI Decisions

FieldValue
CategoryContestability (Responsible AI)
AssetUser agency
ThreatUsers cannot override or question Copilot behavior influenced by prompts
LikelihoodLow (Copilot suggestions are optional)
ImpactLow
MitigationsCopilot's non-mandatory nature, edit/reject options built-in
Residual RiskVery Low
StatusMitigated (Copilot Controls)

RAI-11: Societal Impact - Deskilling Developers

FieldValue
CategorySocietal Impact (Responsible AI)
AssetDeveloper skill development
ThreatOver-reliance on AI-assisted coding reduces skill development
LikelihoodMedium (industry-wide concern)
ImpactLow for HVE Core specifically
MitigationsPrompts emphasize learning and understanding, not just output
Residual RiskMedium (societal, not technical)
StatusAccepted with Documentation

RAI-12: Environmental Impact - Compute Resource Awareness

FieldValue
CategoryEnvironmental Impact (Responsible AI)
AssetCompute resources
ThreatInefficient prompts cause unnecessary model computation
LikelihoodLow
ImpactLow (marginal compute impact)
MitigationsEfficient prompt design guidelines
Residual RiskVery Low
StatusAccepted

RAI-13: Misinformation - Prompts Generating Incorrect Information

FieldValue
CategoryMisinformation (Responsible AI)
AssetDocumentation and code accuracy
ThreatPrompts cause Copilot to generate plausible but incorrect content
LikelihoodMedium (LLM hallucination is known issue)
ImpactMedium
MitigationsVerification prompts, citation requirements in prompt guidelines
Residual RiskMedium (inherent LLM limitation)
StatusPartially Mitigated

OAuth Authentication Threats

These threats address risks specific to the OAuth 2.0 Authorization Code + PKCE flow used by the Mural skill and apply to any future skill that authenticates against a third-party authorization server using a loopback redirect URI on the developer workstation.

Authenticated Mural API egress is additionally restricted to the canonical public API base, rejects absolute operation URLs, and uses dedicated no-redirect openers for API, token, and Azure SAS upload requests. This closes the cross-origin bearer-header replay behavior of Python's default redirect handler. HTTP API overrides are limited to explicit loopback development mode.

The catalog uses an extended 11-row format that adds Source (verbatim citation), Trust Boundary Crossed, and Detection to the standard STRIDE row template.

Mural-specific facts are sourced from https://developers.mural.co/public/docs/oauth (fetched 2026-05-10).

The verbatim quotes and validation log are recorded in .copilot-tracking/research/2026-05-10/oauth-stride-threat-model-validation-research.md.

External standards are cited inline.

Mural documentation contradiction: Mural's OAuth doc narrative claims refresh tokens are rotated, but the documented JSON response schema and reference paragraph confirm they are NOT ({ "access_token": ..., "expires_in": ... } only; "You can reuse your refresh_token as many times as you need"). The schema and reference paragraph are authoritative. OA-11 below is built on the verified non-rotation behavior; do not be misled by Mural's narrative.

FieldValue
CategorySpoofing
AssetUser credentials, OAuth grant decision
ThreatAttacker directs the user to a look-alike Mural consent page (typosquatted domain or DNS hijack) and harvests credentials or coerces an OAuth grant for an attacker-controlled client
LikelihoodLow (requires user-side browser deception or DNS attack)
ImpactHigh (account takeover; attacker-issued tokens with full delegated scope)
MitigationsSkill constructs the authorization URL from a hardcoded constant (https://app.mural.co/api/public/v1/authorization/oauth2/); HTTPS enforced; user instructed to verify URL bar before consenting; client_id is non-secret
Residual RiskLow (deception happens outside the skill's trust boundary; relies on user vigilance and OS DNS integrity)
StatusMitigated with Documentation
SourceRFC 6819 §4.1.4 (Threat: End-User Credentials Phished); MITRE ATT&CK T1539 (Steal Web Session Cookie); Mural authorization endpoint verbatim: "Authorization URL: https://app.mural.co/api/public/v1/authorization/oauth2/"
Trust Boundary CrossedBrowser ↔ Mural Authorization Server
DetectionOut of band (Mural account-side anomaly review at https://app.mural.co/account/api); the local skill cannot detect this

OA-2: Authorization Server Mix-Up via Missing iss Parameter

FieldValue
CategorySpoofing
AssetAuthorization-code-to-token exchange integrity
ThreatIf the skill ever supports more than one authorization server, an attacker AS that the user has previously authorized could redirect a code from itself to Mural's token endpoint (or vice versa) and the client cannot distinguish the issuer because Mural does not return RFC 9207 iss
LikelihoodVery Low for current single-AS skill design; Medium if multi-AS support is added
ImpactHigh (cross-AS token confusion; attacker-controlled token usable against legitimate AS)
MitigationsSkill is single-AS by design; per-request state enforcement (skill _run_login L2200, L2237) binds callback to issuing request; PKCE code_verifier (RFC 7636) cryptographically binds the code to this client and authorization request; do not add a second AS without first implementing RFC 9207 issuer validation or equivalent per-AS state-namespace
Residual RiskLow for current design; would become Medium if multi-AS is added before mitigation
StatusMitigated by Design (single-AS skill)
SourceRFC 9207 §1 (OAuth 2.0 Authorization Server Issuer Identification); RFC 9700 §4.4 (AS Mix-Up); Mural callback verified to expose code + state only (no iss): "https://cleverexample.com/oauth/callback?code=:code&state=:state"
Trust Boundary CrossedBrowser ↔ Mural Authorization Server; Skill Process ↔ Mural Token Endpoint
DetectionCross-AS code rejection logged at the wrong AS's token endpoint (invalid_grant or invalid_client); audit AS-side for unexpected token requests

OA-3: Loopback Redirect URI Hijack

FieldValue
CategorySpoofing
AssetAuthorization code in transit from browser to skill loopback handler
ThreatA co-resident process on the developer workstation binds the loopback port before the skill or races the bind, intercepting the authorization code delivered to http://127.0.0.1:<port>/callback
LikelihoodLow on single-user workstations; Medium on shared dev hosts and Codespaces with port forwarding
ImpactHigh (intercepted code can be exchanged for tokens until single-use enforcement triggers; PKCE prevents exchange but only if the attacker lacks the verifier)
MitigationsLoopback handler binds before authorization request is opened (_start_loopback_server L2087); ephemeral port; PKCE binds the code to this client's code_verifier so an interceptor without the verifier cannot exchange the code; redirect URI validated against an allow-list (_validate_redirect_uri L2110, _resolve_redirect_uri L2148)
Residual RiskLow (PKCE is the load-bearing control; the verifier is held only in-process and never logged via _REDACT_KEYS)
StatusMitigated
SourceRFC 8252 §7.3 (Loopback Interface Redirection); RFC 7636 §1 (PKCE motivation: authorization code interception attack); CAPEC-21 (Exploitation of Trusted Identifiers)
Trust Boundary CrossedBrowser ↔ Skill Process (loopback)
DetectionEADDRINUSE on bind; loopback handler logs unexpected callbacks; second invalid_grant ("already used") on token exchange attempt

OA-4: Client Impersonation via Leaked client_secret

FieldValue
CategorySpoofing
AssetMural-issued client_secret for the registered OAuth application
ThreatMural documents only the confidential-client OAuth flow (no public-client / PKCE-only path), so the skill must hold a client_secret. If that secret leaks (env-var dump, log capture, file-permission downgrade, accidental commit, screen share), an attacker can impersonate the registered client and complete token exchanges for any user-issued authorization code
LikelihoodLow (skill enforces 0600 file permissions and redacts secrets from logs)
ImpactCritical (full client impersonation; attacker can mint tokens for any user who completes the OAuth dance against the legitimate AS)
Mitigations_check_credential_file_perms L530 enforces 0600 mode on the credential file; _REDACT_KEYS L140 includes client_secret and is exercised by _redact() L1332 across all log-emission paths; secret never written to stdout; documented rotation runbook in skill SECURITY.md G-EOP-1; lint rule prohibits hardcoded credentials
Residual RiskLow (depends on _REDACT_KEYS test coverage; Q3=a parallel work item adds the missing test_redaction.py to lock the contract)
StatusMitigated
SourceRFC 6749 §2.3.1 (Client Password); RFC 6819 §4.1.1 (Threat: Obtaining Client Secrets); Mural verbatim: "client_secret: The secret key you copied when you created your app in Mural."
Trust Boundary CrossedSkill Process ↔ Token Cache File; Skill Process ↔ Log Sinks
DetectionFile-mode audit (_check_credential_file_perms); gitleaks pre-commit; CodeQL secret-pattern scanning; Mural-side anomaly detection on token-request volume

OA-5: Authorization Request Tampering / CSRF (Missing state)

FieldValue
CategoryTampering
AssetAuthorization-request integrity; binding of callback to legitimate user session
ThreatAttacker tricks the user's browser into issuing a forged callback containing an attacker-issued authorization code, causing the skill to bind the user's local session to an attacker's Mural account (cross-account login CSRF) or to honor an attacker-tampered redirect_uri / scope
LikelihoodLow when skill enforces state; Medium if state enforcement is dropped because Mural marks state optional
ImpactHigh (cross-account binding; data exfiltration to attacker's Mural workspace; or scope upgrade)
MitigationsSkill MUST enforce state regardless of Mural's "optional" classification; _run_login generates and verifies state at L2200 and L2237; redirect_uri is allow-listed via _validate_redirect_uri L2110; scope is constructed from a hardcoded constant; PKCE binds the code to the client
Residual RiskLow (assuming state enforcement remains; regression test recommended; see Phase 5 follow-on work)
StatusMitigated
SourceRFC 6749 §10.12 (Cross-Site Request Forgery); OAuth 2.1 §4.1.1 (state REQUIRED); RFC 9700 §4.7 (CSRF on Redirect URI); Mural verbatim (note marks state as optional, contradicting OAuth 2.1): "state: A value that you randomly generate and store. (This is optional, but recommended.)"
Trust Boundary CrossedBrowser ↔ Skill Process (loopback)
Detectionstate mismatch in _LoopbackHandler callback; logged as security event (state value itself is not logged; only the mismatch fact)

OA-6: Authorization Code Replay

FieldValue
CategoryTampering
AssetOne-time-use guarantee on the authorization code
ThreatAttacker who observes an authorization code (in browser history, referer header, log scrape, or screen capture) attempts to exchange it a second time at the token endpoint
LikelihoodLow (Mural enforces single-use server-side; PKCE additionally requires the verifier)
ImpactHigh if replay succeeds (attacker tokens issued to attacker client)
MitigationsMural enforces single-use codes; PKCE code_verifier binds the exchange to this client; skill exchanges the code immediately on receipt and never retains it; code is in _REDACT_KEYS so it is never logged; authorization-code TTL (V8) is undocumented but bounded by single-use and the prompt-revoke runbook
Residual RiskVery Low
StatusMitigated
SourceRFC 6819 §4.4.1.1 (Threat: Eavesdropping or Leaking Authorization Codes); RFC 7636 §1 (PKCE); Mural verbatim: "If the provided authorization grant (code) or refresh token is invalid, already used, expired, revoked, does not match the redirect_uri used in the authorization request, or was issued to another client, you will receive ... invalid_grant"
Trust Boundary CrossedSkill Process ↔ Mural Token Endpoint
Detectioninvalid_grant with "already used" semantics on second exchange; monitor token-endpoint error rate

OA-7: OAuth Audit Trail Gaps (Repudiation)

FieldValue
CategoryRepudiation
AssetOAuth event audit log (login, refresh, revoke, scope grant)
ThreatA user repudiates an OAuth grant or token-issued action because the skill emits no client-side audit record, and the Mural-side audit trail is the only source of truth
LikelihoodMedium (the skill writes operational logs but does not emit a structured audit event for OAuth lifecycle transitions)
ImpactMedium (forensic investigation must rely entirely on Mural-side logs; correlation with local client activity is impossible)
MitigationsSkill emits structured logger events for login_completed, token_refreshed, token_revoked; Mural-side audit log retrieved via account-side review at https://app.mural.co/account/api; correlation via per-request state value (logged as opaque ID, not value)
Residual RiskMedium (client-side audit log is operator-managed and not centralized; recommend SIEM forwarding for high-assurance deployments; see Phase 5 follow-on)
StatusPartially Mitigated
SourceRFC 6819 §5.1.4 (Audit and Trail Threats); NIST SP 800-92 (Guide to Computer Security Log Management); OWASP ASVS V8.3 (Logging and Monitoring)
Trust Boundary CrossedSkill Process ↔ Log Sinks; Skill Process ↔ Mural API
DetectionOut-of-band review of Mural API audit log; gap analysis between client-side log timestamps and Mural-side events

OA-8: Token / Secret Leakage via Application Logs

FieldValue
CategoryInformation Disclosure
Assetaccess_token, refresh_token, client_secret, code, code_verifier, future id_token / assertion / client_assertion / device_code / password
ThreatA high-severity log line emits a request body, response body, header dictionary, exception traceback, or URL containing one of the sensitive fields above; the value lands in operator log files, CI logs, or remote log aggregators
LikelihoodMedium (Python developers commonly LOGGER.error("Request failed: %s", response.text) without thinking about token contents)
ImpactCritical (token reuse against Mural API for the lifetime of the token; refresh tokens are non-rotated per OA-11 and remain valid until manual revocation)
MitigationsCentralized _redact() L1332 pipes all loggable structures through _REDACT_KEYS L140; skill convention forbids direct LOGGER.* calls on response bodies / request bodies / URLs; _REDACT_KEYS test (test_redaction.py) locks the key list; instructions file mural-log-hygiene.instructions.md is mandatory reading for any skill change
Residual RiskMedium pending _REDACT_KEYS expansion (Q3=a) and audit of remaining direct LOGGER call sites (mural.py L1509, L1746, L4128, L4143, L5064, L5071, L9271; print(authorize_url) L2228; lowercase loggers L95, L103, L110)
StatusPartially Mitigated (active remediation tracked under Phase 5 follow-on work)
SourceRFC 6819 §5.1.6 (Threat: Information Leakage); RFC 9700 §2.6 (Token Storage and Handling); OWASP ASVS V7.1 (Log Content Requirements); MITRE ATT&CK T1552.001 (Credentials in Files)
Trust Boundary CrossedSkill Process ↔ Log Sinks
DetectionPre-merge gitleaks scan; static-analysis rule for LOGGER\.(debug|info|warning|error|exception)\(.*\\b(response|request|url|body|headers|token|secret|code)\\b patterns; SIEM alert on Mural-token regex in log streams

OA-9: Token Leakage via Browser Referer / History

FieldValue
CategoryInformation Disclosure
AssetAuthorization code; tokens (if ever placed in URL fragment)
ThreatAuthorization code in the redirect URL leaks via Referer header on subsequent navigation, browser history, screen-share, browser-sync, or third-party browser extension exfiltration
LikelihoodMedium (codes appear in the loopback URL by design)
ImpactLow for authorization code (single-use, PKCE-protected, immediately exchanged); Critical if access tokens were ever placed in URL
MitigationsSkill never uses implicit grant or fragment-encoded tokens (Authorization Code only); loopback handler closes the browser tab via auto-redirect to a static "you may close this window" page after callback receipt, breaking the Referer chain; PKCE neutralizes leaked code value
Residual RiskLow
StatusMitigated
SourceRFC 6819 §4.4.2.5 (Threat: Authorization Code Leakage through Counterfeit Web Site); RFC 9700 §2.1.2 (avoid implicit grant); OWASP ASVS V51.4
Trust Boundary CrossedBrowser ↔ Skill Process (loopback)
DetectionOut of band (browser-history forensics); not directly detectable by the skill

OA-10: Token Cache File Disclosure

FieldValue
CategoryInformation Disclosure
AssetPersisted access_token, refresh_token, client_secret in the on-disk credential cache
ThreatAnother local user, container co-tenant, backup process, dotfile-syncer, or accidental git add reads the credential cache file from the user's home directory
LikelihoodLow on properly configured single-user workstations; Medium in shared dev hosts, Codespaces, and dotfile repositories
ImpactCritical (refresh token grants tokens until manual revocation; non-rotated per OA-11)
Mitigations_check_credential_file_perms L530 enforces 0600 mode and refuses to load on permission widening; cache lock via _acquire_cache_lock L1121 prevents partial writes; cache path documented in skill SECURITY.md; .gitignore covers default cache locations; documented backup-exclusion guidance
Residual RiskLow (file-system-level controls; OS account compromise defeats this mitigation)
StatusMitigated
SourceRFC 9700 §2.6 (Token Storage and Handling); OWASP ASVS V8.2 (Client-Side Data Protection); MITRE ATT&CK T1555.003 (Credentials from Web Browsers: analog for cached tokens); CAPEC-509 (Kerberoasting: analog for cached credential theft)
Trust Boundary CrossedSkill Process ↔ Token Cache File
DetectionPermission-mode self-check on every read (_check_credential_file_perms); audit-log file access via OS auditd / fs_usage if enabled

OA-11: Refresh Token Theft (Long-Lived, Non-Rotated)

FieldValue
CategoryInformation Disclosure
Assetrefresh_token issued by Mural
ThreatAn attacker who exfiltrates the refresh_token (via OA-8 log leak, OA-10 file disclosure, OA-4 client_secret combined with stolen code, or out-of-band shoulder-surf) can obtain access tokens indefinitely until the user manually revokes the grant. Mural does NOT rotate refresh tokens despite their narrative documentation suggesting otherwise; verified via the response schema and the explicit "reuse" statement
LikelihoodLow (depends on a prior exfiltration vector landing successfully)
ImpactCritical (long-lived persistence; full delegated scope until manual revocation)
MitigationsRefresh token covered by _REDACT_KEYS (OA-8 control); persisted only with 0600 mode (OA-10 control); skill SECURITY.md G-EOP-1 documents the Mural-account revocation runbook (https://app.mural.co/account/api); refresh code path _apply_refresh L1597 does not log the token value; consumers warned that refresh tokens are non-rotated and that revocation is the only invalidation path
Residual RiskMedium (residual depends on user adherence to revocation runbook on suspected compromise; non-rotation is an upstream design decision the skill cannot change)
StatusPartially Mitigated (Mural-side limitation documented; client-side controls maximized)
SourceRFC 9700 §2.2.2 (Refresh Token Protection); RFC 6819 §5.2.2.3 (Refresh Token Rotation); Mural verbatim refresh-response schema: { "access_token": <TOKEN>, "expires_in": <EXPIRATION (in seconds)> } (no refresh_token field); Mural verbatim reference paragraph: "You can reuse your refresh_token as many times as you need to get a new access_token."
Trust Boundary CrossedSkill Process ↔ Token Cache File; Skill Process ↔ Mural Token Endpoint
DetectionMural-side anomaly detection on token-endpoint request frequency or geographic distribution; out-of-band review at https://app.mural.co/account/api

OA-12: PKCE Verifier Leakage or Weak Entropy

FieldValue
CategoryInformation Disclosure
AssetPKCE code_verifier (must remain secret to bind the code exchange)
ThreatVerifier leaks via log emission, weak entropy (predictable RNG), or insufficient length (fewer than 43 chars), allowing an attacker who also captured the code (OA-3 / OA-9) to exchange it
LikelihoodLow (skill uses secrets.token_urlsafe)
ImpactHigh if combined with a code interception
Mitigations_generate_pkce_pair L1307 uses secrets.token_urlsafe(64) yielding 86 URL-safe characters (well above the RFC 7636 minimum of 43); _verify_pkce L1314 enforces S256 method (the only modern method, since Mural does not document PKCE method parameters the skill assumes S256 per RFC 7636 §4.2); verifier never logged (not in any log call site) and never persisted (in-process only)
Residual RiskVery Low
StatusMitigated
SourceRFC 7636 §4.1 (Code Verifier minimum entropy 256 bits, length 43–128); RFC 7636 §7.1 (Entropy of code_verifier); RFC 9700 §2.1.1 (PKCE for all OAuth clients); Mural verbatim PKCE acknowledgment: "we support PKCE (Proof Key for Code Exchange)"; note PKCE request/response parameters are NOT documented in Mural's parameter tables, so the skill implements per RFC 7636
Trust Boundary CrossedIn-process (verifier never crosses boundary except via TLS to token endpoint)
DetectionToken-exchange invalid_grant indicates verifier mismatch; entropy regression detected by unit test on _generate_pkce_pair

OA-13: Authorization Endpoint Denial of Service

FieldValue
CategoryDenial of Service
AssetMural authorization endpoint availability for this client / user
ThreatBuggy automation or attacker triggers repeated authorization requests (loopback handler crashes mid-flow, retried in a tight loop, or login storm), consuming Mural-side rate-limit budget and locking the user out
LikelihoodLow
ImpactMedium (skill unavailable until rate-limit window resets; user may need account-side intervention)
MitigationsSingle in-flight _run_login enforced by cache lock (_acquire_cache_lock L1121); exponential backoff on retryable errors; user-initiated only (no automatic re-login on every API call); documented login cadence guidance
Residual RiskLow
StatusMitigated
SourceRFC 6819 §5.1.5.2 (Threat: Denial of Service Attacks); OWASP ASVS V11 (Business Logic Verification)
Trust Boundary CrossedSkill Process ↔ Mural Authorization Server
DetectionHTTP 429 from Mural; cache-lock contention metric

OA-14: Token Endpoint Refresh Storm

FieldValue
CategoryDenial of Service
AssetMural token endpoint availability; cached token consistency across concurrent skill invocations
ThreatConcurrent skill processes each detect the access token is expired and race to refresh; the resulting refresh storm hammers Mural's token endpoint and may produce inconsistent cached state
LikelihoodLow for single-user usage; Medium when the skill is invoked from multiple terminals or automation contexts simultaneously
ImpactLow to Medium (rate-limit penalty; brief unavailability)
MitigationsCache lock (_acquire_cache_lock L1121) serializes refresh; refresh attempt re-reads the cache after acquiring the lock to avoid duplicate refresh; access-token TTL of 900s (Mural verbatim "OAuth tokens expire after 15 minutes") sets refresh cadence; documented "do not script-loop the skill" guidance
Residual RiskLow
StatusMitigated
SourceRFC 9700 §2.2.2; Mural verbatim: "By default, OAuth tokens expire after 15 minutes"
Trust Boundary CrossedSkill Process ↔ Mural Token Endpoint
DetectionHTTP 429 from token endpoint; cache-lock wait-time metric
FieldValue
CategoryElevation of Privilege
AssetGranted OAuth scope set
ThreatSkill (or a future variant) requests broader scopes than required for the task at hand, or an attacker tampers with the scope parameter mid-flow to escalate; consent-phishing pattern is a recognized MITRE ATT&CK technique
LikelihoodLow (skill scope set is hardcoded and minimal)
ImpactHigh (excessive scope grants enable destructive operations or data exfiltration beyond the user's expected approval)
MitigationsScope is constructed from a hardcoded constant (not user-influenced); destructive operations require an explicit dispatch-time scope re-check (mural-skill-discipline /memories/repo/); least-privilege scope set documented in skill SECURITY.md; tag-level scopes (room:read, room:write) are space-delimited and case-sensitive per Mural's documented format
Residual RiskLow
StatusMitigated
SourceMITRE ATT&CK T1528 (Steal Application Access Token); CAPEC-593 (Session Hijacking); RFC 6819 §5.1.5.1 (Threat: Obtaining Tokens with Wrong Scope); OWASP ASVS V51.2.1 (least-privilege scope)
Trust Boundary CrossedBrowser ↔ Mural Authorization Server
DetectionScope diff between requested and granted (if Mural ever emits granted scope in token response); periodic Mural-side scope audit at https://app.mural.co/account/api

OA-16: Bearer Token Theft Enabling Cross-Resource Replay

FieldValue
CategoryElevation of Privilege
AssetBearer access_token issued by Mural
ThreatA bearer token (no client-binding) stolen via OA-8 / OA-10 / OA-11 can be replayed against any Mural API endpoint by any actor who possesses the token, with no cryptographic proof-of-possession required. RFC 9449 (DPoP) and FAPI 2.0 sender-constrained token profiles would mitigate this but Mural does not currently document support for either
LikelihoodLow (depends on a prior exfiltration vector)
ImpactHigh (full delegated scope until token expires; refresh token compounds the window per OA-11)
MitigationsDefense in depth via OA-4 (client_secret protection), OA-8 (log redaction), OA-10 (file mode), OA-11 (revocation runbook); access-token TTL of 900s caps the post-theft replay window for the access token specifically; track Mural's roadmap for sender-constrained token support and adopt RFC 9449 DPoP if/when offered
Residual RiskMedium (cannot be fully mitigated without upstream Mural support for sender-constrained tokens; this is an architectural limitation of bearer-token OAuth)
StatusPartially Mitigated (architectural limitation documented)
SourceRFC 9449 (OAuth 2.0 Demonstrating Proof of Possession (DPoP)); FAPI 2.0 Security Profile §5.3 (sender-constrained access tokens); RFC 9700 §2.2.1 (Token Replay Prevention); MITRE ATT&CK T1550.001 (Application Access Token); CAPEC-593
Trust Boundary CrossedSkill Process ↔ Mural API
DetectionMural-side anomaly detection on user-agent, IP, or request-pattern divergence

OA-17: Stolen-Token Abuse Window via Missing Rotation + Long Refresh TTL

FieldValue
CategoryElevation of Privilege
AssetCompromise-recovery time (the window between token theft and effective revocation)
ThreatBecause Mural does not rotate refresh tokens (OA-11) and does not document a refresh-token TTL, a stolen refresh token combined with absence of rotation means recovery requires the user to perform manual revocation at the Mural account UI. Until they do, the attacker retains the same authority as the legitimate user. This compounds the impact of any successful exfiltration vector
LikelihoodLow (compound event: requires successful exfiltration AND delayed user response)
ImpactCritical (open-ended persistence)
MitigationsDocumented incident-response runbook in skill SECURITY.md G-EOP-1 (Mural revocation URL: https://app.mural.co/account/api); access-token TTL of 900s caps the access-token-only attack window; client-side defenses against exfiltration (OA-4, OA-8, OA-10) reduce the precondition probability; advise consumers to monitor Mural account-side audit log on a routine cadence; track Mural's roadmap for refresh-token rotation support and adopt as soon as it is offered
Residual RiskMedium (cannot be fully mitigated without upstream Mural support for refresh-token rotation; this is a documented Mural design limitation, not a skill defect)
StatusPartially Mitigated (architectural limitation documented; G-EOP-2 in skill SECURITY.md is now CONFIRMED CORRECT against Mural's published documentation)
SourceRFC 9700 §2.2.2 (Refresh Token Protection; recommends rotation); RFC 6819 §5.2.2.3 (Refresh Token Rotation); OAuth 2.1 §4.3.1; Mural verbatim refresh-response schema: { "access_token": <TOKEN>, "expires_in": <EXPIRATION (in seconds)> } (no refresh_token); Mural verbatim reuse statement: "You can reuse your refresh_token as many times as you need to get a new access_token."; Mural account-side revocation: https://app.mural.co/account/api
Trust Boundary CrossedSkill Process ↔ Mural API; User ↔ Mural Account Console
DetectionOut-of-band Mural account-side audit; alert on token-issuance anomaly

OA-18: Supply-Chain or Dependency Tampering Compromises the Mural Runtime

FieldValue
CategoryTampering
AssetIntegrity of the Mural CLI runtime and its OAuth helper code paths
ThreatA compromised, substituted, or unpinned dependency alters the runtime behavior of the Mural CLI or its OAuth helpers. Because the same process builds the authorization URL, holds the PKCE code_verifier, terminates the loopback callback, and persists tokens, altered code inside that process can defeat every other control in this OAuth catalog without breaking any protocol invariant observable from outside
LikelihoodLow (the skill depends only on the Python standard library for OAuth and transport; keyring is the sole optional third-party surface)
ImpactHigh (in-process compromise reaches tokens, client_secret, and the code exchange simultaneously)
MitigationsStandard-library-only OAuth and transport paths, so the OAuth surface adds no third-party runtime dependency; repository-wide dependency pinning and SHA-pinned Actions per SC-1 through SC-5; Dependabot patching; uv.lock committed alongside pyproject.toml so the resolved graph is reviewable
Residual RiskMedium (dependency-substitution defenses are repository-level and do not attest the operator's local interpreter, site-packages, or PYTHONPATH)
StatusPartially Mitigated
SourceNIST SP 800-53 SA-12 (Supply Chain Protection); CWE-494 (Download of Code Without Integrity Check); skill gap register G-SUP-1
Trust Boundary CrossedExternal Dependencies ↔ Skill Process
DetectionDependency review and npm audit gates on pull requests; lockfile diff at release; no runtime self-attestation inside the skill

Jira Credential Threats

These threats address credential and error-handling risks specific to the Jira skill (.github/skills/project-planning/jira/scripts/jira.py), a single-file standard-library CLI that authenticates to Jira Data Center with a PAT or Jira Cloud with an expiring API token. Scoped Cloud mode binds requests to the fixed Atlassian resource origin and records auth mode plus normalized origin in the explicitly enabled, operationally sensitive audit sink. The catalog uses the same extended 11-row format as the OAuth threats. The authoritative per-skill model is the Jira skill SECURITY.md. Redaction-architecture hardening is implemented through bounded output sinks, LOGGER, typed JiraAPIError, structured-result sanitization, and source-contract tests.

JR-1: PAT Exfiltration via Traceback or Error Message

FieldValue
CategoryInformation Disclosure
AssetJira PAT (Authorization: Bearer)
ThreatA raw exception or diagnostic that embeds the request URL, headers, or upstream error body could surface the bearer token in stderr, an audit record, or a captured log
LikelihoodLow
ImpactHigh (token grants the operator's Jira scope until revoked)
MitigationsToken sent only in the Authorization header over TLS and never logged; remote error text passes through _redact; every process-stream write routes through _emit, _emit_stdout, or _emit_debug_traceback; typed JiraAPIError renders only controlled structured fields
Residual RiskLow
StatusMitigated
SourceCWE-532 (Insertion of Sensitive Information into Log File); OWASP ASVS v4 §7.1.1
Trust Boundary CrossedSkill Process ↔ Operator diagnostics / audit sink
DetectionSource-contract and behavior redaction tests

JR-2: Basic-Auth Credential Decoded from Logs

FieldValue
CategoryInformation Disclosure
AssetJira Cloud Basic credential (base64(email:token))
ThreatThe Basic Authorization value is reversible base64; if it reaches a log or error string it can be trivially decoded to recover the email and API token
LikelihoodLow
ImpactHigh
Mitigations_redact masks the Basic credential in error text; the credential is built from ASCII-validated components and used only as an in-transit header over TLS; never persisted
Residual RiskLow
StatusMitigated
SourceCWE-522 (Insufficiently Protected Credentials); RFC 7617 (Basic auth is base64, not encryption)
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionRedaction contract tests

JR-3: JIRA_BASE_URL Substitution / SSRF

FieldValue
CategorySpoofing / Tampering
AssetRequest destination integrity (where the bearer token is sent)
ThreatA crafted JIRA_BASE_URL (embedded userinfo, alternate host, redirect chain) could retarget authenticated requests to an attacker-controlled origin, leaking the token
LikelihoodLow
ImpactHigh
Mitigations_canonicalize_base_url reduces the value to an origin-only URL and rejects control characters, userinfo, query, fragment, and non-root paths; HTTPS enforced for non-loopback hosts; _NoRedirect opener refuses 30x so the token is never replayed cross-host
Residual RiskLow
StatusMitigated
SourceCWE-918 (Server-Side Request Forgery); OWASP ASVS v4 §12.6
Trust Boundary CrossedSkill Process ↔ Jira Instance (network)
DetectionTransport regression tests (redirect blocking, HTTPS guard)

JR-4: Upstream Error Body Echoed Verbatim

FieldValue
CategoryInformation Disclosure
AssetDiagnostic output integrity
ThreatA hostile or misconfigured Jira response could embed secrets or sensitive content that, if echoed verbatim, leaks to stderr or downstream automation
LikelihoodLow
ImpactMedium
MitigationsError bodies are JSON-parsed first and only redacted for presentation (_extract_error_message_redact); responses are read through a MAX_BODY_BYTES-capped reader with JSON content-type fail-closed
Residual RiskLow
StatusMitigated
SourceCWE-209 (Generation of Error Message Containing Sensitive Information)
Trust Boundary CrossedJira Instance ↔ Skill Process ↔ Operator diagnostics
DetectionError-redaction regression tests

JR-5: JIRA_PAT Environment Leak via os.environ Dump

FieldValue
CategoryInformation Disclosure
AssetJira PAT / API token in the process environment
ThreatA future debug path that dumps os.environ (or a traceback that captured it) could expose JIRA_PAT / JIRA_API_TOKEN
LikelihoodLow
ImpactHigh
MitigationsNo code path prints os.environ; credentials are held on a frozen dataclass; the optional debug traceback is gated by JIRA_DEBUG and redacted before output
Residual RiskLow
StatusMitigated
SourceCWE-526 (Exposure of Sensitive Information Through Environment Variables); CWE-532
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionCode review; redaction contract tests (#1559)

JR-6: JiraClient repr() Leaking auth_header

FieldValue
CategoryInformation Disclosure
AssetAuthorization header value (Bearer / Basic)
ThreatJiraClient is a @dataclass(frozen=True) whose auth_header field holds the raw credential; the auto-generated repr() would expose it if the object were ever printed, logged, or captured by a debugger or traceback
LikelihoodVery Low (no current code path calls repr(client))
ImpactHigh
Mitigationsauth_header is declared with repr=False; the token is used only as an in-transit header and negative tests pin the representation contract
Residual RiskLow
StatusMitigated
SourceCWE-215 (Insertion of Sensitive Information Into Debugging Code); CWE-532
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
Detectiontest_client_repr_omits_authorization_header pins the negative representation contract

JR-7: handle_comment Stdin Payload Echoed in Traceback

FieldValue
CategoryInformation Disclosure
AssetOperator-supplied stdin comment payload
Threathandle_comment reads a comment body from stdin; if that payload (which may contain sensitive text) were embedded in an error message or traceback, it could leak
LikelihoodLow
ImpactLow
Mitigationsstdin is read through _read_stdin(MAX_BODY_BYTES) (size-capped); parse failures raise ScriptError with a static message, not the raw payload; error text is redacted before display
Residual RiskLow
StatusMitigated
SourceCWE-209; CWE-117 (Improper Output Neutralization for Logs)
Trust Boundary CrossedCLI caller ↔ Skill Process
DetectionRedaction contract tests (#1559)

GitLab Credential Threats

These threats address credential and error-handling risks specific to the GitLab skill. The standard-library CLI uses public-client OAuth with PKCE or human-assisted device authorization by default, keeps PAT support in explicit legacy mode, persists rotating refresh tokens in a bound mode-0600 profile store, and resolves the project from a read-only git remote subprocess. The authoritative per-skill model is the GitLab skill SECURITY.md. Structured-result sanitization, diagnostic redaction sinks, typed API errors, separate REST and OAuth egress owners, bounded audit events, and recursive source-contract tests are implemented. The per-skill model covers the OAuth callback and durable POSIX profile-store boundaries, including Windows fail-close behavior.

GL-1: OAuth or Legacy Token Exfiltration via Traceback or Error Message

FieldValue
CategoryInformation Disclosure
AssetOAuth access/refresh tokens and explicit legacy PAT
ThreatA raw exception, die() message, or diagnostic embedding the URL, headers, or upstream body could surface the token
LikelihoodLow
ImpactHigh
MitigationsCredentials are sent only through OAuth form exchanges, Authorization: Bearer, or explicit PRIVATE-TOKEN over TLS; all process-stream output routes through redacting sinks; typed GitLabAPIError renders controlled fields only
Residual RiskLow
StatusMitigated
SourceCWE-532; OWASP ASVS v4 §7.1.1
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionRedaction and source-contract tests

GL-2: Authentication Context Accidental Dump

FieldValue
CategoryInformation Disclosure
AssetLegacy PAT and OAuth profile identity held during one command
ThreatAn accidental object representation or debugger frame could expose live authentication state
LikelihoodVery Low
ImpactHigh
MitigationsAuthentication uses a frozen AuthContext; its PAT field has repr=False; OAuth tokens remain in the validated profile object and are excluded from status and audit output
Residual RiskLow
StatusMitigated
SourceCWE-526; CWE-215
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionNegative representation and source-contract tests

GL-3: CI Job Log Bypassing Central Transport or Redaction

FieldValue
CategoryInformation Disclosure
AssetCI job-trace egress and PRIVATE-TOKEN
ThreatA credentialed transport path could bypass its designated redirect refusal, auditing, size caps, or redaction owner
LikelihoodLow
ImpactMedium
MitigationsREST requests, including cmd_job_log, use gitlab._request_bytes; OAuth forms use _gitlab_oauth.post_form. A recursive production-module contract permits direct credentialed invocation only in those owners. REST and OAuth behavior tests pin write-ahead audit coverage; job-trace output passes through _redact and is truncated at MAX_LOG_BYTES.
Residual RiskLow
StatusMitigated
SourceCWE-532; CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor)
Trust Boundary CrossedGitLab Instance ↔ Skill Process ↔ Operator diagnostics
DetectionTwo-owner source-contract, REST/OAuth audit behavior, and job-log output tests

GL-4: die() Helper Printing Raw Upstream Body

FieldValue
CategoryInformation Disclosure
AssetDiagnostic output integrity
ThreatThe die() helper prints an error string and exits; if callers pass a raw upstream body, secrets or sensitive content could leak
LikelihoodLow
ImpactMedium
MitigationsAPI failures use typed GitLabAPIError; local configuration failures use die(), which routes through _emit; all upstream body summaries pass through _redact and size caps
Residual RiskLow
StatusMitigated
SourceCWE-209
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionRedaction and typed-error contract tests

GL-5: GITLAB_URL Substitution / SSRF

FieldValue
CategorySpoofing / Tampering
AssetRequest destination integrity
ThreatA crafted GITLAB_URL could retarget authenticated requests to an attacker origin and leak the token
LikelihoodLow
ImpactHigh
Mitigations_normalize_base_url reduces to origin-only and rejects userinfo, query, fragment, non-root paths, and control characters; HTTPS enforced off-loopback; _NoRedirect refuses 30x
Residual RiskLow
StatusMitigated
SourceCWE-918; OWASP ASVS v4 §12.6
Trust Boundary CrossedSkill Process ↔ GitLab Instance
DetectionTransport regression tests

GL-6: Upstream Error Body or CI Trace Echoed Verbatim

FieldValue
CategoryInformation Disclosure
AssetDiagnostic output integrity
ThreatA hostile or misconfigured GitLab response or CI trace could embed secrets that leak if echoed verbatim
LikelihoodMedium (CI traces routinely contain secret-shaped content)
ImpactMedium
MitigationsError bodies parsed-then-redacted; job traces emitted through _redact with truncation; JSON content-type fail-closed; MAX_BODY_BYTES cap
Residual RiskLow
StatusMitigated
SourceCWE-209; CWE-200
Trust Boundary CrossedGitLab Instance ↔ Skill Process ↔ Operator diagnostics
DetectionRedaction regression tests

GL-7: GITLAB_TOKEN Environment Leak via os.environ Dump

FieldValue
CategoryInformation Disclosure
AssetGITLAB_TOKEN in the process environment
ThreatA future debug path dumping os.environ could expose the token
LikelihoodLow
ImpactHigh
MitigationsNo code path prints os.environ; explicit legacy PAT is held on immutable AuthContext; GITLAB_DEBUG enables only a redacted traceback
Residual RiskLow
StatusMitigated
SourceCWE-526; CWE-532
Trust Boundary CrossedSkill Process ↔ Operator diagnostics
DetectionSource-contract and redacted-debug tests

TTS Voice-Over Threats

These threats address credential and content-egress risks specific to the tts-voiceover skill (.github/skills/experimental/tts-voiceover/scripts/), a Python CLI that escapes speaker-notes text into SSML, synthesizes audio through the Azure Cognitive Services Speech SDK over TLS, and embeds the audio into a PowerPoint deck. It authenticates with a SPEECH_KEY subscription key or an Entra token minted by DefaultAzureCredential. The authoritative per-skill model is the tts-voiceover skill SECURITY.md. Its headline residual is speaker-notes content egress to the Azure region; input-parser defense-in-depth is tracked on #1056 / PR #1695.

TT-1: SPEECH_KEY Exfiltration via Traceback, Error, or Logs

FieldValue
CategoryInformation Disclosure
AssetSPEECH_KEY Azure Speech subscription key
ThreatAn exception or diagnostic embedding the key or SDK request context could surface it in stderr or a log
LikelihoodLow
ImpactHigh (key grants synthesis on the subscription until rotated)
MitigationsKey read from the environment once per invocation and passed only to the Speech SDK SpeechConfig(subscription=...); never persisted and never logged. The dual-credential warning names the variable, not its value. Synthesis failure logs only cancellation.reason and error_details. Verified against .github/skills/experimental/tts-voiceover/scripts/generate_voiceover.py
Residual RiskLow
StatusMitigated
SourceCWE-532; OWASP ASVS v4 §7.1.1
Trust Boundary CrossedSkill Process ↔ Azure Speech; Skill Process ↔ Operator diagnostics
DetectionCode review

TT-2: Entra Token Leakage via Debug Output

FieldValue
CategoryInformation Disclosure
AssetEntra access token (aad#{resource}#{token})
ThreatThe composed aad#{resource_id}#{token} authorization value could leak via a debug print or captured traceback
LikelihoodLow
ImpactHigh (bearer token for cognitiveservices.azure.com until expiry)
MitigationsToken minted per invocation by DefaultAzureCredential, composed into the aad#{resource}#{token} value, and passed only to the SDK; not logged or persisted; short TTL caps the exposure window. The logger.exception on the refresh path fires only when acquisition fails, so no token exists to leak. Verified against .github/skills/experimental/tts-voiceover/scripts/generate_voiceover.py
Residual RiskLow
StatusMitigated
SourceCWE-532; CWE-522
Trust Boundary CrossedSkill Process ↔ Entra / Azure Speech
DetectionCode review

TT-3: Speaker-Notes Content Egress Without Data-Classification Gate

FieldValue
CategoryInformation Disclosure
AssetSpeaker-notes content (content.yaml)
ThreatAll narration text leaves the trust boundary to the configured Azure Speech region for synthesis; confidential content could egress without a classification or consent gate
LikelihoodMedium (any run sends content off-box)
ImpactMedium (depends on content sensitivity)
MitigationsEgress is over TLS to the operator-configured region only; documented as the primary residual in the skill SECURITY.md; operators control what content is supplied and which region is used. No automated data-classification gate exists (documented gap)
Residual RiskMedium
StatusPartially Mitigated (documented; no automated classification gate)
SourceCWE-200 (Exposure of Sensitive Information to an Unauthorized Actor)
Trust Boundary CrossedOperator Workstation ↔ Azure Speech (region)
DetectionOut-of-band Azure-side monitoring; operator review of inputs

TT-4: SSML Injection via Unescaped Speaker Notes

FieldValue
CategoryTampering
AssetSSML synthesis request integrity
ThreatSpeaker-notes text interpolated into SSML could inject markup that alters synthesis or smuggles control elements
LikelihoodLow
ImpactLow
MitigationsSpeaker notes are XML-escaped / quoteattr-quoted before insertion into SSML
Residual RiskLow
StatusMitigated
SourceCWE-91 (XML Injection); CWE-116 (Improper Encoding or Escaping of Output)
Trust Boundary CrossedInputs ↔ Skill Process ↔ Azure Speech
DetectionUnit tests on SSML escaping

TT-5: Untrusted PPTX / YAML Parsing (XXE / Unsafe Deserialization)

FieldValue
CategoryTampering / Elevation of Privilege
AssetHost process integrity
ThreatMalicious content.yaml or input PPTX could exploit unsafe YAML deserialization or XML external-entity resolution during parsing
LikelihoodLow
ImpactMedium
Mitigationsyaml.safe_load for YAML; python-pptx OOXML parsing with external-entity resolution disabled; the single raw lxml parse targets a hardcoded trusted timing-template constant (not attacker-influenced) and is being hardened as defense-in-depth (#1056 / PR #1695)
Residual RiskLow
StatusPartially Mitigated (safe parsers in place; lxml defense-in-depth pending #1056/#1695)
SourceCWE-611 (Improper Restriction of XML External Entity Reference); CWE-502 (Deserialization of Untrusted Data)
Trust Boundary CrossedInputs ↔ Skill Process
DetectionParser hardening tracked on #1056/#1695

TT-6: DefaultAzureCredential Ambient-Credential Breadth

FieldValue
CategoryElevation of Privilege / Spoofing
AssetAmbient Azure identity used for synthesis
ThreatDefaultAzureCredential walks a broad chain (environment, managed identity, Azure CLI, and more); on a shared host it could resolve to an unintended, more-privileged identity than the operator expects
LikelihoodLow
ImpactMedium
MitigationsToken scoped to cognitiveservices.azure.com/.default; credential resolution is per-invocation and non-persistent; operators can pin the identity via the environment. Chain breadth documented as a residual in the skill SECURITY.md
Residual RiskMedium
StatusPartially Mitigated (documented; chain breadth inherent to DefaultAzureCredential)
SourceCWE-269 (Improper Privilege Management)
Trust Boundary CrossedSkill Process ↔ Entra
DetectionOperator review of the resolved identity

TT-7: Azure Speech Region / Endpoint Substitution

FieldValue
CategorySpoofing / Tampering
AssetSynthesis request destination (where content and credential are sent)
ThreatA tampered region or endpoint configuration could direct content and the credential to an attacker-controlled endpoint
LikelihoodLow
ImpactHigh
MitigationsThe skill accepts a region label rather than a full endpoint URL, uses the Azure SDK transport, and requests Entra tokens for the fixed Cognitive Services audience. The region value is not yet validated in skill code.
Residual RiskMedium pending verification of SDK region canonicalization and explicit region validation
StatusPartially Mitigated; follow-up validation is required
SourceCWE-918; CWE-297 (Improper Validation of Certificate with Host Mismatch, mitigated by SDK TLS)
Trust Boundary CrossedSkill Process ↔ Azure Speech
DetectionNo skill-level destination detection; operator and SDK behavior review required

Document, Scanning, and Generation Skill Threats

These threats cover the remaining executable skill runtimes: PowerPoint rendering, video-to-GIF conversion, customer-card rendering, GitHub code scanning, the VEX gate, accessibility scanning, and security-planning generation. Each is authoritative in its own per-skill SECURITY.md; the rows below record the repository-level view and cite the per-skill model that owns the underlying assessment.

Likelihood, Impact, and Residual Risk are taken from the named per-skill risk-rating table wherever that table rates the same failure mode. Where the per-skill model does not rate the mode, the row says so and states the basis for the assessment instead of inheriting a neighboring default.

PP-1: Author-Supplied Content-Extra Execution Escapes the Denylist Confinement

FieldValue
CategoryTampering
AssetHost capabilities reachable from the deck-rendering process
ThreatA hostile content-extra script attempts to bypass the documented denylist and reach host capabilities during rendering
LikelihoodMedium (per-skill rating for "Sandbox escape via author Python")
ImpactHigh (per-skill rating; execution in the operator context)
MitigationsDocumented denylist confinement around author-supplied content extras; operator authors and reviews the deck source
Residual RiskMedium (per-skill rating; a denylist is an enumeration of the known-bad, not a sandbox)
StatusPartially Mitigated
SourceNIST SP 800-53 SA-11, AC-6; CWE-94; PowerPoint skill SECURITY.md gaps G-EOP-1 and G-TAM-1
Trust Boundary CrossedNone; PowerPoint Skill Runtime and LibreOffice both sit in the Developer Workstation zone. The confinement boundary is process capability, not trust zone
DetectionDeck source review; no runtime denylist-violation telemetry

PP-2: LibreOffice / MuPDF Parser Exploitation on Untrusted Deck or PDF

FieldValue
CategoryElevation of Privilege
AssetMemory safety of the external converter chain used during export
ThreatA hostile PPTX or PDF stresses or exploits a defect in the LibreOffice or MuPDF parser reached during export
LikelihoodLow (per-skill ratings for "Converter parser exploitation" and "MuPDF memory-safety exploitation")
ImpactHigh (per-skill rating; native-code execution in the operator context)
MitigationsPDF parsing bounds; constrained converter arguments; entity resolution disabled for PPTX XML
Residual RiskMedium (per-skill rating; upstream native parsers are outside repository control)
StatusPartially Mitigated
SourceNIST SP 800-53 SI-10, SC-7; CWE-20; PowerPoint skill SECURITY.md gaps G-TAM-1, G-TAM-2, G-SUP-1
Trust Boundary CrossedNone; both endpoints sit in the Developer Workstation zone. The exposure is untrusted input reaching a native parser
DetectionConverter crash or non-zero exit; no parser-level integrity signal

VG-1: Hostile Media Triggers FFmpeg Decoder CVE Exposure

FieldValue
CategoryTampering
AssetMemory safety of the FFmpeg and ffprobe decode path
ThreatA crafted video stream exercises a decoder defect within FFmpeg or ffprobe during transcoding
LikelihoodLow (per-skill rating)
ImpactHigh (per-skill rating; native decoder compromise in the operator context)
MitigationsBounded conversion timeout; argument construction without a shell; operator supplies the media
Residual RiskMedium (per-skill rating; decoder defects are upstream)
StatusPartially Mitigated
SourceNIST SP 800-53 SI-10; CWE-20; Video-to-GIF skill SECURITY.md gap G-SUP-1
Trust Boundary CrossedNone; Video-to-GIF Skill Runtime and FFmpeg both sit in the Developer Workstation zone
DetectionFFmpeg crash or timeout; no decoder integrity signal

VG-2: Unbounded Media Conversion Exhausts CPU and Disk

FieldValue
CategoryDenial of Service
AssetOperator workstation CPU and disk during conversion
ThreatA pathological input or oversized media file consumes resources before conversion completes
LikelihoodLow (per-skill rating for "Unbounded FFmpeg run exhausts resources")
ImpactMedium (per-skill rating; local resource exhaustion, no data exposure)
MitigationsBounded conversion timeout (V-DOS-1); two-pass conversion with explicit palette handling
Residual RiskLow (per-skill rating)
StatusMitigated
SourceNIST SP 800-53 SC-5; CWE-400; Video-to-GIF skill SECURITY.md control V-DOS-1
Trust Boundary CrossedNone; same-zone local invocation
DetectionTimeout expiry surfaced to the operator

CC-1: Confidential Prose Reaches Downstream YAML Without a Classification Gate

FieldValue
CategoryInformation Disclosure
AssetCustomer and product prose carried from Design Thinking artifacts into rendered decks
ThreatConfidential prose emitted into content.yaml is carried into downstream decks with no classification gate between the source artifact and the rendered output
LikelihoodMedium (per-skill rating)
ImpactLow (per-skill rating; the content stays within operator-controlled outputs)
Mitigationsyaml_escape with quoted placeholders prevents structural breakout; the operator selects source artifacts and output destinations
Residual RiskLow (per-skill rating)
StatusPartially Mitigated. The per-skill model frames the absence of a classification gate as "by design" under G-INF-1; the repository view records it as partially mitigated because no control prevents confidential prose from flowing through
SourceNIST SP 800-53 SC-28; CWE-200; Customer-card-render skill SECURITY.md gap G-INF-1
Trust Boundary CrossedNone; both runtimes sit in the Developer Workstation zone. The concern is data classification, not zone transit
DetectionHuman review of generated content before distribution

GS-1: GitHub CLI or API Path Substitution and Host Trust Drift

FieldValue
CategorySpoofing
AssetIntegrity of the gh invocation and the endpoint it reaches
ThreatA tampered PATH or host environment causes the wrapper to invoke an unexpected gh binary or resolve an unexpected endpoint
LikelihoodLow. New assessment: the per-skill risk table does not rate binary substitution. Basis is the same operator-environment precondition the sibling skills rate Low
ImpactHigh. New assessment: gh owns the token, so a substituted binary observes an authenticated session
MitigationsThe token is owned and supplied by gh and never handled by the skill; endpoint paths are constructed rather than accepted from input
Residual RiskLow. New assessment: exploitation requires prior control of the operator environment, which the repository model treats as out of scope for local tooling
StatusPartially Mitigated
SourceNIST SP 800-53 SA-12; CWE-347; Code-scanning skill SECURITY.md gaps G-SUP-1 and G-TLS-1
Trust Boundary CrossedDeveloper Workstation ↔ GitHub Platform
DetectionNone at the skill layer; GitHub-side authentication and audit logging

GS-2: Branch Allow-List Permits Traversal-Like Values in the Ref Query Segment

FieldValue
CategoryTampering
AssetThe requested ref context of a code-scanning query
ThreatA crafted branch argument alters the requested ref context even though the endpoint path itself remains constrained
LikelihoodLow (per-skill rating for "Argument/query injection into gh api")
ImpactMedium (per-skill rating; alert scope confusion rather than credential exposure)
MitigationsAllow-list validation of arguments; arguments passed as argv with no shell
Residual RiskLow (per-skill rating)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-7; CWE-20; Code-scanning skill SECURITY.md gap G-TAM-1
Trust Boundary CrossedDeveloper Workstation ↔ GitHub Platform
DetectionReturned alert set inconsistent with the requested ref; no automated check

VX-1: Crafted Detection-Issue Content Suppresses or Forces Drafting Decisions

FieldValue
CategoryTampering
AssetThe VEX gate decision and the AI-credit budget it governs
ThreatA hostile issue body misdirects the gate into a skip or proceed outcome, either suppressing a needed draft or consuming AI credits
LikelihoodLow (per-skill ratings for both the skip and proceed variants)
ImpactMedium (per-skill rating for the proceed variant, which is the higher of the two)
MitigationsBot-owned detection issue; regex-bounded parsing; workflow credit budgets; manual triage remains regardless of gate outcome
Residual RiskLow (per-skill rating)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-7, SC-5; CWE-20; VEX skill SECURITY.md gaps G-TAM-1 and G-DOS-1
Trust Boundary CrossedCI/CD Pipeline ↔ Developer Workstation
DetectionGate decision reason emitted to stdout and captured in Actions logs

AX-1: Scanner Fetch Reaches Internal or Metadata Endpoints Without an Allow-List

FieldValue
CategoryInformation Disclosure
AssetInternal services and cloud metadata endpoints reachable from the scanning host
ThreatThe headless scanner reaches an operator-supplied target that resolves to an internal service or a cloud metadata endpoint
LikelihoodMedium (per-skill rating for "SSRF to internal / cloud-metadata endpoint")
ImpactHigh (per-skill rating; metadata endpoints can expose instance credentials)
MitigationsOperator-supplied allow-list where configured; the operator chooses the scan target; findings are normalized rather than executed
Residual RiskMedium (per-skill rating; no default network egress restriction)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-7, SC-28; CWE-918; Accessibility skill SECURITY.md gaps G-INF-1 and G-INF-2
Trust Boundary CrossedDeveloper Workstation ↔ External Dependencies
DetectionScan target recorded in run output; no egress-policy enforcement at the skill layer

AX-2: Hostile Target Causes Headless-Browser Resource Exhaustion

FieldValue
CategoryDenial of Service
AssetScanning-host CPU and memory during page render
ThreatA slow or malicious target consumes CPU and memory while the headless browser renders it
LikelihoodLow (per-skill rating for "Hostile target resource exhaustion")
ImpactMedium (per-skill rating; local resource exhaustion)
MitigationsBounded scan timeout; operator-scoped invocation
Residual RiskLow (per-skill rating)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-5; CWE-400; Accessibility skill SECURITY.md
Trust Boundary CrossedNone; Accessibility Skill Scanner and the headless browser both sit in the Developer Workstation zone
DetectionTimeout expiry surfaced to the operator

SP-1: Spec Edits or Generator Drift Change the Curated Surface

FieldValue
CategoryTampering
AssetThe curated multi-skill analysis surface represented by the threat-model spec and its generated outputs
ThreatA modified spec or an altered generator shifts the generated model away from the intended security posture, so a reviewer assesses a model that no longer matches the system
LikelihoodMedium (per-skill ratings for the overlay and evidence tampering modes)
ImpactMedium (per-skill rating; the misrepresentation is reviewable rather than directly exploitable)
MitigationsDeterministic generation for a given spec and generator version; strict overlay schema with complete invalidation fingerprints; pending-approval state that no runtime path promotes; human review required before a generated model is treated as authored
Residual RiskMedium (per-skill rating; correctness of the curated analysis is a review property, not an enforced one)
StatusPartially Mitigated
SourceNIST SP 800-53 SA-11; CWE-20; Security-planning skill SECURITY.md gaps G-TAM-1, G-TAM-2, G-TAM-3, G-INF-1, G-DOS-1
Trust Boundary CrossedDeveloper Workstation ↔ Repository Contents
DetectionDeterministic regeneration diff; committed spec under pull-request review

Copilot Telemetry Skill Threats

The copilot-otel-metrics skill turns on GitHub Copilot Chat's OTLP export and stands up somewhere for the data to land, locally in a containerized Grafana/Prometheus/Tempo/Loki stack or in an operator-deployed Azure Monitor workspace. The otel-lgtm image also runs Pyroscope, which no shipped dashboard or helper queries; it shares the same data volume, so it is part of the asset below even though nothing in the skill sends it profiles. The primary asset is the payload rather than the code. Spans emitted by the extension were directly observed carrying full prompt text, tool-call arguments and results, and system instructions on a configuration where content capture was left at its documented default, so following the skill accumulates a durable corpus of prompt content. The threats below are grouped by the skill's own trust buckets: B1 editor OTLP ingest, B2 telemetry at rest and query surfaces, B3 reference helper scripts, B4 container image supply chain, B5 editor-global configuration mutation, B6 host process control, and B7 cloud control-plane artifact generation.

Likelihood, Impact, and Residual Risk are taken from the skill's own risk-rating tables wherever those tables rate the same failure mode. Rows that the skill does not rate are marked New assessment and state their basis rather than inheriting a neighboring default. Most of these threats do not cross a repository trust zone: the local stack, the helper scripts, the editor, and the generated artifacts all sit inside the Developer Workstation zone, and container isolation is a sub-boundary within it rather than a zone of its own, matching the treatment of the dev container. Those rows say so instead of inventing a crossing.

OT-1: Prompt Content Traverses Plaintext OTLP Ingest

FieldValue
CategoryInformation Disclosure
AssetPrompt text, tool-call arguments and results, and system instructions carried on Copilot Chat spans
ThreatSpans reach the OTLP receiver over plaintext HTTP carrying six directly observed content attributes, so any redirection of otlpEndpoint away from loopback sends prompt content off the machine in clear text
LikelihoodHigh (per-skill rating; content was observed present with the capture setting left at its documented default)
ImpactHigh (per-skill rating; full prompt and tool-call content)
MitigationsEvery published port binds 127.0.0.1; captureContent omitted from the documented settings block; a curl verification command so the reader checks rather than assumes
Residual RiskMedium (per-skill rating; contained by loopback binding only, and the skill cannot change extension span behavior)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-8, SC-28; CWE-319; copilot-otel-metrics skill SECURITY.md gaps G-INF-1 and G-TLS-1
Trust Boundary CrossedNone; GitHub Copilot and the OTLP receiver both sit in the Developer Workstation zone. The crossing appears only when the operator redirects the endpoint off-host, which the skill states explicitly
DetectionOperator-run curl check against the receiver; no automated alert on content-bearing attributes in the local path

OT-2: Unauthenticated OTLP Receiver Accepts Injected Copilot Series

FieldValue
CategorySpoofing
AssetIntegrity of the stored Copilot usage and cost series
ThreatAny local process reaching 127.0.0.1:4318 submits spans and metrics under the copilot-chat service name with attacker-chosen service_version and session_id, indistinguishable from real editor output by inspection alone
LikelihoodLow (per-skill rating; requires an adversary already executing on the host)
ImpactMedium (per-skill rating; forged usage and cost data)
MitigationsLoopback-only port publishing; baseline.py captures pre-enablement store state and reports discriminators that require real editor activity
Residual RiskMedium (per-skill rating; detection after the fact, not prevention)
StatusPartially Mitigated
SourceNIST SP 800-53 IA-3, SI-10; CWE-306; copilot-otel-metrics skill SECURITY.md gap G-SPF-1
Trust Boundary CrossedNone; both endpoints sit in the Developer Workstation zone. The adversary is a same-host process rather than a zone crossing
Detectionbaseline.py diff against the pre-enablement snapshot

OT-3: Local Flooding and Delta-Temporality Loss Degrade the Ingest Path

FieldValue
CategoryDenial of Service
AssetAvailability and completeness of the local ingest path
ThreatUnauthenticated ingest permits volumetric flooding of the local store by a local process, and a dropped delta-temporality metric was observed failing an entire batched write, discarding co-batched cumulative metrics
LikelihoodLow (per-skill ratings for both the flooding and batched-write-loss variants)
ImpactLow (per-skill rating for both variants; a single-machine demonstration stack)
Mitigations--enable-feature=otlp-deltatocumulative replaces dropping with conversion; loopback-only publishing bounds the flooding adversary to local processes
Residual RiskLow (per-skill rating; conversion state is held in memory and resets on container restart, producing a bounded gap)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-5; CWE-400; copilot-otel-metrics skill SECURITY.md gap G-DOS-1
Trust Boundary CrossedNone; both endpoints sit in the Developer Workstation zone
DetectionGap in converted series after a container restart; verify.py reports stored-signal presence

OT-4: Prompt Corpus Readable at Rest in the Unencrypted Local Volume

FieldValue
CategoryInformation Disclosure
AssetThe accumulated prompt and tool-call corpus persisted in the copilot-otel-data volume, which backs all five services the shipped stack runs: Prometheus metrics, Tempo traces, Loki logs, Pyroscope profiles, and Grafana state
ThreatAny local user with Docker access or filesystem access to the volume reads the full stored corpus, and docker compose down deliberately preserves the volume, so an operator who believes the stack is torn down has in fact retained the corpus
LikelihoodMedium (per-skill rating)
ImpactHigh (per-skill rating; durable plaintext prompt content)
MitigationsContainer isolation and host filesystem permissions; teardown documentation states the volume-preserving and volume-removing variants explicitly; the skill states that the store holds prompt content regardless of the capture setting
Residual RiskMedium (per-skill rating; the volume is unencrypted, Tempo retention is unset, and no expiry applies to trace content)
StatusOpen
SourceNIST SP 800-53 SC-28, MP-6; CWE-311; copilot-otel-metrics skill SECURITY.md gaps G-INF-1 and G-INF-2
Trust Boundary CrossedNone; the receiver and the store are co-located in the same container inside the Developer Workstation zone
DetectionNone at the skill layer; volume presence is observable through docker volume ls

OT-5: Unbounded Trace Growth Exhausts Local Storage

FieldValue
CategoryDenial of Service
AssetHost disk capacity backing the copilot-otel-data volume
ThreatNo Tempo retention limit is configured, so trace volume grows without bound and a long-running stack on a small disk exhausts local storage
LikelihoodLow (per-skill rating)
ImpactMedium (per-skill rating; local storage exhaustion)
MitigationsPrometheus bounded by a deliberate 120-day retention setting; teardown documentation covers volume removal to reclaim space
Residual RiskLow (per-skill rating; accepted, the operator removes the volume to reclaim)
StatusOpen
SourceNIST SP 800-53 SC-5, AU-4; CWE-770; copilot-otel-metrics skill SECURITY.md
Trust Boundary CrossedNone; both endpoints sit in the Developer Workstation zone
DetectionHost disk-usage monitoring outside the skill; no in-stack alert

OT-6: Published Default Grafana Credentials Accepted from Any Local Process

FieldValue
CategorySpoofing
AssetThe Grafana instance, its dashboards, and its datasource definitions
ThreatGrafana ships with admin/admin and the skill does not change them, so any local process or any other user on the workstation authenticates as the Grafana administrator
LikelihoodHigh (per-skill rating; the credential is published and unchanged)
ImpactMedium (per-skill rating)
MitigationsGrafana is published on 127.0.0.1:3000 only, so the weak credential is never presented to a network
Residual RiskLow (per-skill rating; loopback-only publishing is the whole of the compensating control)
StatusOpen
SourceNIST SP 800-53 IA-5, AC-3; CWE-1392; copilot-otel-metrics skill SECURITY.md gap G-SPF-1
Trust Boundary CrossedNone; the operator and the Grafana instance both sit in the Developer Workstation zone. The realistic adversary is a same-host process or a second user on a shared workstation, not a network peer
DetectionGrafana retains limited default audit history; actions are attributable to the shared admin account rather than to a person

OT-7: Grafana Administrator Role Reachable Without Additional Authority

FieldValue
CategoryElevation of Privilege
AssetGrafana administrator authority over dashboards, datasources, and stored query surfaces
ThreatThe highest privilege in the stack is reachable from any local process using published default credentials, which is privilege escalation within the stack
LikelihoodLow (New assessment; the per-skill risk table rates the credential-acceptance failure mode but not the escalation separately. Basis: the escalation requires the same same-host position already required for OT-6)
ImpactLow (New assessment. Basis: the skill records that the same actor could read the volume directly, so the escalation confers no authority beyond what the host user already holds)
MitigationsLoopback-only publishing; the escalation does not cross the host user boundary
Residual RiskLow (per-skill gap register, which records G-EOP-1 as EoP-Low and accepted)
StatusOpen
SourceNIST SP 800-53 AC-6; CWE-269; copilot-otel-metrics skill SECURITY.md gaps G-EOP-1 and G-SPF-1
Trust Boundary CrossedNone; both endpoints sit in the Developer Workstation zone
DetectionNone; shared-account actions are not attributable to a person

OT-8: Local Port Impersonation Misleads the Verification Helpers

FieldValue
CategorySpoofing
AssetCorrectness of the health and content assertions the helpers report to the operator
ThreatA local process that binds a stack port before the container does impersonates the service over plaintext loopback HTTP and returns fabricated results, so verify.py reports a healthy stack that does not exist
LikelihoodLow (per-skill rating; requires an adversary already executing on the host)
ImpactLow (per-skill rating)
MitigationsLoopback-only targets by default; validate_dashboard.py refuses a non-loopback host unless COPILOT_OTEL_ALLOW_REMOTE=1 is set, so retargeting is a deliberate act
Residual RiskLow (per-skill rating; accepted for loopback plaintext HTTP)
StatusOpen
SourceNIST SP 800-53 IA-3, SC-8; CWE-350; copilot-otel-metrics skill SECURITY.md
Trust Boundary CrossedNone; the helpers and the local services both sit in the Developer Workstation zone
DetectionNone; a fabricated healthy response is indistinguishable from a real one at the helper layer

OT-9: Attacker-Controlled Store Content Replayed to Operator and Agent

FieldValue
CategoryTampering
AssetOperator and agent interpretation of helper output, query results, and dashboard content
ThreatBecause ingest is unauthenticated, service_version, session_id, span attributes, and trace names read back by the helpers are attacker-controlled, and text embedded in them can be acted on as instruction rather than inspected as data
LikelihoodLow (New assessment; the per-skill risk table rates label values reaching terminal output but not the instruction-treatment failure mode. Basis: it requires the same same-host injection position as OT-2)
ImpactMedium (New assessment. Basis: this repository runs agent workflows over local tool output, so text treated as instruction has a wider blast radius than a printed label)
MitigationsThe skill states in place that everything returned from the store is untrusted data and never instructions; baseline.py diffing detects injected series; no shipped helper enumerates span content
Residual RiskLow (New assessment. Basis: the control is a written boundary rather than an enforced filter, but the precondition is same-host code execution, which already dominates the local model)
StatusPartially Mitigated
SourceNIST SP 800-53 SI-10, SC-7; CWE-20; copilot-otel-metrics skill SECURITY.md gap G-SPF-1
Trust Boundary CrossedNone; the helpers and the store both sit in the Developer Workstation zone
Detectionbaseline.py diff against the pre-enablement snapshot

OT-10: Dashboard Import Overwrites an Unrelated Dashboard Sharing a UID

FieldValue
CategoryTampering
AssetExisting Grafana dashboard definitions on the targeted instance
Threatvalidate_dashboard.py imports through the Grafana API with overwrite: true, which replaces an unrelated dashboard occupying the same uid
LikelihoodLow (per-skill rating)
ImpactLow (per-skill rating)
MitigationsThe helper refuses a non-loopback Grafana unless COPILOT_OTEL_ALLOW_REMOTE=1 is set; endpoint and credentials come from the environment rather than being hard-coded
Residual RiskLow (per-skill rating; non-loopback targets refused by default)
StatusPartially Mitigated
SourceNIST SP 800-53 SI-7, AC-3; CWE-284; copilot-otel-metrics skill SECURITY.md gap G-TAM-1
Trust Boundary CrossedNone by default; the helper and the local Grafana both sit in the Developer Workstation zone, and reaching a remote instance requires the explicit opt-in
DetectionGrafana dashboard version history on the affected instance

OT-11: Malicious Stack Image Substituted Under a Mutable Tag

FieldValue
CategoryTampering
AssetIntegrity of the grafana/otel-lgtm image that supplies the receiver, both stores, and Grafana
ThreatThe image is referenced by the mutable tag 0.29.2 with no digest pin and no signature or provenance verification, so a republished tag is pulled and run without challenge on any host that has not already cached the layers
LikelihoodLow (per-skill rating)
ImpactHigh (per-skill rating; the substituted image supplies every co-located service in the stack)
MitigationsTag pinning limits drift; no build step and no third-party plugin installation
Residual RiskMedium (per-skill rating; tag-pinned rather than digest-pinned)
StatusOpen
SourceNIST SP 800-53 SA-12, SI-7; CWE-494; copilot-otel-metrics skill SECURITY.md gap G-SUP-1
Trust Boundary CrossedExternal Dependencies ↔ Developer Workstation
DetectionDocker records the resolved digest locally after a pull; the skill does not capture or compare it, so drift between hosts goes unnoticed

OT-12: Compromised Stack Image Executes with Docker Daemon Authority

FieldValue
CategoryElevation of Privilege
AssetWorkstation authority held by the Docker daemon, which is root-equivalent on a typical developer machine
ThreatA compromised image holds whatever authority the daemon grants, independent of what the compose definition declares
LikelihoodLow (per-skill rating)
ImpactHigh (per-skill rating; root-equivalent on a typical developer workstation)
MitigationsThe compose definition adds no capabilities, sets no privileged flag, and mounts no host paths beyond the single named data volume
Residual RiskMedium (per-skill rating; bounded by the tag pin alone, which is the same control OT-11 records as insufficient)
StatusOpen
SourceNIST SP 800-53 AC-6, CM-7; CWE-250; copilot-otel-metrics skill SECURITY.md gaps G-SUP-1 and G-EOP-2
Trust Boundary CrossedExternal Dependencies ↔ Developer Workstation
DetectionNone at the skill layer; container behavior is not monitored

OT-13: Assisted Settings Write Damages a User-Owned JSONC File

FieldValue
CategoryTampering
AssetThe user's global settings.json, including comments, formatting, and unrelated configuration the skill did not create
ThreatA naive parse-and-reserialize silently destroys user comments, trailing commas, and chosen formatting, and a concurrent VS Code write can overwrite the change
LikelihoodLow (per-skill rating for the reserialization variant)
ImpactMedium (per-skill rating)
MitigationsTimestamped backup before the write; per-key upsert that replaces only the target value spans and never reserializes; exact diff presented for explicit approval; post-write re-parse with automatic restore on failure
Residual RiskLow (per-skill rating; concurrent VS Code writes remain unpreventable from outside the editor, with the backup as the recovery path)
StatusPartially Mitigated
SourceNIST SP 800-53 CM-3, SI-7; CWE-664; copilot-otel-metrics skill SECURITY.md gaps G-TAM-2 and G-REP-1
Trust Boundary CrossedNone; the agent and the settings file both sit in the Developer Workstation zone
DetectionTimestamped backup file left beside the settings file records the pre-change state; post-write parse failure triggers restore

OT-14: Whole-File Settings Read Brings Unrelated Values into Model Context

FieldValue
CategoryInformation Disclosure
AssetUnrelated settings values, which on a developer workstation frequently include API endpoints, internal hostnames, and occasionally tokens stored there by other extensions
ThreatThe upsert requires reading the whole settings document, so every value in it enters model context
LikelihoodMedium (per-skill rating)
ImpactLow (per-skill rating)
MitigationsExposure is mitigated in output rather than in reading: the presented diff shows only the changed lines, so unrelated values are not echoed
Residual RiskLow (per-skill rating; reading the whole document is required to preserve it)
StatusPartially Mitigated
SourceNIST SP 800-53 AC-4, SC-28; CWE-200; copilot-otel-metrics skill SECURITY.md gap G-INF-4
Trust Boundary CrossedNone; the agent and the settings file both sit in the Developer Workstation zone
DetectionNone; the read is not separately logged

OT-15: Agent Executes a Generated File with Docker or Cloud Authority

FieldValue
CategoryElevation of Privilege
AssetThe no-execution boundary between generating a file and running it
ThreatAn agent that ran a generated compose or infrastructure file would convert file-write capability into root-equivalent or subscription-scoped execution with no human decision in between
LikelihoodLow (per-skill rating)
ImpactHigh (per-skill rating; docker compose up executes with Docker daemon authority)
Mitigationsdocker compose, az deployment, az group create, and terraform apply are printed for the user and never executed; stated in the skill constraints and stop rules and exercised by the behavior gate
Residual RiskMedium (per-skill rating; the prohibition is advisory prose rather than an enforced control, and a hook would make it enforced)
StatusPartially Mitigated
SourceNIST SP 800-53 AC-6, CM-7; CWE-269; copilot-otel-metrics skill SECURITY.md gap G-EOP-4
Trust Boundary CrossedNone at generation time; the agent and the generated artifacts both sit in the Developer Workstation zone. Execution is what would cross into the Docker daemon and the Azure subscription
DetectionBehavior-gate coverage of the stop rules; shell history and Docker daemon records attribute any execution to the user rather than to the agent

OT-16: Generated Template Over-Grants Access on Deployment

FieldValue
CategoryElevation of Privilege
AssetAzure role assignments and billable resources created when an operator deploys the generated templates
ThreatA template that granted by default would create a Monitoring Reader role assignment on the workspace without a deliberate operator choice
LikelihoodLow (per-skill rating)
ImpactMedium (per-skill rating)
MitigationsThe role assignment is opt-in through an empty-by-default parameter; required inputs for subscription, region, and naming have no defaults; the agent never holds Azure credentials and never deploys
Residual RiskLow (per-skill rating)
StatusPartially Mitigated
SourceNIST SP 800-53 AC-6, CM-6; CWE-732; copilot-otel-metrics skill SECURITY.md gap G-EOP-3
Trust Boundary CrossedNone at generation time; the templates are inert files in the Developer Workstation zone until an operator deploys them with their own Azure credentials
DetectionAzure Activity Log records the role assignment at deployment time

OT-17: Shared Fleet Ingest Credential Enables Telemetry Forgery

FieldValue
CategorySpoofing
AssetIntegrity of organization-wide Copilot usage reporting
ThreatCopilot's exporter can only send a fixed header set, so every workstation presents the same static write-side credential with no per-user or per-device binding, and anything holding it submits telemetry indistinguishable from a real developer's
LikelihoodLow (per-skill rating)
ImpactMedium (per-skill rating; token totals, tool counts, and per-team breakdowns become forgeable)
MitigationsNone preventive. The exposure is disclosed before any Azure artifact is generated, with the write-side-only blast radius stated plainly; read access is governed separately by Azure RBAC
Residual RiskMedium (per-skill rating; inherent to static-header export)
StatusOpen
SourceNIST SP 800-53 IA-2, IA-5; CWE-287; copilot-otel-metrics skill SECURITY.md gap G-INF-3
Trust Boundary CrossedDeveloper Workstation ↔ External SaaS APIs
DetectionNone; ingested telemetry carries no per-user provenance beyond attacker-controlled resource attributes

OT-18: Fleet Ingest Credential Cannot Be Attributed or Rotated in Place

FieldValue
CategoryRepudiation
AssetAttribution and revocability of fleet telemetry ingestion
ThreatNo documented in-place rotation exists for the connection string, so revoking it means recreating the component and redistributing to the whole fleet, and no submission can be attributed to a particular user or device
LikelihoodMedium (per-skill rating)
ImpactMedium (per-skill rating; incident response becomes a fleet-wide operation rather than a per-user one)
MitigationsNone preventive. Disclosed rather than mitigated; the credential is supplied from the operator's secret store and never written into a generated file
Residual RiskMedium (per-skill rating)
StatusOpen
SourceNIST SP 800-53 AU-10, IA-5; CWE-778; copilot-otel-metrics skill SECURITY.md gap G-INF-3
Trust Boundary CrossedDeveloper Workstation ↔ External SaaS APIs
DetectionNone; there is no per-user provenance to audit and no rotation event to observe

OT-19: Prompt Content Reaches a Shared, Billed, Queryable Workspace

FieldValue
CategoryInformation Disclosure
AssetDeveloper prompt content in an organization-wide Log Analytics workspace readable by anyone holding Monitoring Reader
ThreatContent-bearing span attributes reach shared storage unless they are removed before ingestion, and the removal is defeated by deleting the collector processor
LikelihoodMedium (per-skill rating)
ImpactHigh (per-skill rating; shared, queryable, durable prompt content)
MitigationsThe generated collector configuration deletes the six observed plaintext content attributes plus copilot_chat.reasoning_content defensively, acting before data reaches storage; the Azure dashboard ships a panel counting these attributes
Residual RiskLow (per-skill rating; the strongest available control acts pre-storage, and a workspace receiving content is visible rather than silent)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-28, AC-4; CWE-359; copilot-otel-metrics skill SECURITY.md gap G-INF-1
Trust Boundary CrossedNone; the collector and the workspace are both operator-deployed components in the External SaaS APIs zone. The crossing occurs earlier, on the workstation-to-collector export covered by OT-17
DetectionAzure dashboard panel counting content attributes in the workspace

OT-20: Unbounded Ingestion Inflates Cost Against a Billed Backend

FieldValue
CategoryDenial of Service
AssetAzure Monitor ingestion spend for the organization
ThreatThe shared credential permits unbounded ingestion against a billed backend, so the practical denial of service is financial rather than availability
LikelihoodMedium (per-skill rating)
ImpactMedium (per-skill rating)
MitigationsdailyQuotaGb defaults to 5 in every generated template and is named as the only spend guardrail; disabling the cap requires deliberately setting it to -1; captureContent is named as the dominant volume multiplier wherever cost is discussed
Residual RiskLow (per-skill rating)
StatusPartially Mitigated
SourceNIST SP 800-53 SC-5, SA-5; CWE-770; copilot-otel-metrics skill SECURITY.md gap G-DOS-2
Trust Boundary CrossedNone; the collector and the workspace are both in the External SaaS APIs zone
DetectionDaily quota breach surfaced by Azure Monitor; ingestion volume visible on the generated dashboard

Security Controls

Supply Chain Security Controls

IDControlImplementationValidates Against
SC-1Dependency Pinning ValidationTest-DependencyPinning.ps1S-1, S-2
SC-2SHA Staleness MonitoringTest-SHAStaleness.ps1S-1
SC-3Dependency Reviewdependency-review.ymlS-2, AI-5
SC-4npm Security Auditnpm audit in pr-validation.ymlS-2
SC-5Dependabot Updatesdependabot.ymlS-1, S-2
SC-6Tool Checksum Verificationscripts/security/tool-checksums.jsonS-1
SC-7SBOM Generation and Attestationanchore/sbom-action, actions/attest in release-stable.ymlS-1, S-2
SC-8SBOM Dependency Diffsbom-diff job in release-stable.ymlS-1, S-2
SC-9VEX Vulnerability Triage and Attestationvex-detect.yml, vex-draft.md, vex-attest job in release-stable.ymlS-1, S-2

SC-8: SBOM Dependency Diff Implementation

The sbom-diff job in release-stable.yml runs during each release to surface supply chain changes between consecutive versions. It compares the current dependency SBOM against the previous release, generating a structured dependency-diff.md report that is uploaded to the GitHub Release.

FieldValue
TriggerRuns when release_created == 'true', after SBOM generation completes
InputSPDX JSON dependency SBOMs from current build and previous GitHub Release
Outputdependency-diff.md uploaded to the GitHub Release as an asset
Failure Modecontinue-on-error: true prevents diff failures from blocking the release
Permissionscontents: write (release asset upload only)

The diff script parses SPDX JSON packages, excludes root document entries, and categorizes changes into three groups:

  • Added packages not present in the previous release
  • Removed packages no longer included in the current build
  • Version changes where the same package appears in both releases at different versions

When no previous release exists or the prior release lacks a dependency SBOM, the job exits cleanly without producing a diff. This graceful degradation ensures the first release in a repository proceeds without error.

SC-9: VEX Vulnerability Triage and Attestation Implementation

SC-9 spans three workflows: detection finds untriaged vulnerabilities, drafting proposes OpenVEX status updates for human review, and the release pipeline attests the resulting document. The canonical VEX document is security/vex/hve-core.openvex.json.

FieldValue
Detection TriggerTuesdays 08:00 UTC, after a successful Stable Release Pipeline run, or manual dispatch
Detection Workflowvex-detect.yml runs OSV-Scanner and files or updates a single triage issue
Detection Permissionscontents: read, issues: write
Drafting Triggerworkflow_run from VEX Detection, plus manual dispatch
Drafting Workflowvex-draft.md invokes the SSSC Reviewer agent and opens one pull request
Drafting Permissionscontents: read, issues: read
Release Attestationvex-attest job in release-stable.yml, via the reusable vex-attest.yml
AttestationsBuild provenance over the VEX document, plus VEX as predicate over the SBOM subject
Human Review GateAI drafts; a CODEOWNERS-required human reviews and merges the pull request

Detection performs no AI drafting. It compares OSV-Scanner findings against the VEX document and reports divergence as a triage issue.

Drafting is gated twice so it consumes no model budget when there is nothing to do. The first gate skips while a VEX draft pull request is already open. The second gate skips when every finding already carries a terminal VEX status. The resulting pull request is restricted to the VEX document and is labeled security, automated, and needs-triage.

The release attestation produces two artifacts: a build-provenance attestation whose subject is the VEX document, and an in-toto attestation that binds the VEX document as an OpenVEX predicate over the dependency SBOM subject. The VEX document is also uploaded to the GitHub Release.

The merge commit author is the accountable author of record, never the agent.

Code Quality Controls

IDControlImplementationValidates Against
CQ-1CodeQL Analysiscodeql-analysis.ymlT-1, E-1
CQ-2Markdown Lintinglint:md npm scriptT-2, RAI-4
CQ-3Frontmatter ValidationValidate-MarkdownFrontmatter.ps1T-2
CQ-4PowerShell AnalysisInvoke-PSScriptAnalyzer.ps1T-1
CQ-5YAML LintingInvoke-YamlLint.ps1T-1
CQ-6Workflow Input IsolationStep-level env: mappings for caller-controlled inputsT-3
CQ-7Project Path ValidationAssert-WorkflowProjectDirectory.ps1T-3
CQ-8Input Interpolation DetectionTest-DangerousWorkflow.ps1T-3
CQ-9Fork Workflow ApprovalRepository Actions settingsT-3

CQ-6 keeps GitHub expression evaluation out of shell command text. A workflow maps an input such as ${{ inputs.version }} to an environment variable, then reads the shell's native variable ($INPUT_VERSION or $env:INPUT_VERSION) inside the run: block. Matrix values generated from repository-controlled configuration do not cross the same caller-controlled boundary.

Test-DangerousWorkflow.ps1 enforces the boundary through the dangerous-workflow/direct-input-interpolation rule, which fails the lint:dangerous-workflow lane and the dangerous-workflow-check required check. The rule is type-driven rather than text-driven: it resolves each inputs.<name> reference found in a run: body or an actions/github-script script: body against the declared type in on.workflow_call.inputs or on.workflow_dispatch.inputs, and reports every reference whose type is not boolean. The scan covers .github/workflows and .github/actions.

Composite action metadata is held to a stricter rule. The action metadata schema gives inputs.<input_id> only description, required, default, and deprecationMessage, so an action input cannot declare itself boolean and no exception applies. Every action input reaching a runs.steps[*].run body is reported as untyped. This matters because a composite action is otherwise a laundering path: a workflow input passed through a step with: value would reach shell command text on the far side of the CQ-6 boundary.

One documented exception is retained. An input declared type: boolean is exempt because GitHub constrains that type to the literals true and false, so the substituted text can carry no shell metacharacters, and callers that supply a mismatched value are rejected before the workflow runs. Every other declared type carries arbitrary caller text, and an input whose declared type cannot be resolved is treated as a violation so the gate fails closed. Interpolations outside shell command text, such as working-directory:, if:, and action with: values, are not shell command text and remain in scope for CodeQL rather than for CQ-6.

Access Controls

IDControlImplementationValidates Against
AC-1Branch ProtectionRepository settingsT-1, E-2
AC-2CODEOWNERS Enforcement.github/CODEOWNERST-1, T-2
AC-3PR Review RequirementsBranch protection rulesT-2, AI-1
AC-4Minimal Workflow Permissionspermissions: in all workflowsE-1

Vulnerability Management Controls

IDControlImplementationValidates Against
VM-1Coordinated DisclosureSECURITY.mdI-1
VM-2Secret ScanningGitHub native, gitleaks PR gate (gitleaks-scan.yml)I-1, I-2
VM-3Credential Persistence Disabledpersist-credentials: falseI-1, E-1

Assurance Argument

This section presents the security assurance case using Goal Structuring Notation (GSN) patterns.

Top-Level Goal

G0: HVE Core is acceptably secure for its intended use as an enterprise prompt engineering framework.

Supporting Goals

GoalStatementStrategy
G1Supply chain attacks are mitigatedS1: Defense-in-depth controls
G2Unauthorized modifications are preventedS2: Access control enforcement
G3AI-specific risks are documented and addressedS3: Risk acceptance with documentation
G4Responsible AI principles are followedS4: Guidelines and review processes

Evidence Mapping

GoalEvidence
G1Dependency pinning logs, staleness reports, dependency review results, SBOM attestation verification, dependency SBOM diff reports
G2Branch protection configuration, CODEOWNERS file, PR review history
G3This security model document, OAuth Authentication Threats, MCP Server Trust Analysis
G4Writing style guidelines, inclusive language checks, PR reviews

Assumptions and Justifications

IDAssumptionJustification
A1GitHub platform security is adequateSOC 2 Type II certified
A2GitHub Copilot provides baseline AI safetyMicrosoft RAI compliance
A3Contributors act in good faithPR review provides verification
A4Consumers implement their own code reviewDocumented as consumer responsibility

Argument Summary

HVE Core achieves acceptable security through:

  1. Automated Controls: 25+ security controls execute automatically via CI/CD
  2. Defense-in-Depth: Multiple overlapping controls for critical threats
  3. Transparent Risk Acceptance: AI-inherent risks documented with clear boundaries
  4. Inherited Security: Uses GitHub and Copilot platform security

MCP Server Trust Analysis

HVE Core documents integrations with Model Context Protocol servers. This section analyzes the trust posture of each server.

NOTE

GitHub MCP is enabled by default in VS Code when using GitHub Copilot. The other servers are optional and recommended for an optimal HVE Core development experience. See MCP Configuration for setup instructions.

Server Summary

ServerProviderClassificationTrust LevelData Flow RiskDefault
GitHub MCPGitHubFirst-partyHighLowYes
Azure DevOps MCPMicrosoftFirst-partyHighLowNo
Microsoft Docs MCPMicrosoftFirst-partyHighLowNo
Context7 MCPUpstashThird-partyMediumMediumNo

GitHub MCP Server

AttributeAssessment
OperatorGitHub (Microsoft subsidiary)
DeploymentRemote (github.com hosted) or local
AuthenticationOAuth, GitHub App tokens, PATs
AuthorizationInherits GitHub permission model
Data HandlingData stays within GitHub ecosystem
AuditGitHub audit log captures operations
RecommendationLow risk; enable organization policies for access control

Azure DevOps MCP Server

AttributeAssessment
OperatorMicrosoft
DeploymentLocal only (npx invocation)
AuthenticationBrowser-based Azure AD login
AuthorizationInherits Azure DevOps permissions
Data HandlingNo persistent storage by MCP server
AuditAzure DevOps audit log
RecommendationLow risk; standard Microsoft security practices apply

Microsoft Docs MCP Server

AttributeAssessment
OperatorMicrosoft
DeploymentRemote (learn.microsoft.com API)
AuthenticationNone required (public documentation)
AuthorizationRate limiting only
Data HandlingRead-only queries; no user data transmitted beyond search terms
AuditStandard Microsoft API logging
RecommendationLow risk; queries limited to public documentation

Context7 MCP Server

AttributeAssessment
OperatorUpstash (third-party)
DeploymentLocal client, Upstash backend
AuthenticationAPI keys via Upstash dashboard
AuthorizationRate limiting, enterprise SSO available
Data HandlingQueries processed locally; only topics sent to backend
AuditAPI logs with 30-day retention
RecommendationMedium risk; evaluate topic extraction for sensitive context

Trust Recommendations

  1. First-party servers (GitHub, Azure DevOps, Microsoft Docs): Enable with organization policy controls; GitHub MCP is enabled by default
  2. Third-party servers (Context7): Evaluate data flow, use API key rotation, review Upstash trust center

Mural Skill Runtime Hardening

The Mural skill is not an MCP server. It is a local Python CLI dispatched through argparse, and an agent caller reaches it by invoking that CLI through a terminal tool. Because both stdout and stderr are captured into agent context, every output sink routes through the skill's redaction barrier rather than only the operator-facing ones.

AttributeAssessment
Operatorhve-core (.github/skills/experimental/mural/)
DeploymentLocal CLI (python -m mural <command>); no listener beyond the single-shot OAuth loopback receiver
AuthenticationPer-user Mural OAuth app via Authorization Code + PKCE loopback flow
AuthorizationInherits the granted Mural scope set
Data HandlingTokens persisted to the OS keyring or a per-user on-disk cache (mode 0600); Mural payloads returned as untrusted text on stdout
AuditRedacted stderr diagnostics plus the Mural API audit trail
Threat ModelMural Skill Security Model; the OAuth-flow STRIDE entries in OAuth Authentication Threats
RecommendationMedium data-flow risk; treat all returned widget text as untrusted, restrict OAuth scopes via MURAL_SCOPES where possible

Outstanding Hardening Work

  • Build an Atheris fuzz harness under .github/skills/experimental/mural/tests/fuzz/ exercising _redact() and _LoopbackHandler request parsing.
  • MURAL_KEYRING_BACKEND is a developer trust toggle: when set, the skill imports the named module via importlib and uses it as the OS keyring backend. Treat any value as code-execution surface; operators must only set it to a backend module they own or fully trust. Unset by default; the OS keyring or the mode-0600 on-disk cache is the production path.

Skill Security Models

Most skills are markdown knowledge packs with no runtime and are covered by the repository-level supply-chain and developer-workflow controls above. Skills that ship an executable runtime (network egress, credential handling, subprocess execution, or untrusted document/content parsing) carry their own per-skill STRIDE threat model in a SECURITY.md next to their SKILL.md. Those models follow a shared structure (assets, adversaries, trust buckets with per-bucket STRIDE mitigations, and an Enterprise Readiness Gaps register) and are the authoritative source for each skill's residual risk.

SkillRuntime surfacePrimary residual gapsSecurity model
jiraREST CLI; environment credentials; scoped Cloud routing to the fixed Atlassian resource API; configured-origin unscoped Cloud and Data Center routingNo client-side token revocation; audit sink not tamper-evident; regex redaction residual; no certificate pinningSECURITY.md
gitlabREST CLI; public-client PKCE loopback and human-assisted device flow; owner-only mode-0600 profile store and lock; explicit legacy PAT; git-remote subprocessRefresh-commit uncertainty; same-uid store access; no server revocation on local logout; untrusted CI-trace output; no certificate pinningSECURITY.md
mural (experimental)REST CLI; OAuth loopback; keyring/mode-0600 store; canonical API destination; separate no-redirect API, token, and SAS egressOAuth audit gap; file-backend plaintext; keyring backend toggle; no certificate pinningSECURITY.md
tts-voiceover (experimental)Azure Speech egress; key/Entra credentials; SSML + PPTX parsingContent egress to Azure region; broad credential chainSECURITY.md
accessibilityPath A authorized HTTP(S) and operator-selected local-file scanning through npx @axe-core/cli@4.12.1; Path B validated configuration, same-origin Playwright 1.61.1 runtime, endpoint-managed system Chrome, direct-request probes, runtime evidence, and design-intent verificationPath A npx integrity and remote redirect/DNS/browser-derived egress; target-derived report, trace, screenshot, and transcript content; endpoint-owned Chrome identity and patching; Playwright/Chrome parser surface; inherited child environment; consuming-project design-intent validation boundarySECURITY.md
powerpoint (experimental)Sandboxed content-extra.py execution; LibreOffice/MuPDF document parsingDenylist confinement is not OS-level; external-parser CVE exposureSECURITY.md
video-to-gif (experimental)Local CLI (bash + PowerShell); FFmpeg/ffprobe subprocess; untrusted media parsingInherited FFmpeg decoder CVE exposure; bare-filename search resolutionSECURITY.md
copilot-otel-metrics (experimental)Schema-enforced, backed-up, audited, atomically replaced write into the user's global settings.json; loopback OTLP ingest through a fail-closed filtering Collector in front of a containerized Grafana/Prometheus/Tempo stack; five stdlib Python reference helpers plus a shared input-policy module querying local APIs; generated fleet collector configuration, a per-workstation relay, Bicep, Terraform, and Azure CLI templates the operator deploysPrompt content present in spans before the Collector filters it and in plaintext across the loopback hop; content carriers the Collector governs incompletely, namely span names and metric metadata preserved for shipped dashboard queries, and span links and metric exemplars unreachable by any processor in this distribution, and the instrumentation scope and schema fields left unfiltered on an assumption about emitter behavior; the content scrub is fail-open per statement while its sibling allow-list is fail-closed; shared fleet-wide ingest credential with no per-user binding or in-place rotation, held in the workstation relay's runtime environment rather than the editor's, at the cost of an unauthenticated local listener and of making relay health a prerequisite for all of that workstation's telemetry; unauthenticated Prometheus and Tempo query APIs; exporter-side certificate validation outside skill control; retention is the only deletion mechanism; the no-execution boundary on Docker and infrastructure commands is advisory rather than enforcedSECURITY.md
gh-code-scanningGitHub code-scanning read via gh CLI subprocess; stdout onlyUnpinned gh/jq PATH dependencies; TLS delegated to ghSECURITY.md
customer-card-render (experimental)Local Python CLI; regex parse of untrusted DT markdown; YAML emissionInherited powerpoint build toolchain; confidential DT prose egressSECURITY.md
security-planningLocal Python generator, native TMT validation harness, Windows UI Automation, screenshot capture, and overlay/evidence handlingScreenshot evidence is never redacted; UI Automation drives a real desktop session; overlays stay pending until a human promotes themSECURITY.md
vexLocal Python gate (vex_gate.py); anchored-regex parse of untrusted detection-issue body; json.loads of local OpenVEX doc; exit code onlyGate-suppression by issue-edit access; forced-proceed AI-credit consumptionSECURITY.md

Skills whose scripts perform only local validation with no external surface (for example adr-author and vally-tests) do not require a dedicated model; their risk is bounded by the repository-level controls. When a new skill adds an executable runtime with any of the surfaces above, add a SECURITY.md following the shared structure and register it in this table and in the security documentation index.

Quantitative Security Metrics

Configured Thresholds

MetricThresholdSource
Dependency Pinning Compliance≥95%dependency-pinning-scan.yml
SHA Staleness≤30 dayssha-staleness-check.yml
Dependency Review Failmoderatedependency-review.yml
npm Audit Fail Levelmoderatepr-validation.yml
Required PR Reviewers1Branch protection

Security Response Commitments

CommitmentSLASource
Security Report Response24 hoursSECURITY.md
Governance Change Comment1 weekGOVERNANCE.md

Validation Workflow Coverage

WorkflowTriggerSecurity Checks
pr-validation.ymlPR to main/developPinning, npm audit, CodeQL, gitleaks
release-stable.ymlPush to mainPinning, gitleaks, SBOM attestation, dependency diff (release)
codeql-analysis.ymlPush, PR, weeklyStatic analysis
dependency-review.ymlPR to main/developVulnerability scanning
weekly-security-maintenance.ymlSundays 2 AM UTCPinning, staleness, CodeQL

References

Internal Documentation

External Standards

OAuth Standards (Authorization Code + PKCE)


🤖 Crafted with precision by ✨Copilot following brilliant human instruction, then carefully refined by our team of discerning human reviewers.