Rules

CLI

Cartography RunRules CLI

Execute security frameworks and present facts about your environment.

class cartography.rules.cli.OutputFormat(value)

Bases: str, Enum

Output format options.

__format__(format_spec)

Returns format using actual value type unless __str__ has been overridden.

cartography.rules.cli.complete_facts(ctx: Context, incomplete: str) Generator[tuple[str, str], None, None]

Autocomplete fact IDs with descriptions based on the selected rule.

Parameters:
  • ctx (typer.Context) – The Typer context containing parsed parameters.

  • incomplete (str) – The partial fact ID typed by the user.

Yields:

tuple[str, str] – A tuple of (fact_id, fact_name) for matching facts.

cartography.rules.cli.complete_frameworks(incomplete: str) Generator[str, None, None]

Autocomplete framework filters for CLI tab completion.

Supports formats: “CIS”, “CIS:aws”, “CIS:aws:5.0”

Parameters:

incomplete (str) – The partial framework filter typed by the user.

Yields:

str – Framework filter strings that start with the incomplete string.

cartography.rules.cli.complete_rules(incomplete: str) Generator[str, None, None]

Autocomplete rule names for CLI tab completion.

Parameters:

incomplete (str) – The partial rule name typed by the user.

Yields:

str – Rule names that start with the incomplete string.

cartography.rules.cli.complete_rules_with_all(incomplete: str) Generator[str, None, None]

Autocomplete rule names plus ‘all’ for CLI tab completion.

Parameters:

incomplete (str) – The partial rule name typed by the user.

Yields:

str – Rule names (plus ‘all’) that start with the incomplete string.

cartography.rules.cli.frameworks_cmd() None

List all compliance frameworks referenced by rules.

 .. admonition:: Examples

cartography-rules frameworks

cartography.rules.cli.list_cmd(rule: ~types.Annotated[str | None, <typer.models.ArgumentInfo object at 0x7fe2a3279570>] | None = None, framework: ~types.Annotated[str | None, <typer.models.OptionInfo object at 0x7fe2a3279e10>] | None = None) None

List available rules and facts.

 .. admonition:: Examples

cartography-rules list cartography-rules list –framework CIS cartography-rules list –framework CIS:aws cartography-rules list mfa-missing

cartography.rules.cli.main()

Entrypoint for the cartography-rules CLI.

This function initializes logging and launches the Typer application. It is the main entry point when running cartography-rules from the command line.

cartography.rules.cli.run_cmd(rule: ~types.Annotated[str | None, <typer.models.ArgumentInfo object at 0x7fe2a3279030>] | None = None, fact: ~types.Annotated[str | None, <typer.models.ArgumentInfo object at 0x7fe2a3279420>] | None = None, uri: ~typing.Annotated[str, <typer.models.OptionInfo object at 0x7fe2a3279c00>] = 'bolt://localhost:7687', user: ~typing.Annotated[str, <typer.models.OptionInfo object at 0x7fe2a327b970>] = 'neo4j', database: ~typing.Annotated[str, <typer.models.OptionInfo object at 0x7fe2a3279990>] = 'neo4j', neo4j_password_env_var: ~types.Annotated[str | None, <typer.models.OptionInfo object at 0x7fe2a3279d50>] | None = None, neo4j_password_prompt: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x7fe2a32793c0>] = False, output: ~cartography.rules.cli.Annotated[~cartography.rules.cli.OutputFormat, <typer.models.OptionInfo object at 0x7fe2a3279cc0>] = OutputFormat.text, experimental: bool = <typer.models.OptionInfo object>, framework: ~types.Annotated[str | None, <typer.models.OptionInfo object at 0x7fe2a3278e50>] | None = None) None

Execute a security framework.

 .. admonition:: Examples

cartography-rules run all cartography-rules run all –framework CIS cartography-rules run all –framework CIS:aws:5.0 cartography-rules run mfa-missing cartography-rules run mfa-missing missing-mfa-cloudflare

Runners

Framework and Fact execution logic for Cartography rules.

cartography.rules.runners.filter_rules_by_framework(rule_names: list[str], framework_filter: str) list[str]

Filter rules by framework specification.

The framework filter supports the following formats (case-insensitive): - “CIS” - Match any rule with a CIS framework - “CIS:aws” - Match CIS frameworks with scope “aws” - “CIS:aws:5.0” - Match CIS frameworks with scope “aws” and revision “5.0”

Parameters:
  • rule_names – List of rule names to filter.

  • framework_filter – Framework filter string.

Returns:

List of rule names that match the framework filter.

cartography.rules.runners.get_all_frameworks() dict[str, list[Framework]]

Get all unique frameworks from all rules, grouped by short_name.

Returns:

Dictionary mapping framework short_name to list of unique Framework objects.

cartography.rules.runners.run_rules(rule_names: list[str], uri: str, neo4j_user: str, neo4j_password: str, neo4j_database: str, output_format: str = 'text', fact_filter: str | None = None, exclude_experimental: bool = False, framework_filter: str | None = None)

Execute the specified rules and present results.

Parameters:
  • rule_names (list[str]) – The names of the rules to execute.

  • uri (str) – The URI of the Neo4j database. E.g. “bolt://localhost:7687” or “neo4j+s://tenant123.databases.neo4j.io:7687”

  • neo4j_user (str) – The username for the Neo4j database.

  • neo4j_password (str) – The password for the Neo4j database.

  • neo4j_database (str) – The name of the Neo4j database.

  • output_format (str) – Either “text” or “json”. Defaults to “text”.

  • fact_filter (str | None) – Optional fact ID to filter execution (case-insensitive).

  • exclude_experimental (bool) – Whether to exclude experimental facts from execution.

  • framework_filter (str | None) – Optional framework filter (e.g., “CIS”, “CIS:aws”, “CIS:aws:5.0”).

Returns:

The exit code (0 for success, 1 for failure).

Return type:

int

Formatters

Output formatting utilities for Cartography rules.

cartography.rules.formatters.to_serializable(obj)

Convert complex objects to JSON-serializable formats.

This function recursively converts Pydantic models, Enums, dataclasses, and nested structures to basic Python types that can be serialized to JSON.

Parameters:

obj – Any Python object to convert. Supports Pydantic BaseModel, Enum, dataclass, dict, list, tuple, set, and primitive types.

Returns:

A JSON-serializable representation of the input object.

Examples

>>> from pydantic import BaseModel
>>> class User(BaseModel):
...     name: str
...     age: int
>>> to_serializable(User(name="Alice", age=30))
{'name': 'Alice', 'age': 30}

Spec

class cartography.rules.spec.model.Fact(id: str, name: str, description: str, module: Module, maturity: Maturity, cypher_query: str, cypher_visual_query: str, cypher_count_query: str, asset_id_field: str | None = None)

Bases: object

A Fact gathers information about the environment using a Cypher query.

__init__(id: str, name: str, description: str, module: Module, maturity: Maturity, cypher_query: str, cypher_visual_query: str, cypher_count_query: str, asset_id_field: str | None = None) None
asset_id_field: str | None = None

The field name in the output model that uniquely identifies an asset. When set, failing count is computed as the count of distinct values of this field rather than the total number of finding rows. This is needed when a single asset can produce multiple finding rows (e.g., one security group with multiple violating rules).

cypher_count_query: str

A query that returns the total count of assets of the type being evaluated by this Fact. This count includes all assets regardless of whether they match the Fact criteria. Should return a single value with RETURN COUNT(…) AS count.

cypher_query: str

The Cypher query to gather information about the environment. Returns data field by field e.g. RETURN node.prop1, node.prop2.

cypher_visual_query: str

Same as cypher_query, returns it in a visual format for the web interface with .. RETURN *. Often includes additional relationships to help give context.

description: str

More details about the Fact. Information on details that we’re querying for.

id: str

A descriptive identifier for the Fact. By convention, should be lowercase and use underscores like rule-name-module.

maturity: Maturity

The maturity level of the Fact query.

module: Module

The Module that the Fact is associated with e.g. AWS, Azure, GCP, etc.

name: str

A descriptive name for the Fact.

class cartography.rules.spec.model.Finding(*, source: str | None = None, extra: dict[str, Any] = {})

Bases: BaseModel

Base class for Rule finding models.

extra: dict[str, Any]

A dictionary to hold any extra fields returned by the Fact query that are not explicitly defined in the output model.

model_config: ClassVar[ConfigDict] = {'coerce_numbers_to_str': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

source: str | None

The source of the Fact data, e.g. the specific Cartography module that ingested the data. This field is useful especially for CROSS_CLOUD facts.

class cartography.rules.spec.model.Framework(name: str, short_name: str, requirement: str, scope: str | None = None, revision: str | None = None)

Bases: object

A reference to a compliance framework requirement.

All fields are case-insensitive and normalized to lowercase on creation.

name

Full name of the framework (e.g., “cis aws foundations benchmark”).

Type:

str

short_name

Abbreviated name for filtering (e.g., “cis”).

Type:

str

requirement

The specific requirement identifier (e.g., “1.14”).

Type:

str

scope

Optional platform or domain the framework applies to (e.g., “aws”, “gcp”).

Type:

str | None

revision

Optional version/revision of the framework (e.g., “5.0”).

Type:

str | None

__init__(name: str, short_name: str, requirement: str, scope: str | None = None, revision: str | None = None) None
matches(short_name: str | None = None, scope: str | None = None, revision: str | None = None) bool

Check if this framework matches the given filter criteria.

Parameters:
  • short_name – Filter by short name (case-insensitive).

  • scope – Filter by scope (case-insensitive).

  • revision – Filter by revision (case-insensitive).

Returns:

True if all provided criteria match, False otherwise.

class cartography.rules.spec.model.Maturity(value)

Bases: str, Enum

Maturity levels for Facts.

__format__(format_spec)

Returns format using actual value type unless __str__ has been overridden.

EXPERIMENTAL = 'EXPERIMENTAL'

Initial version, may be unstable or incomplete.

Type:

Experimental

STABLE = 'STABLE'

Well-tested and reliable for production use.

Type:

Stable

class cartography.rules.spec.model.Module(value)

Bases: str, Enum

Services that can be monitored

__format__(format_spec)

Returns format using actual value type unless __str__ has been overridden.

AIRBYTE = 'Airbyte'

Airbyte data integration

ANTHROPIC = 'Anthropic'

Anthropic AI

AWS = 'AWS'

Amazon Web Services

AZURE = 'Azure'

Microsoft Azure

BIGFIX = 'BigFix'

BigFix patch management

CLOUDFLARE = 'Cloudflare'

Cloudflare services

CROSS_CLOUD = 'Cross-Cloud'

Multi-cloud or provider-agnostic rules

CROWDSTRIKE = 'CrowdStrike'

CrowdStrike endpoint security

DIGITALOCEAN = 'DigitalOcean'

DigitalOcean cloud services

DUO = 'Duo'

Duo authentication

ENTRA = 'Entra'

Entra identity and access management

GCP = 'GCP'

Google Cloud Platform

GITHUB = 'GitHub'

GitHub source code management

GOOGLEWORKSPACE = 'GoogleWorkspace'

Google Workspace identity and access management

JAMF = 'Jamf'

Jamf endpoint security

KANDJI = 'Kandji'

Kandji endpoint security

KEYCLOAK = 'Keycloak'

Keycloak identity and access management

KUBERNETES = 'Kubernetes'

Kubernetes cluster security

LASTPASS = 'LastPass'

LastPass password manager

OCI = 'OCI'

Oracle Cloud Infrastructure

OKTA = 'Okta'

Okta identity and access management

OPENAI = 'OpenAI'

OpenAI

PAGERDUTY = 'PagerDuty'

PagerDuty incident response

SCALEWAY = 'Scaleway'

Scaleway cloud services

SEMGREP = 'Semgrep'

Semgrep code security

SENTINELONE = 'SentinelOne'

SentinelOne endpoint security

SNIPEIT = 'Snipe-IT'

Snipe-IT asset management

SPACELIFT = 'SpaceLift'

SpaceLift infrastructure as code

TAILSCALE = 'TailScale'

TailScale VPN

TRIVY = 'Trivy'

Trivy vulnerability scanner

class cartography.rules.spec.model.Rule(id: str, name: str, tags: tuple[str, ...], description: str, version: str, facts: tuple[~cartography.rules.spec.model.Fact, ...], output_model: type[~cartography.rules.spec.model.Finding], references: list[~cartography.rules.spec.model.RuleReference] = <factory>, frameworks: tuple[~cartography.rules.spec.model.Framework, ...] = ())

Bases: object

A Rule represents a security issue or misconfiguration detected in the environment.

__init__(id: str, name: str, tags: tuple[str, ...], description: str, version: str, facts: tuple[~cartography.rules.spec.model.Fact, ...], output_model: type[~cartography.rules.spec.model.Finding], references: list[~cartography.rules.spec.model.RuleReference] = <factory>, frameworks: tuple[~cartography.rules.spec.model.Framework, ...] = ()) None
get_fact_by_id(fact_id: str) Fact | None

Returns a fact by its ID, or None if not found.

Parameters:

fact_id (str) – The ID of the Fact to find (case-insensitive).

Returns:

The matching Fact, or None if not found.

Return type:

Fact | None

has_framework(short_name: str | None = None, scope: str | None = None, revision: str | None = None) bool

Check if this rule has a framework matching the given criteria.

Parameters:
  • short_name – Filter by framework short name (case-insensitive).

  • scope – Filter by framework scope (case-insensitive).

  • revision – Filter by framework revision (case-insensitive).

Returns:

True if any framework matches all provided criteria.

parse_results(fact: Fact, fact_results: list[dict[str, Any]]) list[Finding]

Parse raw query results into typed Finding objects.

This method converts the raw dictionary results from a Cypher query into strongly-typed Finding objects using the Rule’s output_model. Fields not defined in the output model are stored in the extra dict.

Parameters:
  • fact (Fact) – The Fact that produced these results (used for source tracking).

  • fact_results (list[dict[str, Any]]) – Raw results from the Cypher query.

Returns:

A list of typed Finding objects.

Return type:

list[Finding]

description: str

A brief description of the Rule. Can include details about the security issue or misconfiguration.

facts: tuple[Fact, ...]

The Facts that contribute to this Rule.

frameworks: tuple[Framework, ...] = ()

Compliance frameworks this rule maps to (e.g., CIS benchmarks).

id: str

A unique identifier for the Rule. Should be globally unique within Cartography.

property modules: set[Module]

Returns the set of modules associated with this rule.

name: str

A brief name for the Rule.

output_model: type[Finding]

The output model class for the Rule.

references: list[RuleReference]

References or links to external resources related to the Rule.

tags: tuple[str, ...]

Tags associated with the Rule for categorization and filtering.

version: str

The version of the Rule definition.

class cartography.rules.spec.model.RuleReference(text: str, url: str)

Bases: object

A reference document for a Rule.

__init__(text: str, url: str) None

Execution result classes for Cartography rules.

This module defines the data structures used to represent the results of rule and fact execution.

class cartography.rules.spec.result.CounterResult(current_fact: int = 0, total_facts: int = 0, total_findings: int = 0, total_assets: int = 0, total_failing: int = 0, total_passing: int = 0)

Bases: object

Counter for tracking rule execution progress and aggregate metrics.

This class maintains running totals during rule execution, including the current progress and aggregate compliance metrics across all facts.

current_fact

The index of the currently executing fact.

Type:

int

total_facts

The total number of facts to execute.

Type:

int

total_findings

The cumulative count of findings across all facts.

Type:

int

total_assets

Sum of total_assets across all facts (for compliance).

Type:

int

total_failing

Sum of failing assets across all facts (for compliance).

Type:

int

total_passing

Sum of passing assets across all facts (for compliance).

Type:

int

__init__(current_fact: int = 0, total_facts: int = 0, total_findings: int = 0, total_assets: int = 0, total_failing: int = 0, total_passing: int = 0) None
class cartography.rules.spec.result.FactResult(fact_id: str, fact_name: str, fact_description: str, fact_provider: str, findings: list[~cartography.rules.spec.model.Finding] = <factory>, total_assets: int | None = None, failing: int | None = None, passing: int | None = None)

Bases: object

Results for a single Fact execution.

Contains the findings from executing a Fact’s Cypher query along with optional compliance metrics when a count query is provided.

fact_id

The unique identifier of the executed Fact.

Type:

str

fact_name

The human-readable name of the Fact.

Type:

str

fact_description

A description of what the Fact checks for.

Type:

str

fact_provider

The cloud provider or module this Fact applies to.

Type:

str

findings

The list of findings from the Fact query.

Type:

list[Finding]

total_assets

Total assets evaluated (from cypher_count_query). None if no count query was provided.

Type:

int | None

failing

Number of assets that match the finding criteria. None if no count query was provided.

Type:

int | None

passing

Number of assets that don’t match (total_assets - failing). None if no count query was provided.

Type:

int | None

__init__(fact_id: str, fact_name: str, fact_description: str, fact_provider: str, findings: list[~cartography.rules.spec.model.Finding] = <factory>, total_assets: int | None = None, failing: int | None = None, passing: int | None = None) None
class cartography.rules.spec.result.RuleResult(rule_id: str, rule_name: str, rule_description: str, counter: ~cartography.rules.spec.result.CounterResult, facts: list[~cartography.rules.spec.result.FactResult] = <factory>, rule_tags: tuple[str, ...] = (), rule_frameworks: tuple[~cartography.rules.spec.model.Framework, ...] = ())

Bases: object

Results for a single Rule execution.

Contains the aggregated results from executing all Facts within a Rule, along with execution counters and metadata.

rule_id

The unique identifier of the executed Rule.

Type:

str

rule_name

The human-readable name of the Rule.

Type:

str

rule_description

A description of the security issue or misconfiguration.

Type:

str

counter

Execution counters and aggregate metrics.

Type:

CounterResult

facts

Results from each Fact executed within this Rule.

Type:

list[FactResult]

rule_tags

Tags associated with the Rule.

Type:

tuple[str, …]

rule_frameworks

Compliance frameworks this rule maps to.

Type:

tuple[Framework, …]

__init__(rule_id: str, rule_name: str, rule_description: str, counter: ~cartography.rules.spec.result.CounterResult, facts: list[~cartography.rules.spec.result.FactResult] = <factory>, rule_tags: tuple[str, ...] = (), rule_frameworks: tuple[~cartography.rules.spec.model.Framework, ...] = ()) None