On-Chain Monitoring Plan Template (Builders)
This template turns a completed threat model into an operational monitoring plan for a protocol or set of smart contracts on Stellar. Where the threat model asks: "What could go wrong and how will we design against it?", this plan asks "How will we watch for it in production?" Each threat you identified becomes one or more observable on-chain effects, and each effect becomes a rule your monitoring solution watches while your contracts are live.
Directions: fill out each section below to the best of your ability. Carry your threat identifiers over from your STRIDE threat model so the two documents stay linked. Work through the sections in order; every threat should leave the exercise with at least one monitor and a defined response.
Keep completed plans internal. A filled-in monitoring plan is a map of what you do — and don't — watch for. Publish the blank template; treat a populated version as sensitive.
What are we monitoring?
Directions: describe the system in scope, then inventory the components and on-chain addresses this plan covers.
Input text: high-level description of the protocol, the value it holds, and the parts of it this plan covers.
| Component | On-chain address (C... contract / G... account) | Notes |
|---|---|---|
| e.g. Lending pool core | C... | Holds pooled collateral and debt |
Note: keep this inventory current. Addresses can change with new versions, and an out-of-date address list is the most common reason a monitor silently stops working. If it's discovered later that scope has changed, update this section with the latest information.
What could go wrong?
Directions: list the threats this plan monitors, carried over from your threat model. Reuse the identifiers from your STRIDE model (for example, Elevation.1) so each monitor traces back to a known threat. Assign each threat a severity using the reminders below.
Severity reminders
| Severity | Meaning |
|---|---|
| Critical | Direct, large-scale loss of funds or control; requires immediate response. |
| High | Serious impact to funds, users, or availability; requires prompt response. |
| Medium | Limited or containable impact; response can be scheduled. |
| Low | Minor or informational; monitored for awareness. |
Threat register
| Threat ID | Threat (from threat model) | Affected component | Severity |
|---|---|---|---|
| Elevation.1 | Unauthorized change of contract admin/owner | Lending pool core — access control | Critical |
What does exploitation look like on-chain?
Directions: for each threat, describe how exploitation might unfold and the observable on-chain effect(s) it would leave behind. There can be several scenarios, and several effects, per threat.
| Threat ID | Exploitation scenario | Observable on-chain effect(s) |
|---|---|---|
| Elevation.1 | A leaked admin key reassigns ownership, then raises borrow caps and drains reserves. | set_admin / ownership-transfer event; privileged parameter change from a non-allowlisted caller |
If a threat has no observable on-chain effect (for example, a compromised frontend or an oracle's upstream data source), record it here and plan to monitor it off-chain — don't drop it just because it isn't visible on-chain.
What will we monitor for?
Directions: map each observable effect to a monitoring rule, stating the trigger condition and the baseline that makes it meaningful. Uniquely identify each monitor as <ThreatID>.M.<n> so it traces back to its threat — the same way remediations in your threat model are identified as <ThreatID>.R.<n>.
| Monitor ID | Observable on-chain effect | Trigger condition & baseline | Monitoring rule (plain-language intent) |
|---|---|---|---|
| Elevation.1.M.1 | Owner/admin address changes | Any set_admin event. Baseline: zero — never expected in normal operation. | Alert immediately on any admin change on the core contract. |
| Elevation.1.M.2 | Privileged call from an unexpected address | Caller not in the known-admin allowlist. Baseline: only the multisig calls these. | Alert on privileged calls from non-allowlisted addresses. |
Each monitor can be stated in a single line:
- We address [Threat ID] in [affected component] by monitoring for [on-chain effect] on [address].
- For example: Elevation.1.M.1 - We address Elevation.1 in the lending pool factory by monitoring for deploy invocations from users not on an approved list at address CABC123....
What happens when an alert fires?
Directions: for each monitor, define what happens when it triggers — who is notified, through which channel, any automated action, and who owns the rule. This is where your monitoring vendor's automated-response capability (for example, pausing a contract) is recorded.
| Monitor ID | Severity | Response / action (who, channel, automated action) | Owner | Status | Last reviewed |
|---|---|---|---|---|---|
| Elevation.1.M.1 | Critical | Page on-call security (PagerDuty + Slack); trigger guardian pause; open incident bridge. | Protocol Security | Active | YYYY-MM-DD |
Status values: Active (live and alerting), Tuning (live but thresholds being refined), Planned (agreed but not yet implemented).
Did we do a good job?
- Does every threat in your threat model have at least one monitor, or a documented reason it can't be monitored on-chain?
- Is every trigger threshold grounded in an actual baseline rather than a guess?
- Does every monitor have a defined response, an owner, and a status?
- Have any monitors fired? Were they true positives, and did the response work as written?
- Are all on-chain addresses still current after the latest deploy or upgrade?
- Were any threats found that only surface off-chain, needing a different kind of monitoring?
Treat this plan as a living document: revisit it whenever your contracts, addresses, or threat model change.