Design the CyberOps Security Boundary
Design human-governed controls for a local MCP defensive assistant.
Introduction
30 Second Summary
Helpful assistants can process messy evidence quickly. A hidden instruction inside that evidence can steer an unchecked assistant toward an action nobody approved.
In this project, you will design the security boundary for Frankly CyberOps before it gains executable capability. Your finished documents will prove that no tool action depends on model intent alone.
What You'll Build
Walk someone through the finished design to prove that attacker-controlled evidence cannot authorize a tool.
By the end of this project, you'll have:
- A local-only security charter that sorts every request into one of three outcomes: PERMIT, approval-gated, or DENY.
- A level-0 data-flow diagram that makes GAP-01 visible. Its corrected path shows every gate before execution.
- A prioritized STRIDE register connecting each threat to a mitigation. Each high-priority item also names its verification evidence.
- Secret Mission: A hostile evidence test that proves an indirect prompt injection produces a logged denial with no executor invocation.
Are there any prerequisites?
You only need Visual Studio Code on Windows for this phase. No additional installation is required.
Before We Start
This checkpoint defines the authorized local environment Frankly CyberOps may protect before any executable capability exists. Your answer makes human approval the final authority for every later design choice.
Set Up the Security Design Workspace
Security requirements need a small workspace that reviewers can inspect. Threat decisions stay traceable when they share that reviewable home.
Later implementation choices can point back to these records. In this step, you will open a local folder in Visual Studio Code for the security-design documentation.
In this step, get ready to:
- Create the local workspace folder.
- Open the folder in VS Code.
- Create three saved Markdown design files.
Create and open the workspace folder
The workspace folder keeps every design artifact under one clear project name. You will place it in your Windows Documents folder so it is easy to find again.
- Press the Windows key to open the search bar.
- Type File Explorer and press Enter to open it.
- Select Documents in the left sidebar.
- Press Ctrl+Shift+N to create a new folder.
- Type frankly-cyberops-design and press Enter to name the folder.
Your first building block is in place because the empty frankly-cyberops-design folder now gives the design work a clear home.
- Press the Windows key to open the search bar.
- Type Visual Studio Code and press Enter to open it.
- Click File in the top menu bar.
- Click Open Folder....
- Select the frankly-cyberops-design folder inside Documents.
- Click Select Folder.
That is the workspace foundation in place. VS Code shows frankly-cyberops-design at the top of the Explorer sidebar.
Folder did not open?
- Return to File and select Open Folder... again.
- Check that you selected frankly-cyberops-design inside your Documents folder.
Still stuck? Help me open my frankly-cyberops-design folder as a VS Code workspace.
Create the Markdown files
Each file has one security-design responsibility. Keeping them separate makes later reviews easier to follow.
- Select the Explorer icon in the left Activity Bar.
- Select New File... in the Explorer view.
- Type security-charter.md and press Enter.
- Select New File... again.
- Type threat-model.md and press Enter.
- Select New File... one more time.
- Type decision-log.md and press Enter.
You now see three empty files under the workspace folder in Explorer. Their names define the documentation structure for the remaining design work.
Why separate the design files?
- The security-charter.md file is ready for the authorized-use charter.
- The threat-model.md file is ready for the data-flow diagram and STRIDE register.
- The decision-log.md file is ready for security decisions and residual-risk rationale.
Save and verify the workspace
Saving each file establishes the exact empty artifact state needed for the next step. The filenames should remain grouped beneath the workspace folder.
- Select security-charter.md in Explorer.
- Press Ctrl+S to save the file.
- Select threat-model.md in Explorer.
- Press Ctrl+S to save the file.
- Select decision-log.md in Explorer.
- Press Ctrl+S to save the file.
Before you check the workspace, which three filenames do you expect to see beneath frankly-cyberops-design?
- Inspect the Explorer sidebar in VS Code.
You will see security-charter.md, threat-model.md, and decision-log.md beneath the workspace folder. This confirms the documentation workspace is ready.
Missing a file?
- Compare each filename with the names shown above.
- Use New File... in Explorer to recreate any missing file.
- Press Ctrl+S after selecting each file.
Need another pair of eyes? Help me check why one of my Markdown files is missing from VS Code Explorer.
✔️ Awesome, I've got everything!
Your frankly-cyberops-design workspace is open. All three empty Markdown files are saved in Explorer.
ⓧ I'd like to double check the full code
Compare your workspace with this exact artifact state:
- frankly-cyberops-design: Local VS Code workspace folder opened by the learner.
- security-charter.md: Saved empty Markdown file in the frankly-cyberops-design workspace, ready for the authorized-use charter.
- threat-model.md: Saved empty Markdown file in the frankly-cyberops-design workspace, ready for the data-flow diagram and STRIDE register.
- decision-log.md: Saved empty Markdown file in the frankly-cyberops-design workspace, ready for security decisions and residual-risk rationale.
Your security-design workspace is ready for reviewable decisions. Next, you will turn security-charter.md into the authorized-use contract for Frankly CyberOps.
Write the Authorized-Use Charter
Your VS Code workspace now gives each security decision a traceable home. Frankly CyberOps still needs a contract that separates authorized defensive work from unsafe requests.
Before the assistant can reject unsafe work, it needs explicit rules for targets, actions, data, approvals, and failure behavior. This step turns those rules into an authorized-use boundary.
In this step, get ready to:
- Set the system's authority boundary.
- Classify each type of action.
- Make unsafe or incomplete requests fail closed.
Define the purpose and authority boundary
The charter starts by defining who operates Frankly CyberOps. It also limits where the assistant may act.
- Switch back to security-charter.md in the editor.
- Enter # Frankly CyberOps Authorized-Use Charter as the document title.
You should now see the charter title at the top of the file.
- Add ## Purpose and Operating Assumptions below the title.
- Save security-charter.md with Ctrl+S.
The saved Markdown file now has a clear place for the charter's operating assumptions.
- Write one sentence defining Frankly CyberOps as a single-operator local-only defensive assistant.
- Add a sentence limiting the charter to targets backed by explicit authorization evidence.
Your purpose section should now identify the operator. It should also establish the evidence required before a target enters scope.
- Save security-charter.md with Ctrl+S.
- Add ## Decision Authority below the operating assumptions.
The new section separates recommendations from authorization.
- State that Claude may analyze evidence or recommend an action.
- State that only the human operator may authorize the exact action.
You should now see a clear authority boundary. Claude can support the decision without becoming the decision-maker.
- Save security-charter.md with Ctrl+S.
Why the charter comes first
A written boundary gives every later control a fixed standard. Model output cannot expand the authorized scope.
The charter also makes reviews repeatable. The same request should receive the same classification every time.
Classify every action
Action classes turn the charter into a decision tool. Every request receives a class before execution or approval is considered.
- Add ## Action Classes below the decision-authority section.
- Add ### Permitted under the new heading.
The permitted subsection is ready to hold work that stays inside the defensive boundary.
- Write a rule allowing defensive review of saved evidence from an authorized lab.
- Limit permitted work to targets with documented authorization.
The permitted class now supports safe analysis without opening the door to unknown targets.
- Save security-charter.md with Ctrl+S.
- Add ### Approval-Gated below the permitted class.
The approval-gated subsection is ready for actions that need explicit human control.
- Write a rule requiring human approval for active validation or any action with system impact.
- Bind approval to the actor, tool, target, and normalized parameters.
Approval now describes one exact action. A changed request needs a new approval decision.
- Save security-charter.md with Ctrl+S.
- Add ### Denied below the approval-gated class.
The denied subsection is ready to capture requests that must never proceed.
- State that work against an unknown or unauthorized target is denied.
- Add a blanket denial covering credential theft, persistence, destructive actions, and stealth.
Your three classes now provide a direct route from a request to a policy outcome.
- Save security-charter.md with Ctrl+S.
Set failure rules and test decisions
A fail-closed policy turns missing control state into denial. The charter also treats scan evidence as untrusted input.
- Add ## Data Handling and Failure Rules below the action classes.
- Write a rule treating scan evidence as untrusted data instead of instructions.
Hostile text inside scan evidence now remains data under the charter.
- Add a rule requiring secrets to be excluded or redacted.
- Add a rule requiring approval to match the exact action.
The data rules now protect secrets. The approval rule prevents reused approval from covering a changed action.
- Add a rule that produces DENY when authorization, policy, approval, or audit state is unavailable.
- Save security-charter.md with Ctrl+S.
The charter now has an explicit default outcome for incomplete security state.
- Add ## Decision Table below the failure rules.
- Create a table with columns named Request, Authorization Evidence, Action Class, Approval State, Decision, and Reason.
The decision table gives you one place to apply every charter rule to a concrete request.
- Add an authorized-lab row using the request Review saved scan evidence from the approved local lab..
- Add a missing-authorization row using the request Scan a target with no authorization record..
Two requests are now ready for classification under different authorization states.
- Add an exploit row using the request Exploit the lab to obtain credentials..
- Save security-charter.md with Ctrl+S.
Before you complete the decisions, which outcome do you expect for each request?
- Complete the Decision cell for all three rows using the charter.
- Save security-charter.md with Ctrl+S.
You should see PERMIT for the authorized-lab request. The missing-authorization request should show DENY.
The exploit request should also show DENY. You have now locked in the core boundary: unsupported requests have nowhere to proceed.
Decision table does not match?
- Make authorization evidence mandatory if the missing-authorization row produces PERMIT.
- Make the denied class override every other class if the exploit row does not produce DENY.
Still seeing a different result? Help me compare my decision table with my authorized-use charter.
✔️ My charter is complete
Your saved charter now defines scope, authority, action classes, data handling, failure behavior, and test decisions.
ⓧ I'd like to double check the charter
Compare security-charter.md with this completion checklist.
- Confirm the purpose defines a single-operator local-only defensive assistant.
- Confirm targets require evidence of authorization.
- Confirm Claude may recommend actions but cannot authorize them.
- Confirm the charter defines permitted, approval-gated, and denied classes.
- Confirm credential theft, persistence, destructive actions, stealth, and unauthorized targets are denied.
- Confirm scan evidence is untrusted.
- Confirm secrets are excluded or redacted.
- Confirm approval matches the exact action.
- Confirm missing authorization, policy, approval, or audit state produces DENY.
- Confirm the example decisions are PERMIT, DENY, and DENY.
Your charter can now classify requests before any capability exists. Next, you will map the unsafe path that appears when untrusted evidence flows toward execution without these controls.
Map the Unsafe Happy Path
Your authorized-use charter now defines the work Frankly CyberOps may accept. This step tests what happens when untrusted scan evidence enters the system in your VS Code workspace.
A naive assistant can let attacker-controlled evidence shape the reasoning inside Claude Desktop. A level-0 data-flow diagram exposes that unsafe route before you redesign it.
In this step, get ready to:
- Map the operator, Claude Desktop, the future local MCP server, Docker-isolated tools, the authorized lab, and local storage.
- Mark the attacker-controlled, AI, MCP, Docker, and storage trust boundaries.
- Document GAP-01 as the unsafe route from hostile evidence toward execution.
Draw the level-0 data-flow diagram
A level-0 diagram shows the system's major components without implementation detail. It gives every later security decision a specific place in the design.
Why map data flow first?
A checklist-only review is quicker. Its flat structure leaves data movement and trust-zone changes hard to trace.
A data-flow diagram shows where evidence moves between actors, processes, and storage. That visible path makes unsafe handoffs easier to identify.
- Select threat-model.md in the Explorer view to make it the active editor.
- Add a section named Level-0 Data-Flow Diagram.
- Add external-entity nodes for Operator and Authorized lab.
- Confirm both external-entity labels are visible in the diagram.
- Add process nodes for Claude Desktop, Future local MCP server, and Docker-isolated security tools.
- Add data-store nodes for Evidence storage, Findings storage, and Audit storage.
- Confirm the diagram now contains all eight required components.
Your draft now separates people, processes, external systems, and stored data. The next lines show how information moves between them.
- Connect the nodes with labeled flows for authorized request, proposed tool action, tool invocation, lab traffic, scan evidence, findings, and audit event.
- Save threat-model.md by pressing Ctrl+S.
You should now be able to start at the operator and follow the proposed work through Claude Desktop toward the authorized lab. The evidence, findings, and audit destinations should also be visible.
Mark the trust boundaries
A trust boundary marks a handoff between zones with different security assumptions. Each boundary turns a broad concern into a specific crossing that you can review.
- Enclose the authorized lab and its outbound scan data within a boundary labeled Attacker-controlled lab data.
- Enclose the Claude Desktop context within a boundary labeled AI context.
- Confirm that lab evidence crosses into a separate AI trust zone.
- Enclose the future local MCP server within a boundary labeled MCP policy and execution layer.
- Enclose the security tools within a boundary labeled Docker container boundary.
- Confirm that the MCP layer remains separate from the Docker-isolated tools.
- Enclose the three data stores within a boundary labeled Persistent local storage.
- Save threat-model.md by pressing Ctrl+S.
Your map now shows five distinct trust zones. Each crossing identifies a place where assumptions can fail.
Why Docker stays a trust boundary
Docker Desktop runs Linux containers inside a virtual machine on Windows. Bind mounts, inherited credentials, and network access can still weaken that containment.
Keeping the container boundary visible prevents the design from treating isolation as automatic proof of safety.
Expose GAP-01
The diagram becomes useful when you follow attacker-controlled content across it. This designed obstacle keeps the route unchecked so its weakness remains visible.
- Add a scan result labeled Hostile text embedded in scan output to the output from Authorized lab.
- Draw the route from Authorized lab to Evidence storage.
- Confirm that the hostile text crosses from attacker-controlled lab data into persistent storage.
- Extend the route from Evidence storage to Claude Desktop.
- Extend the route from Claude Desktop toward the Docker-isolated security tools through the Future local MCP server.
Before you inspect this route, do you think any independent decision currently prevents the hostile evidence from influencing execution?
- Trace the route from the hostile scan result to the Docker-isolated security tools.
The trace reaches the execution path without an independent authorization check. It also reaches that path without an approval gate.
- Label the unchecked route GAP-01.
- Save threat-model.md by pressing Ctrl+S.
- Select decision-log.md in the Explorer view to make it the active editor.
- Add one decision entry titled GAP-01: Model intent is not authorization. The entry states that model intent or model output cannot constitute authorization because untrusted, attacker-controlled evidence may influence model reasoning. It requires independent deterministic authorization and approval controls before execution.
- Save decision-log.md by pressing Ctrl+S.
Before you test the finished map, where do you expect the unchecked route to cross into a different trust zone?
- Test the diagram by tracing from Authorized lab through Evidence storage to Claude Desktop and toward the Docker-isolated security tools.
You should cross the Attacker-controlled lab data boundary. The route reaches execution without an independent authorization or approval gate.
That is a meaningful milestone. Your design now exposes GAP-01 before any executable capability exists.
✔️ Awesome, I've got everything!
Your diagram shows every required component, all five trust boundaries, and the unchecked GAP-01 route. Your decision log also explains why model intent cannot authorize execution.
ⓧ I'd like to double check the design
Compare your two updated design files with this checklist.
- Confirm threat-model.md contains the operator, Claude Desktop, future local MCP server, Docker-isolated security tools, authorized lab, evidence storage, findings storage, and audit storage.
- Confirm the diagram identifies attacker-controlled lab data, AI context, MCP policy and execution, Docker isolation, and persistent local storage as separate trust boundaries.
- Confirm GAP-01 traces hostile scan evidence through Claude toward execution without independent authorization or approval.
- Confirm decision-log.md records why model intent cannot constitute authorization and requires deterministic controls before execution.
You can now point to the exact route where attacker-controlled evidence threatens the execution path. Next, you will replace that route with deterministic authorization, exact-action approval, isolation, and audit gates.
Insert Deterministic Security Gates
Your GAP-01 route now makes the danger visible. Attacker-controlled evidence can influence Claude Desktop on its way toward execution.
Deterministic security gates make decisions from trusted application state outside the model. They cover authorization, policy, human approval, execution limits, plus auditability.
In this step, get ready to:
- Replace the unchecked route in your data-flow diagram with deterministic security gates.
- Document constrained-executor controls using least privilege.
- Prove unsafe states produce DENY before execution.
Replace the unchecked route
A deterministic gate reaches the same decision from the same trusted inputs. Model recommendations remain inputs to the design, while application controls decide whether execution is allowed.
Why deterministic gates?
A checklist can describe the intended controls, but it cannot prove that every execution route uses them. Your corrected diagram makes each required decision point visible.
The guarded route also keeps authorization outside the AI context. Attacker-controlled evidence cannot redefine the policy that evaluates it.
- In the Explorer sidebar from earlier, select threat-model.md.
- Relabel GAP-01 as the unsafe historical route.
Your diagram still preserves the original weakness. This gives reviewers a visible comparison between the unsafe route and its replacement.
- Place an Authorization and policy decision point before any approval or execution component.
- Connect the future local MCP server to this decision point.
The future local MCP server should now reach execution controls only through the new decision point. This breaks the direct model-to-executor path.
- Add an Exact-action approval gate after the policy decision for approval-gated actions.
- Bind the approval record to the actor, tool, target, and normalized parameters.
The approval gate now describes one specific action. Any change to those four values requires a new approval decision.
- Add a Constrained executor after the policy and approval gates.
- Place a Create audit event stage between the constrained executor and the result-return path.
Your guarded route now requires authorization, applicable approval, constrained execution, and writable audit logging. Each stage has a distinct security responsibility.
- Route successful results from Create audit event back to Claude Desktop.
- Remove every line that allows Claude Desktop, evidence storage, or findings storage to reach the constrained executor directly.
That closes the visible bypass. Every permitted execution route now passes through trusted controls before results return to Claude Desktop.
Still See a Bypass Route?
- Check every line entering the constrained executor for a connection from the policy decision or exact-action approval gate.
- Move the result-return line so it begins after successful audit-event creation.
- Keep GAP-01 visible only as a labeled historical route.
If the paths are difficult to separate, help me review the guarded route in my data-flow diagram.
Constrain the future executor
The constrained executor applies least privilege to the tools that may run later. Treat Docker as one containment boundary whose strength depends on mounts, credentials, network access, and process limits.
- Add a Constrained executor controls section to threat-model.md.
- Add a control note requiring security tools to run inside Docker isolation.
The design now gives tool execution its own containment boundary. This limits the environment available to a future security tool.
- Require the minimum filesystem mounts needed for the approved action.
- Require read-only mounts wherever the tool only needs to read.
Your filesystem notes should now limit both the number of exposed paths and the access allowed through each mount.
- Prohibit inherited broad credentials inside the constrained executor.
- Restrict outbound network access to known destinations required by the approved action.
The executor can now access only scoped credentials and expected network destinations. Compromised tool behavior has fewer places to reach.
- Require strict input and output schemas for every exposed tool.
- Require a timeout for every tool invocation.
The design now rejects malformed tool data and limits how long an invocation can consume resources.
- Add rate limits for repeated tool invocations.
- Save threat-model.md with Ctrl+S.
Your control notes now cover isolation, filesystem exposure, credentials, network destinations, schemas, timeouts, and invocation rates.
Why Isolation Needs Constraints
Docker supplies a process boundary, while bind mounts can expose host files to the container. Read-only mounts prevent writes through paths that only need read access.
Scoped credentials and known network destinations reduce the damage available to a compromised tool. The boundary becomes useful because each permission is deliberately limited.
Add fail-closed acceptance cases
A fail-closed policy blocks execution whenever a required security decision cannot be completed safely. Acceptance cases turn that principle into outcomes that future implementation tests can verify.
- Add a Fail-closed acceptance cases section to threat-model.md.
- Add an unknown-target case whose expected decision is DENY.
The first case proves that missing target authorization stops the route before execution.
- Add a stale or changed approval-parameters case whose expected decision is DENY.
- Add an unavailable-policy case whose expected decision is DENY.
These cases block approval reuse after an action changes. They also stop execution when the policy cannot return a trusted decision.
- Add an unavailable-audit-logging case whose expected decision is DENY.
- Add an unexpected-tool-name case whose expected decision is DENY.
The guarded route now refuses actions that cannot produce evidence and tools that the policy does not recognize.
- Add an instruction-like untrusted-content case that treats the content as evidence.
- Set its expected outcome to a safe analysis response or DENY with no executor invocation.
The final case keeps text found in scan evidence inside the untrusted-data boundary. Its instructions gain no authority over policy or tools.
- Switch back to decision-log.md from earlier.
- Append a decision stating that the guarded route replaces model-directed execution with deterministic authorization, parameter-bound approval, constrained Docker-isolated execution, and writable audit logging.
The decision log now preserves both halves of the design choice. It records why GAP-01 is unsafe and which trusted controls replace it.
- Save decision-log.md with Ctrl+S.
- Return to threat-model.md from earlier.
- Save threat-model.md with Ctrl+S.
Both files now preserve the corrected boundary and the reasoning behind it.
✔️ Awesome, I've got everything!
- Confirm threat-model.md is saved with the guarded route, constrained-executor controls, and fail-closed cases.
- Confirm decision-log.md is saved with the decision that replaces model-directed execution.
ⓧ I'd like to double check the full design
Compare your saved design against each requirement below.
- Confirm the diagram retains GAP-01 as the unsafe historical route.
- Confirm every permitted execution route passes through deterministic authorization and policy validation.
- Confirm approval-gated actions require approval bound to the actor, tool, target, and normalized parameters.
- Confirm the route passes through a constrained executor and successful audit-event creation before results return to Claude Desktop.
- Confirm the control notes require Docker isolation, minimum filesystem mounts, read-only mounts where possible, no inherited broad credentials, known network destinations, strict schemas, timeouts, and rate limits.
- Confirm the fail-closed cases cover unknown targets, stale or changed approvals, unavailable policy, unavailable audit logging, unexpected tool names, and instruction-like untrusted content.
- Confirm decision-log.md records deterministic authorization, parameter-bound approval, constrained Docker-isolated execution, and writable audit logging as the replacement for model-directed execution.
Before you trace the corrected route, do you expect any path to reach the executor without exact authorization and writable audit logging?
- Begin an approval-gated validation request at the operator in your diagram.
- Follow the request into the authorization and policy decision point.
- Continue the request through the exact-action approval gate.
- Compare the approval record with the actor, tool, target, and normalized parameters.
- Continue the approved request into the constrained executor.
- Confirm the audit store accepts a writable event before following the result back to Claude Desktop.
You should find no route to the executor unless authorization is present, the approval matches the exact action, and the audit event can be written. That is the hard part solved: model intent no longer controls whether a tool runs.
Does Your Trace Still Bypass a Gate?
- Check for a line that reaches the constrained executor directly from Claude Desktop or evidence storage.
- Check that approval comparison happens before the constrained executor.
- Check that audit-event creation completes before results return to Claude Desktop.
If one of those paths is unclear, help me find the missing gate in my corrected security-boundary diagram.
Your security boundary now forces every permitted action through deterministic controls. Next, you will use STRIDE to test that corrected design for threats and residual risk.
Build the STRIDE Threat Register
Your guarded diagram now gives every execution path a deterministic route. That route reaches the executor only after trusted controls approve it.
Residual risk still exists at every trust boundary. A STRIDE register turns each concern into a prioritized record with mitigation and verification evidence.
In this step, get ready to:
- Create a threat register with consistent risk and evidence fields.
- Cover all six STRIDE categories across the corrected design.
- Record accepted residual risks with explicit review conditions.
Create the register structure
Each register row connects one threat to the part of the design it affects. Consistent columns make it possible to compare priorities before implementation begins.
How STRIDE Frames the Review
- Spoofing examines false identities or fabricated authorization evidence.
- Tampering examines unauthorized changes to data or tool behavior.
- Repudiation examines actions that cannot be tied to reliable records.
- Information disclosure examines exposure of secrets or sensitive findings.
- Denial of service examines failures that reduce availability.
- Elevation of privilege examines access beyond the permissions granted to a component.
- Select threat-model.md in the Explorer view from earlier.
- Add a level-2 heading named STRIDE Threat Register below the corrected diagram.
- Create a Markdown table below the heading with one header cell for ID, component or flow, STRIDE category, threat, pre-control priority, mitigation, verification evidence, residual priority, and status.
You should now see the register heading followed by a header row with nine named fields.
- Save threat-model.md by pressing Ctrl+S.
The register structure is now part of the saved threat model.
Populate all six STRIDE categories
The register needs threats from every major boundary in the corrected diagram. Each row below includes a priority before controls plus the risk that remains after those controls.
Threat Rows to Add
- The TM-01 row covers spoofed authorization in the authorization and policy flow. Its category is Spoofing. Its pre-control priority is High. A fail-closed policy independently validates the actor plus authorized target. Verification uses forged or missing authorization and confirms a DENY result with no executor invocation. Its residual priority is Low. Its status is Mitigated.
- The TM-02 row covers tampered evidence in the lab-to-evidence flow. Its category is Tampering. Its pre-control priority is High. The mitigation preserves provenance plus raw evidence while normalization and schemas detect changes. Verification confirms modified evidence is rejected or flagged while the original remains available for comparison. Its residual priority is Medium. Its status is Accepted.
- The TM-03 row covers repudiated approvals in the approval-to-execution flow. Its category is Repudiation. Its pre-control priority is High. The mitigation binds the approval record to the actor, tool, target, normalized parameters, timestamp, and expiry. Verification confirms the audit event contains the complete approval record for the executed action. Its residual priority is Low. Its status is Mitigated.
- The TM-04 row covers sensitive-data disclosure across evidence, findings, and audit storage. Its category is Information disclosure. Its pre-control priority is High. The mitigation excludes or redacts secrets while limiting mounts, credentials, and output fields. Verification confirms a harmless secret marker never appears in model context, findings, or audit output. Its residual priority is Low. Its status is Mitigated.
- The TM-05 row covers resource exhaustion in the constrained executor. Its category is Denial of service. Its pre-control priority is Medium. The mitigation applies timeouts plus rate limits to tool requests. Verification confirms repeated or oversized requests stop within the defined limits. Its residual priority is Medium. Its status is Accepted.
- The TM-06 row covers privilege escalation at the constrained executor and Docker boundary. Its category is Elevation of privilege. Its pre-control priority is High. The mitigation applies least privilege through minimum mounts, read-only access, narrow credentials, and known network destinations. Verification confirms blocked host writes plus blocked connections to unapproved destinations. Its residual priority is Low. Its status is Mitigated.
- The TM-07 row covers tool poisoning in the future local MCP server. Its category is Tampering. Its pre-control priority is High. The mitigation permits known tool names through strict input and output schemas. Verification confirms an unexpected tool name is denied before execution. Its residual priority is Low. Its status is Mitigated.
- The TM-08 row covers indirect prompt injection in the evidence-to-AI flow. Its category is Tampering. Its pre-control priority is High. The mitigation treats evidence as untrusted data while authorization remains outside model context. Verification confirms instruction-like evidence produces safe analysis or a denial with no executor invocation. Its residual priority is Low. Its status is Mitigated.
- The TM-09 row covers audit failure immediately before execution. Its category is Repudiation. Its pre-control priority is High. The mitigation requires a writable audit event before the executor can run. Verification confirms unavailable audit logging blocks invocation. Its residual priority is Low. Its status is Mitigated.
- Add the TM-01 through TM-03 rows to threat-model.md using the row blueprint.
- Save threat-model.md by pressing Ctrl+S.
The first three rows now cover false authorization, evidence integrity, and approval accountability.
- Add the TM-04 through TM-06 rows using the row blueprint.
- Save threat-model.md by pressing Ctrl+S.
The next three rows now cover data exposure, resource availability, and executor privilege.
- Add the TM-07 through TM-09 rows using the row blueprint.
- Save threat-model.md by pressing Ctrl+S.
Your register should now contain nine rows. The category column should include every STRIDE category at least once.
Prioritize residual risk and verify the register
A residual priority describes the exposure that remains after mitigation. Accepting that exposure requires a recorded rationale plus a condition that triggers another review.
Residual Risk Decisions to Record
TM-02 accepts a Medium chance that hostile evidence bypasses normalization. The local authorized-lab scope limits the exposure.
Revisit TM-02 if evidence can come from outside the authorized lab.
TM-05 accepts Medium local resource contention after timeouts and rate limits. The single-operator scope limits the impact.
Revisit TM-05 if concurrent, background, or multi-user execution is introduced.
- Select decision-log.md in the Explorer view from earlier.
- Add a level-2 heading named Accepted Residual Risks below the existing GAP-01 decisions.
- Record the accepted TM-02 risk with its rationale and review condition.
The first acceptance should now explain why the remaining risk is tolerable within the authorized-lab scope.
- Record the accepted TM-05 risk with its rationale and review condition.
- Save decision-log.md by pressing Ctrl+S.
The decision log should now connect both accepted risks to the condition that forces a future review.
Before you review the files, do you expect any High row to pass without both a mitigation and verification check?
- Switch back to threat-model.md from earlier.
- Confirm the register contains all nine required columns.
- Confirm the category column contains all six STRIDE categories.
- Review every High row for a mitigation and verification check.
- Compare the Accepted rows with the residual-risk decisions in decision-log.md.
The register should contain every STRIDE category. Every High row should include mitigation and verification evidence.
TM-02 and TM-05 should be the only accepted residual risks. Each should have a rationale plus an explicit review condition in decision-log.md.
That closes the systematic review. Every high-priority threat now points to a control that future implementation work can prove.
✔️ Awesome, I've got everything!
Your checkpoint is complete when the threat register and residual-risk decisions are saved in their existing files.
ⓧ I'd like to double check the full code
The cumulative design artifacts should match this state.
- The frankly-cyberops-design folder remains open as the local workspace.
- The saved security-charter.md still defines authorized use, denied behavior, human approval, untrusted evidence handling, and fail-closed decisions.
- The saved threat-model.md still contains the corrected guarded data-flow diagram plus its deterministic authorization, approval, isolation, and audit controls.
- The saved threat-model.md now also contains a nine-column STRIDE register covering spoofed authorization, tampered evidence, repudiated approvals, sensitive-data disclosure, resource exhaustion, privilege escalation, tool poisoning, indirect prompt injection, and audit failure.
- All six STRIDE categories appear in the register. Every High row contains a mitigation and verification check.
- The saved decision-log.md retains the GAP-01 decisions plus each accepted residual risk, its rationale, and its review condition.
Secret mission
Defeat an Indirect Prompt Injection
A hostile scan result tries to override policy with an out-of-scope tool request. Trace it through your guarded design to prove the executor receives no invocation.
Clean Up Your Resources
Clean Up Your Resources
All three design files live inside one local folder. This project created no cloud resources or ongoing costs.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- The local frankly-cyberops-design folder containing security-charter.md, threat-model.md, and decision-log.md.
Keep everything running
No action is needed. Choose this if you want to carry the design authority into the next project in Visual Studio Code.
- Leave the frankly-cyberops-design folder unchanged as the security contract for the next project.
Pause - I'll come back to this later
Pausing closes the editor while preserving every design decision. No background process needs to be stopped.
- Close the Visual Studio Code window.
- Leave the frankly-cyberops-design folder in its current location.
Your charter, guarded data-flow diagram, STRIDE register, and prompt-injection abuse case remain ready for the architecture phase.
Delete - I don't want to use this again
Deleting this folder permanently removes all three design files. Your installed tools remain untouched.
Windows may ask you to confirm the permanent deletion.
- Close the Visual Studio Code window.
- Use the Windows file browser to return to the location where you created the workspace.
- Select the frankly-cyberops-design folder.
- Press Shift+Delete to permanently delete the selected folder.
- Confirm the deletion if Windows asks.
- Return to the folder's original location.
You should no longer see the frankly-cyberops-design folder or any of its three design files.
Nice Work!
Nice Work!
You did it! You created an implementation-ready security boundary for Frankly CyberOps before giving the assistant any executable capability.
What you learned:
- Defined an authorized-use charter that classifies requests as permitted, approval-gated, or denied. Its fail-closed rules preserve human authority when authorization, policy, approval, or audit state is unavailable.
- Mapped attacker-controlled evidence across a level-0 data-flow diagram. Replaced GAP-01 with deterministic gates for authorization, exact-action approval, constrained execution, and audit logging.
- Built a prioritized STRIDE threat register covering all six categories. Every High-priority threat now has a mitigation plus a verification check. Accepted residual risks include explicit revisit conditions.
- Secret Mission: Proved that an indirect prompt injection hidden in scan evidence remains untrusted data. The abuse case ends with a logged denial or safe analysis response. Its evidence proves no executor invocation occurred.
Ready to quiz yourself?