Make aspex scan enforce your team’s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.
Three features turn aspex scan from a scanner a developer runs into a control a security team owns.
Problem
Feature
A finding you have consciously accepted keeps failing CI
.aspex.yaml ignore - accept a risk with a reason and an expiry
The default severities are not your severities
.aspex.yaml severity - promote, demote, or disable any rule
90 findings on day one, and you cannot fix them all before enabling the gate
Baseline - hide pre-existing findings, fail only on new ones
30 risky servers, and you do not know which to fix first
--with-trace - rank by static risk x observed use
Policy file: .aspex.yaml
aspex scan init # writes a starter .aspex.yaml in the current directory
aspex scan looks for ./.aspex.yaml, then ~/.config/aspex/config.yaml. Pass --config <path> to use a specific file. Commit the project-local file so the whole team and CI share one policy.
# Accept a specific risk. Every entry needs a reason.# Add an expiry so accepted risks get re-reviewed instead of forgotten.ignore: - rule: MCP004 server: filesystem reason: "Intentionally scoped to ~/projects for the monorepo" expires: 2027-01-01 - rule: MCP026 server: "internal-*" # globs match server names reason: "Our internal servers expose many tools by design"# Your severity for a rule. "off" disables it entirely.severity: MCP021: critical # plaintext HTTP is never acceptable here MCP026: low# Default gate when --fail-on is not passed on the command line.fail_on: high
Rules:
reason is required. A policy file with an unexplained ignore is rejected.
server is optional. Omit it to ignore a rule everywhere; use a glob like internal-* for a group.
An expired ignore stops suppressing and prints a warning, so the finding comes back into view instead of being silently forgotten.
Severity overrides are applied before scoring and before the --fail-on gate. Your score and your CI result reflect your policy, not the defaults.
Suppressed findings are always listed at the end of the report and in --json output under suppressed, so a clean run is never mistaken for “nothing found”.Attack paths (AP001…AP006, see Capabilities and attack paths) are governed the same way: - rule: AP003 with a reason accepts a path, optionally scoped with server: to one of the servers on it. Baselines record paths too, so --baseline hides pre-existing compositions and only new ones fail the gate.
Baseline: adopt on an existing estate
Turning on --fail-on high against 30 servers with 90 existing findings fails forever. A baseline snapshots what exists today so only new findings fail the gate, then you burn the baseline down at your own pace.
# Day one: snapshot the current stateaspex scan --save-baseline aspex-baseline.json# From then on: only new findings are shown and gatedaspex scan --baseline aspex-baseline.json --fail-on high
Commit aspex-baseline.json. Re-run --save-baseline after you fix things to shrink it. Findings are keyed by server and rule ID, so the same rule appearing on a new server is correctly treated as new.
Use --baseline for the transition and .aspex.yaml ignores for permanent, explained decisions. A baseline entry means “not yet”; an ignore entry means “we decided”.
Prioritize with --with-trace
aspex scan knows what a server can do. aspex trace knows what your agents did. --with-trace joins them:
aspex scan --with-trace # last 7 days of agent activityaspex scan --with-trace --trace-since 30d
◆ Observed activity last 7d, from aspex trace logs postgres CRITICAL 340 calls · 3 tools 12 flagged (critical) filesystem CRITICAL 88 calls · 6 tools github HIGH not seen memory clean 41 calls · 4 tools ▲ Prioritize - risky AND in active use: CRITICAL postgres 340 calls, tools: execute_sql, list_tables, describe_table CRITICAL filesystem 88 calls, tools: read_file, write_file, ...
A critical server that was never invoked is a latent risk: remove it or scope it down. The same server invoked 340 times last week, twelve of them tripping a trace rule, is the one to fix today. The Prioritize list is servers with a HIGH or CRITICAL static finding and observed calls in the window.--json output includes the per-server activity under activity.
CI example
- uses: aspex-security/aspex/.github/actions/aspex-scan-action@main with: fail-on: high# .aspex.yaml and aspex-baseline.json are read from the checked-out repo.
Detection contract
Aspex ships a corpus of known-malicious and known-benign MCP servers under testdata/corpus/. Every malicious fixture declares the rule IDs that must fire; every benign fixture (real, popular servers such as the official filesystem, GitHub, Slack, and fetch servers) declares the highest severity Aspex may report. CI runs both on every change, so a rule cannot regress detection or start crying wolf on a server people actually use. Contributing a fixture is the highest-signal way to improve Aspex: see CONTRIBUTING.md.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Aspex","colors":{"primary":"#ec3013","light":"#ff9783","dark":"#ae1800"},"logo":{"light":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/light.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=291ecea15a099f8047decc0604202c15","dark":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/dark.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=cbccbbea1c0bc688e22550711e3590f0","href":"/introduction"},"favicon":"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/favicon.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=a76f00414e8ed34f1441b09d2bfaa544","navbar":{"links":[{"href":"https://github.com/aspex-security/aspex","label":"GitHub"},{"href":"https://github.com/aspex-security/aspex/blob/main/CHANGELOG.md","label":"Changelog"}],"primary":{"type":"button","label":"Install","href":"/install"}},"footer":{"socials":{"github":"https://github.com/aspex-security/aspex"}},"fonts":{"family":"Archivo"},"styling":{"eyebrows":"section","codeblocks":"dark","latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"aspex","hasAudioNarration":false,"actualSubdomain":"aspex","customDomains":[],"gitSource":{"type":"github","owner":"aspex-security","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6aa7ebb78a94481b048c0895","clientVersion":"0.0.4143","searchFilterCounts":[{"language":"default","tag":"Commands","count":13},{"language":"default","tag":"Concepts","count":4},{"language":"default","tag":"Guides","count":4},{"language":"default","tag":"Start","count":4},{"language":"default","tag":"Reference","count":4}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":":root{--aspex-ink: #201e1d;--aspex-ground: #f3f2f2;--aspex-surface: #eae9e9;--aspex-accent: #ec3013;--aspex-accent-deep: #ae1800;--aspex-divider: rgba(32, 30, 29, 0.4)}#content-area *,#sidebar *,#navbar *,#topbar *,.prose *{border-radius:0!important}html:not(.dark) body,html:not(.dark) #navbar,html:not(.dark) #sidebar{background:var(--aspex-ground)}html.dark{--aspex-ink: #f3f2f2;--aspex-ground: #201e1d;--aspex-surface: #2c2a29;--aspex-divider: rgba(243, 242, 242, 0.35)}#navbar,#topbar{border-bottom:2px solid var(--aspex-divider)!important}#sidebar{border-right:2px solid var(--aspex-divider)!important}.prose hr{height:2px;border:0;background:var(--aspex-divider)}.prose h1{font-weight:800;letter-spacing:-0.02em;line-height:1.08}.prose h2{font-weight:800;letter-spacing:-0.015em}.prose h3,.prose h4{font-weight:800}#sidebar h5,.eyebrow,[class*=\"eyebrow\"]{font-size:11px;letter-spacing:0.08em;text-transform:uppercase;font-weight:600}#sidebar a,#sidebar li a{border-left:2px solid transparent;padding-left:12px}#sidebar a[aria-current=\"page\"],#sidebar li.active>a{border-left-color:var(--aspex-accent)!important;background:transparent!important;color:var(--aspex-ink)!important;font-weight:600}#navbar a[href=\"/install\"],.prose a.button-primary{background:var(--aspex-accent)!important;color:var(--aspex-ground)!important;font-weight:800;justify-content:flex-start}#navbar a[href=\"/install\"]:hover{background:#dd2b0f!important}.prose pre,[class*=\"codeblock\"] pre{background:#201e1d!important;border-top:2px solid var(--aspex-accent)}.prose :not(pre)>code,[class*=\"card\"] code{background:var(--aspex-surface);color:var(--aspex-ink);padding:2px 6px;font-size:0.9em}.prose table th{font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:rgba(32, 30, 29, 0.6);border-bottom:2px solid var(--aspex-divider)}html.dark .prose table th{color:rgba(243, 242, 242, 0.6)}.prose table td{border-bottom:1px solid var(--aspex-divider)}.prose table tr:nth-child(2n) td{background:transparent}.prose .card,[class*=\"card\"]{border:2px solid var(--aspex-divider)!important;box-shadow:none!important}.prose .card:hover{background:var(--aspex-surface)}.callout,[class*=\"callout\"]{border-left:2px solid var(--aspex-accent)!important;background:transparent!important}[class*=\"step-indicator\"]{background:var(--aspex-ink)!important;color:var(--aspex-ground)!important;font-weight:800}:focus-visible{outline:2px solid var(--aspex-accent);outline-offset:2px}::selection{background:rgba(236, 48, 19, 0.3)}.prose a{color:var(--aspex-accent-deep);text-underline-offset:3px}html.dark .prose a{color:var(--aspex-light, #ff9783)}html.dark #sidebar a[aria-current=\"page\"],html.dark #sidebar li.active>a{color:var(--aspex-ink)!important}"}],"page":{"pagePath":"guides/policy","slug":"/guides/policy","pageMetadata":{"title":"Policy, baselines and prioritization","description":"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.","href":"/guides/policy"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Make aspex scan enforce your team’s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Tip}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Three features turn `,_jsx(_components.code,{children:`aspex scan`}),` from a scanner a developer runs into a control a security team owns.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Problem`}),_jsx(_components.th,{children:`Feature`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A finding you have consciously accepted keeps failing CI`}),_jsxs(_components.td,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`.aspex.yaml`}),` ignore`]}),` - accept a risk with a reason and an expiry`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The default severities are not your severities`}),_jsxs(_components.td,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`.aspex.yaml`}),` severity`]}),` - promote, demote, or disable any rule`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`90 findings on day one, and you cannot fix them all before enabling the gate`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Baseline`}),` - hide pre-existing findings, fail only on new ones`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`30 risky servers, and you do not know which to fix first`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`--with-trace`})}),` - rank by static risk x observed use`]})]})]})]}),`\n`,_jsxs(Heading,{level:`2`,id:`policy-file-aspex-yaml`,children:[`Policy file: `,_jsx(_components.code,{children:`.aspex.yaml`})]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` init`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # writes a starter .aspex.yaml in the current directory`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`aspex scan`}),` looks for `,_jsx(_components.code,{children:`./.aspex.yaml`}),`, then `,_jsx(_components.code,{children:`~/.config/aspex/config.yaml`}),`. Pass `,_jsx(_components.code,{children:`--config \u003cpath>`}),` to use a specific file. Commit the project-local file so the whole team and CI share one policy.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`18`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`18`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Accept a specific risk. Every entry needs a reason.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Add an expiry so accepted risks get re-reviewed instead of forgotten.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`ignore`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`rule`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`MCP004`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` server`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`filesystem`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` reason`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"Intentionally scoped to ~/projects for the monorepo\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` expires`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: 2027-01-01`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`rule`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`MCP026`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` server`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"internal-*\"`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # globs match server names`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` reason`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`\"Our internal servers expose many tools by design\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Your severity for a rule. \"off\" disables it entirely.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`severity`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` MCP021`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`critical`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # plaintext HTTP is never acceptable here`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` MCP026`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`low`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Default gate when --fail-on is not passed on the command line.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`fail_on`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`high`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Rules:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`reason`}),` is required. A policy file with an unexplained ignore is rejected.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`server`}),` is optional. Omit it to ignore a rule everywhere; use a glob like `,_jsx(_components.code,{children:`internal-*`}),` for a group.`]}),`\n`,_jsx(_components.li,{children:`An expired ignore stops suppressing and prints a warning, so the finding comes back into view instead of being silently forgotten.`}),`\n`,_jsxs(_components.li,{children:[`Severity overrides are applied `,_jsx(_components.strong,{children:`before`}),` scoring and `,_jsx(_components.strong,{children:`before`}),` the `,_jsx(_components.code,{children:`--fail-on`}),` gate. Your score and your CI result reflect your policy, not the defaults.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Suppressed findings are always listed at the end of the report and in `,_jsx(_components.code,{children:`--json`}),` output under `,_jsx(_components.code,{children:`suppressed`}),`, so a clean run is never mistaken for “nothing found”.`]}),`\n`,_jsxs(_components.p,{children:[`Attack paths (`,_jsx(_components.code,{children:`AP001`}),`…`,_jsx(_components.code,{children:`AP006`}),`, see `,_jsx(_components.a,{href:`/concepts/capabilities-and-attack-paths`,children:`Capabilities and attack paths`}),`) are governed the same way: `,_jsx(_components.code,{children:`- rule: AP003`}),` with a `,_jsx(_components.code,{children:`reason`}),` accepts a path, optionally scoped with `,_jsx(_components.code,{children:`server:`}),` to one of the servers on it. Baselines record paths too, so `,_jsx(_components.code,{children:`--baseline`}),` hides pre-existing compositions and only new ones fail the gate.`]}),`\n`,_jsx(Heading,{level:`2`,id:`baseline-adopt-on-an-existing-estate`,children:`Baseline: adopt on an existing estate`}),`\n`,_jsxs(_components.p,{children:[`Turning on `,_jsx(_components.code,{children:`--fail-on high`}),` against 30 servers with 90 existing findings fails forever. A baseline snapshots what exists today so only `,_jsx(_components.strong,{children:`new`}),` findings fail the gate, then you burn the baseline down at your own pace.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# Day one: snapshot the current state`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --save-baseline`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` aspex-baseline.json`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# From then on: only new findings are shown and gated`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --baseline`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` aspex-baseline.json`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --fail-on`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` high`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Commit `,_jsx(_components.code,{children:`aspex-baseline.json`}),`. Re-run `,_jsx(_components.code,{children:`--save-baseline`}),` after you fix things to shrink it. Findings are keyed by server and rule ID, so the same rule appearing on a new server is correctly treated as new.`]}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`--baseline`}),` for the transition and `,_jsx(_components.code,{children:`.aspex.yaml`}),` ignores for permanent, explained decisions. A baseline entry means “not yet”; an ignore entry means “we decided”.`]})}),`\n`,_jsxs(Heading,{level:`2`,id:`prioritize-with-with-trace`,children:[`Prioritize with `,_jsx(_components.code,{children:`--with-trace`})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`aspex scan`}),` knows what a server `,_jsx(_components.strong,{children:`can`}),` do. `,_jsx(_components.code,{children:`aspex trace`}),` knows what your agents `,_jsx(_components.strong,{children:`did`}),`. `,_jsx(_components.code,{children:`--with-trace`}),` joins them:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --with-trace`}),_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:` # last 7 days of agent activity`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#DCDCAA`,\"--shiki-dark\":`#DCDCAA`},children:`aspex`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` scan`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --with-trace`}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` --trace-since`}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:` 30d`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{numberOfLines:`11`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ◆ Observed activity last 7d, from aspex trace logs`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` postgres CRITICAL 340 calls · 3 tools 12 flagged (critical)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` filesystem CRITICAL 88 calls · 6 tools`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` github HIGH not seen`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` memory clean 41 calls · 4 tools`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` ▲ Prioritize - risky AND in active use:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CRITICAL postgres 340 calls, tools: execute_sql, list_tables, describe_table`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:` CRITICAL filesystem 88 calls, tools: read_file, write_file, ...`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsxs(_components.p,{children:[`A critical server that was never invoked is a latent risk: remove it or scope it down. The same server invoked 340 times last week, twelve of them tripping a trace rule, is the one to fix today. The `,_jsx(_components.code,{children:`Prioritize`}),` list is servers with a HIGH or CRITICAL static finding `,_jsx(_components.strong,{children:`and`}),` observed calls in the window.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`--json`}),` output includes the per-server activity under `,_jsx(_components.code,{children:`activity`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`ci-example`,children:`CI example`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes dark-plus dark-plus`,style:{backgroundColor:`#0B0C0E`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:`uses`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`aspex-security/aspex/.github/actions/aspex-scan-action@main`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` with`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#569CD6`,\"--shiki-dark\":`#569CD6`},children:` fail-on`}),_jsx(_components.span,{style:{color:`#D4D4D4`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#CE9178`,\"--shiki-dark\":`#CE9178`},children:`high`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A9955`,\"--shiki-dark\":`#6A9955`},children:`# .aspex.yaml and aspex-baseline.json are read from the checked-out repo.`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`detection-contract`,children:`Detection contract`}),`\n`,_jsxs(_components.p,{children:[`Aspex ships a corpus of known-malicious and known-benign MCP servers under `,_jsx(_components.code,{children:`testdata/corpus/`}),`. Every malicious fixture declares the rule IDs that must fire; every benign fixture (real, popular servers such as the official filesystem, GitHub, Slack, and fetch servers) declares the highest severity Aspex may report. CI runs both on every change, so a rule cannot regress detection or start crying wolf on a server people actually use. Contributing a fixture is the highest-signal way to improve Aspex: see `,_jsx(_components.a,{href:`https://github.com/aspex-security/aspex/blob/main/CONTRIBUTING.md`,children:`CONTRIBUTING.md`}),`.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"dark","config":{},"pageMetadata":{"title":"Policy, baselines and prioritization","description":"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.","href":"/guides/policy"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Policy file: .aspex.yaml","slug":"policy-file-aspex-yaml","depth":2,"children":[]},{"title":"Baseline: adopt on an existing estate","slug":"baseline-adopt-on-an-existing-estate","depth":2,"children":[]},{"title":"Prioritize with --with-trace","slug":"prioritize-with-with-trace","depth":2,"children":[]},{"title":"CI example","slug":"ci-example","depth":2,"children":[]},{"title":"Detection contract","slug":"detection-contract","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"aspex","siteName":"Aspex","title":"Policy, baselines and prioritization - Aspex","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-09-11T11:35:37.110Z","originalFileLocation":"guides/policy.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Aspex\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Policy, baselines and prioritization - Aspex\">\u003cmeta data-mint-head property=\"og:description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Aspex\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://aspex.mintlify.app/guides/policy\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://aspex.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Policy%2C+baselines+and+prioritization\u0026amp;description=Make+aspex+scan+enforce+your+team%27s+rules%2C+adopt+it+on+an+estate+with+existing+findings%2C+and+fix+the+risky+servers+that+are+actually+in+use+first.\u0026amp;theme=a3815f0eddddc599c27011b4\u0026amp;signature=e62d9f8fedee01b73c709bf2e199b5c6a2413da738c0272e81eff9ebbc7efb7d\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Policy, baselines and prioritization - Aspex\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Make aspex scan enforce your team\u0026#x27;s rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://aspex.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Policy%2C+baselines+and+prioritization\u0026amp;description=Make+aspex+scan+enforce+your+team%27s+rules%2C+adopt+it+on+an+estate+with+existing+findings%2C+and+fix+the+risky+servers+that+are+actually+in+use+first.\u0026amp;theme=a3815f0eddddc599c27011b4\u0026amp;signature=e62d9f8fedee01b73c709bf2e199b5c6a2413da738c0272e81eff9ebbc7efb7d\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/aspex/QVudd8SD-Ga_PaCT/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Aspex\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#ec3013\">\u003clink data-mint-head rel=\"canonical\" href=\"https://aspex.mintlify.app/guides/policy\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/policy.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://aspex.mintlify.app/#organization\",\"name\":\"Aspex\",\"url\":\"https://aspex.mintlify.app\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/aspex/AsYxeTAcjauo5hC7/logo/light.svg?fit=max\u0026auto=format\u0026n=AsYxeTAcjauo5hC7\u0026q=85\u0026s=291ecea15a099f8047decc0604202c15\"}},{\"@type\":\"WebSite\",\"@id\":\"https://aspex.mintlify.app#website\",\"name\":\"Aspex\",\"url\":\"https://aspex.mintlify.app\",\"publisher\":{\"@id\":\"https://aspex.mintlify.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://aspex.mintlify.app/guides/policy#webpage\",\"url\":\"https://aspex.mintlify.app/guides/policy\",\"name\":\"Policy, baselines and prioritization\",\"description\":\"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\",\"dateModified\":\"2026-09-11T11:35:37.110Z\",\"isPartOf\":{\"@id\":\"https://aspex.mintlify.app#website\"},\"breadcrumb\":{\"@id\":\"https://aspex.mintlify.app/guides/policy#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://aspex.mintlify.app/guides/policy#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://aspex.mintlify.app/guides/daily-workflow\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Policy, baselines and prioritization\",\"item\":\"https://aspex.mintlify.app/guides/policy\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://aspex.mintlify.app/guides/policy#article\",\"headline\":\"Policy, baselines and prioritization\",\"name\":\"Policy, baselines and prioritization\",\"description\":\"Make aspex scan enforce your team's rules, adopt it on an estate with existing findings, and fix the risky servers that are actually in use first.\",\"url\":\"https://aspex.mintlify.app/guides/policy\",\"mainEntityOfPage\":{\"@id\":\"https://aspex.mintlify.app/guides/policy#webpage\"},\"dateModified\":\"2026-09-11T11:35:37.110Z\",\"publisher\":{\"@id\":\"https://aspex.mintlify.app/#organization\"},\"isPartOf\":{\"@id\":\"https://aspex.mintlify.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Aspex\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Aspex\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/guides/policy.md","siteName":"Aspex","nav":{"global":null,"groups":[{"group":"Start","pages":[{"title":"Know what your agents can do. Know what they actually did.","sidebarTitle":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"Common workflows","href":"/guides/common-workflows"},{"title":"Install","href":"/install"}]},{"group":"Concepts","pages":[{"title":"How Aspex reasons","href":"/concepts/how-aspex-reasons"},{"title":"Capabilities and attack paths","href":"/concepts/capabilities-and-attack-paths"},{"title":"Observed vs inferred","href":"/concepts/observed-vs-inferred"},{"title":"Score and blast radius","href":"/concepts/score-and-blast-radius"}]},{"group":"Commands","pages":[{"title":"aspex (front door)","href":"/tools/launcher"},{"title":"aspex scan","href":"/tools/scan"},{"title":"scan subcommands","href":"/tools/scan-subcommands"},{"title":"aspex trace","href":"/tools/trace"},{"title":"aspex explain","href":"/tools/explain"},{"title":"aspex simulate","href":"/tools/simulate"},{"title":"lock, verify, diff","href":"/tools/change-detection"},{"title":"aspex explore","href":"/tools/explore"},{"title":"aspex tighten","href":"/tools/tighten"},{"title":"aspex bom","href":"/tools/bom"},{"title":"aspex mcp","href":"/tools/mcp"},{"title":"aspex doctor","href":"/tools/doctor"},{"title":"aspex-attack","href":"/tools/attack"}]},{"group":"Guides","pages":[{"title":"Daily Workflow","href":"/guides/daily-workflow"},{"title":"CI integration","description":"Fail the build when a config change introduces a risky MCP server. GitHub Actions, SARIF, baselines, and the pre-commit hook.","href":"/guides/ci-integration"},{"title":"Policy, baselines and prioritization","href":"/guides/policy"},{"title":"VS Code and Cursor","description":"aspex scan findings as editor diagnostics, plus the SARIF viewer and pre-commit hook routes that work today.","href":"/guides/vscode"}]},{"group":"Reference","pages":[{"title":"Rules","href":"/reference/rules"},{"title":"Supported Clients","href":"/reference/clients"},{"title":"Agent Security Corpus","href":"/reference/corpus"},{"title":"Privacy","href":"/privacy"}]}]},"basePath":"","title":"Policy, baselines and prioritization - Aspex","buildId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","deploymentId":"dpl_Fyv1NbzwP68g2bEH2Roy98uY1zmE","dynamics":[],"chunks":[]}