Input constraints control which entities can trigger a transform. They're evaluated by the Maltego client before showing the transform to users, so users only see transforms that apply to their selection.
Basic Usage
Add constraints via the input_constraint parameter in @register_transform:
from maltego.server import register_transform
from maltego.model.input_constraints import EntityTypeConstraint
@register_transform(
display_name="Domain Transform",
transform_set="My Transforms",
input_constraint=EntityTypeConstraint(entity_type="maltego.Domain")
)
async def domain_only(entity):
# Only runs on Domain entities
...Entity Type Constraints
Single Entity Type
from maltego.model.input_constraints import EntityTypeConstraint
input_constraint=EntityTypeConstraint(entity_type="maltego.Domain")Multiple Entity Types (OR)
from maltego.model.input_constraints import EntitySatisfiesAny, EntityTypeConstraint
input_constraint=EntitySatisfiesAny(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntityTypeConstraint(entity_type="maltego.IPv4Address"),
]
)Property Constraints
Property Exists
from maltego.model.input_constraints import (
EntityHasPropertySatisfying,
PropertyNameEquals
)
# Entity must have an 'email' property
input_constraint=EntityHasPropertySatisfying(
constraint=PropertyNameEquals(value="email")
)Property Value Equals
from maltego.model.input_constraints import (
EntityHasPropertySatisfying,
PropertySatisfiesAll,
PropertyNameEquals,
PropertyValueEquals
)
# Property 'status' must equal 'active'
input_constraint=EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="status"),
PropertyValueEquals(value="active", ignore_case=True),
]
)
)Property String Matching
from maltego.model.input_constraints import (
EntityHasPropertySatisfying,
PropertySatisfiesAll,
PropertyNameEquals,
PropertyValueStringMatch,
ConstraintStringMatchType
)
# Property 'domain' starts with 'www.'
input_constraint=EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="domain"),
PropertyValueStringMatch(
value="www.",
match_type=ConstraintStringMatchType.STARTSWITH,
ignore_case=True
),
]
)
)String Match Types:
| Type | Description |
|---|---|
STARTSWITH | Value starts with pattern |
ENDSWITH | Value ends with pattern |
CONTAINS | Value contains pattern |
Property Regex Matching
from maltego.model.input_constraints import (
EntityHasPropertySatisfying,
PropertyValueMatchesRegex
)
# Property value matches email pattern
input_constraint=EntityHasPropertySatisfying(
constraint=PropertyValueMatchesRegex(
regex=r"^[\w.-]+@[\w.-]+\.\w+$"
)
)Property Type Checking
from maltego.model.input_constraints import (
EntityHasPropertySatisfying,
PropertyTypeEquals
)
# Entity has a DATE-type property
input_constraint=EntityHasPropertySatisfying(
constraint=PropertyTypeEquals(value="DATE")
)Property Types: STRING, INT, DOUBLE, BOOLEAN, DATE, DATETIME, DATETIME_RANGE
Combining Constraints
AND Logic (All Must Match)
from maltego.model.input_constraints import EntitySatisfiesAll
input_constraint=EntitySatisfiesAll(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntityHasPropertySatisfying(
constraint=PropertyNameEquals(value="registrar")
),
]
)OR Logic (Any Can Match)
from maltego.model.input_constraints import EntitySatisfiesAny
input_constraint=EntitySatisfiesAny(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntityTypeConstraint(entity_type="maltego.URL"),
]
)NOT Logic (None Should Match)
from maltego.model.input_constraints import EntitySatisfiesNone
# Entity does NOT have status='inactive'
input_constraint=EntitySatisfiesNone(
constraints=[
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="status"),
PropertyValueEquals(value="inactive"),
]
)
),
]
)Complex Examples
Entity Type + Property Value
# Domain entities where registrar is "GoDaddy"
input_constraint=EntitySatisfiesAll(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="registrar"),
PropertyValueEquals(value="GoDaddy", ignore_case=True),
]
)
),
]
)Multiple Types + Property Condition
# (Domain OR Person) with email ending in @company.com
input_constraint=EntitySatisfiesAll(
constraints=[
EntitySatisfiesAny(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntityTypeConstraint(entity_type="maltego.Person"),
]
),
EntityHasPropertySatisfying(
constraint=PropertySatisfiesAll(
constraints=[
PropertyNameEquals(value="email"),
PropertyValueStringMatch(
value="@company.com",
match_type=ConstraintStringMatchType.ENDSWITH,
ignore_case=True
),
]
)
),
]
)Excluding Certain Values
# Domains that are NOT .gov or .mil
input_constraint=EntitySatisfiesAll(
constraints=[
EntityTypeConstraint(entity_type="maltego.Domain"),
EntitySatisfiesNone(
constraints=[
EntityHasPropertySatisfying(
constraint=PropertyValueStringMatch(
value=".gov",
match_type=ConstraintStringMatchType.ENDSWITH
)
),
EntityHasPropertySatisfying(
constraint=PropertyValueStringMatch(
value=".mil",
match_type=ConstraintStringMatchType.ENDSWITH
)
),
]
),
]
)Complete Example
Run maltego-transforms start my_project to create a new project from the template. See transforms/input_constraints_example.py for runnable examples of all constraint types covered in this guide.
Constraint Reference
Entity-Level Constraints
| Constraint | Description |
|---|---|
EntityTypeConstraint | Match specific entity type |
EntitySatisfiesAll | All constraints must match (AND) |
EntitySatisfiesAny | At least one constraint must match (OR) |
EntitySatisfiesNone | No constraints must match (NOT) |
EntityHasPropertySatisfying | Entity has property matching constraint |
Property-Level Constraints
| Constraint | Description |
|---|---|
PropertyNameEquals | Property name matches |
PropertyDisplayNameEquals | Property display name matches |
PropertyValueEquals | Property value exact match |
PropertyValueStringMatch | Property value string pattern |
PropertyValueMatchesRegex | Property value regex match |
PropertyTypeEquals | Property type matches |
PropertySatisfiesAll | All property constraints match (AND) |
PropertySatisfiesAny | At least one property constraint matches (OR) |
Best Practices
- Be specific - Narrow constraints reduce clutter in transform menus
- Use entity types first - They're the fastest filter
- Combine with property checks - For precise targeting
- Test constraints - Ensure transforms appear when expected
- Document requirements - Help users understand when transforms apply