Detection rules › Panther
Panther rules: tines
Tines Actions Disabled Change
#Detections when Tines Actions are set to Disabled Change
Detection logic
from panther_tines_helpers import tines_alert_context
ACTIONS = ["ActionsDisabledChange"]
def rule(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return action in ACTIONS
def title(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
actor = event.get("user_email", "<NO_USERNAME>")
return f"Tines: {action} " f"by {actor}"
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_actions_disabled_changes.py
RuleID: Tines.Actions.DisabledChanges
DisplayName: Tines Actions Disabled Change
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
Reference: https://www.tines.com/university/tines-basics/architecture-of-an-action
Severity: Medium
Description: >
Detections when Tines Actions are set to Disabled Change
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
- user_id
- operation_name
- tenant_id
- request_ip
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameis one ofActionsDisabledChange
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | in |
| field:"operation_name" kind:in value:"ActionsDisabledChange" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-05-23 23:16:41",
"id": 7111111,
"operation_name": "ActionsDisabledChange",
"request_ip": "12.12.12.12",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
"tenant_id": "8888",
"user_email": "user@company.com",
"user_id": "17171",
"user_name": "user at company dot com"
}
Tines Custom CertificateAuthority setting changed
#Detects when Tines Custom CertificateAuthority settings are changed
Detection logic
from panther_tines_helpers import tines_alert_context
ACTIONS = [
"CustomCertificateAuthoritySet",
]
def rule(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return action in ACTIONS
def title(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return f"Tines: [{action}] " f"by [{event.deep_get('user_email', default='<NO_USEREMAIL>')}]"
def alert_context(event):
return tines_alert_context(event)
def dedup(event):
return (
f"{event.deep_get('user_id', default='<NO_USERID>')}"
"_"
f"{event.deep_get('operation_name', default='<NO_OPERATION>')}"
)
Rule specification
AnalysisType: rule
Filename: tines_custom_ca.py
RuleID: Tines.Custom.CertificateAuthority
DisplayName: Tines Custom CertificateAuthority setting changed
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
- IAM - Credential Security
Reference: https://www.tines.com/docs/admin/custom-certificate-authority
Severity: High
Description: >
Detects when Tines Custom CertificateAuthority settings are changed
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
- user_id
- operation_name
- tenant_id
- request_ip
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameis one ofCustomCertificateAuthoritySet
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | in |
| field:"operation_name" kind:in value:"CustomCertificateAuthoritySet" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-05-18 22:54:11",
"id": 7111111,
"inputs": {},
"operation_name": "CustomCertificateAuthoritySet",
"request_ip": "12.12.12.12",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
"tenant_id": "8888",
"user_email": "user@company.com",
"user_id": "17171",
"user_name": "user at company dot com"
}
Tines Enqueued/Retrying Job Deletion
#Currently enqueued or retrying jobs were cleared
Detection logic
from panther_tines_helpers import tines_alert_context
def rule(event):
return event.get("operation_name", "<NO_OPERATION_NAME>") in [
"JobsQueuedDeletion",
"JobsRetryingDeletion",
]
def title(event):
operation = event.get("operation_name", "<NO_OPERATION_NAME>")
user = event.get("user_email", "<NO_USER_EMAIL>")
tines_instance = event.get("p_source_label", "<NO_SOURCE_LABEL>")
return f"Tines [{operation}] performed by [{user}] on [{tines_instance}]."
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_enqueued_retrying_job_deletion.py
RuleID: Tines.Enqueued.Retrying.Job.Destruction
DisplayName: "Tines Enqueued/Retrying Job Deletion"
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
Severity: Low
Description: "Currently enqueued or retrying jobs were cleared"
Runbook: "Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons."
Reference: https://www.tines.com/docs/self-hosting/job-management
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameis one ofJobsQueuedDeletion,JobsRetryingDeletion
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | in |
| field:"operation_name" kind:in |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
p_source_label |
Response runbook
Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-06-13 15:14:46",
"id": 1234,
"operation_name": "JobsQueuedDeletion",
"p_source_label": "tines-log-source-name",
"request_ip": "98.224.225.84",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"tenant_id": "1337",
"user_email": "user@email.com",
"user_id": "7331",
"user_name": "Tines User Person"
}
Tines Global Resource Destruction
#A Tines user has destroyed a global resource.
Detection logic
from panther_tines_helpers import tines_alert_context
def rule(event):
return event.get("operation_name", "<NO_OPERATION_NAME>") == "GlobalResourceDestruction"
def title(event):
operation = event.get("operation_name", "<NO_OPERATION_NAME>")
user = event.get("user_email", "<NO_USER_EMAIL>")
tines_instance = event.get("p_source_label", "<NO_SOURCE_LABEL>")
return f"Tines [{operation}] performed by [{user}] on [{tines_instance}]."
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_global_resource_destruction.py
RuleID: Tines.Global.Resource.Destruction
DisplayName: "Tines Global Resource Destruction"
Enabled: true
SummaryAttributes:
- user_id
- operation_name
- tenant_id
- request_ip
LogTypes:
- Tines.Audit
Tags:
- Tines
Severity: Low
Description: "A Tines user has destroyed a global resource."
Runbook: "Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons."
Reference: https://www.tines.com/docs/resources
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameisGlobalResourceDestruction
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | eq |
| field:"operation_name" kind:eq value:"GlobalResourceDestruction" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
p_source_label |
Response runbook
Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-06-13 15:14:46",
"id": 1234,
"operation_name": "GlobalResourceDestruction",
"p_source_label": "tines-log-source-name",
"request_ip": "98.224.225.84",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"tenant_id": "1337",
"user_email": "user@email.com",
"user_id": "7331",
"user_name": "Tines User Person"
}
Tines SSO Settings
#Detects when Tines SSO settings are changed
Detection logic
from panther_tines_helpers import tines_alert_context
ACTIONS = [
"SsoConfigurationDefaultSet",
"SsoConfigurationOidcSet",
"SsoConfigurationSamlSet",
]
def rule(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return action in ACTIONS
def title(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return (
f"Tines: [{action}] Setting "
f"changed by [{event.deep_get('user_email', default='<NO_USEREMAIL>')}]"
)
def alert_context(event):
return tines_alert_context(event)
def dedup(event):
return (
f"{event.deep_get('user_id', default='<NO_USERID>')}"
"_"
f"{event.deep_get('operation_name', default='<NO_OPERATION>')}"
)
Rule specification
AnalysisType: rule
Filename: tines_sso_settings.py
RuleID: Tines.SSO.Settings
DisplayName: Tines SSO Settings
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
- IAM - Credential Security
Severity: High
Description: >
Detects when Tines SSO settings are changed
Reference: https://www.tines.com/docs/admin/single-sign-on
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
- user_id
- operation_name
- tenant_id
- request_ip
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameis one ofSsoConfigurationDefaultSet,SsoConfigurationOidcSet,SsoConfigurationSamlSet
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | in |
| field:"operation_name" kind:in |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-05-16 23:26:46",
"id": 1111111,
"inputs": {
"domainId": "REDACTED",
"fingerprint": "REDACTED",
"idpCertificate": "REDACTED",
"targetUrl": "REDACTED"
},
"operation_name": "SsoConfigurationSamlSet",
"request_ip": "12.12.12.12",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
"tenant_id": "8888",
"user_email": "user@company.com",
"user_id": "17171",
"user_name": "user at company dot com"
}
Tines Story Items Destruction
#A user has destroyed a story item
Detection logic
from panther_tines_helpers import tines_alert_context
def rule(event):
return event.get("operation_name", "<NO_OPERATION_NAME>") == "StoryItemsDestruction"
def title(event):
operation = event.get("operation_name", "<NO_OPERATION_NAME>")
user = event.get("user_email", "<NO_USER_EMAIL>")
tines_instance = event.get("p_source_label", "<NO_SOURCE_LABEL>")
return f"Tines [{operation}] performed by [{user}] on [{tines_instance}]."
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_story_items_destruction.py
RuleID: Tines.Story.Items.Destruction
DisplayName: "Tines Story Items Destruction"
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
Severity: Info
Description: "A user has destroyed a story item"
Runbook: "Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons."
Reference: https://www.tines.com/docs/stories
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameisStoryItemsDestruction
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | eq |
| field:"operation_name" kind:eq value:"StoryItemsDestruction" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
p_source_label |
Response runbook
Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-06-13 15:14:46",
"id": 1234,
"operation_name": "StoryItemsDestruction",
"p_source_label": "tines-log-source-name",
"request_ip": "98.224.225.84",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"tenant_id": "1337",
"user_email": "user@email.com",
"user_id": "7331",
"user_name": "Tines User Person"
}
Tines Story Jobs Clearance
#A Tines User has cleared story jobs.
Detection logic
from panther_tines_helpers import tines_alert_context
def rule(event):
return event.get("operation_name", "<NO_OPERATION_NAME>") == "StoryJobsClearance"
def title(event):
operation = event.get("operation_name", "<NO_OPERATION_NAME>")
user = event.get("user_email", "<NO_USER_EMAIL>")
tines_instance = event.get("p_source_label", "<NO_SOURCE_LABEL>")
return f"Tines: [{operation}] performed by [{user}] on [{tines_instance}]."
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_story_jobs_clearance.py
RuleID: Tines.Story.Jobs.Clearance
DisplayName: "Tines Story Jobs Clearance"
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
Severity: Low
Description: "A Tines User has cleared story jobs."
Runbook: "Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons."
Reference: https://www.tines.com/docs/stories
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameisStoryJobsClearance
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | eq |
| field:"operation_name" kind:eq value:"StoryJobsClearance" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
p_source_label |
Response runbook
Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-06-13 15:14:46",
"id": 1234,
"operation_name": "StoryJobsClearance",
"p_source_label": "tines-log-source-name",
"request_ip": "98.224.225.84",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"tenant_id": "1337",
"user_email": "user@email.com",
"user_id": "7331",
"user_name": "Tines User Person"
}
Tines Team Destruction
#A user has destroyed a team
Detection logic
from panther_tines_helpers import tines_alert_context
def rule(event):
return event.get("operation_name", "<NO_OPERATION_NAME>") == "TeamDestruction"
def title(event):
operation = event.get("operation_name", "<NO_OPERATION_NAME>")
user = event.get("user_email", "<NO_USER_EMAIL>")
tines_instance = event.get("p_source_label", "<NO_SOURCE_LABEL>")
return f"Tines [{operation}] performed by [{user}] on [{tines_instance}]."
def alert_context(event):
return tines_alert_context(event)
Rule specification
AnalysisType: rule
Filename: tines_team_destruction.py
RuleID: Tines.Team.Destruction
DisplayName: "Tines Team Destruction"
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
Severity: Low
Description: "A user has destroyed a team"
Runbook: "Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons."
Reference: https://www.tines.com/docs/admin/teams
DedupPeriodMinutes: 60
Threshold: 1
Stages and Predicates
Fires on Tines.Audit events when the condition below holds.
Condition
operation_nameisTeamDestruction
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
operation_name | eq |
| field:"operation_name" kind:eq value:"TeamDestruction" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
p_source_label |
Response runbook
Possible data destruction. Please reach out to the user and confirm this was done for valid business reasons.
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-06-13 15:14:46",
"id": 1234,
"operation_name": "TeamDestruction",
"p_source_label": "tines-log-source-name",
"request_ip": "98.224.225.84",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ( KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"tenant_id": "1337",
"user_email": "user@email.com",
"user_id": "7331",
"user_name": "Tines User Person"
}
Tines Tenant API Keys Added
#Detects when Tines Tenant API Keys are added
Detection logic
from panther_tines_helpers import tines_alert_context
ACTIONS = [
"AuthenticationTokenCreation",
# AuthenticationTokenDeletion does not include
# the scope of the deleted token.
# Leaving deletion un-implemented for now
# "AuthenticationTokenDeletion",
]
def rule(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
is_tenant_token = event.deep_get("inputs", "inputs", "isServiceToken", default=False)
return all([action in ACTIONS, is_tenant_token])
def title(event):
action = event.get("operation_name", "<NO_OPERATION_NAME>")
return (
f"Tines: Tenant [{action}] "
f"by [{event.deep_get('user_email', default='<NO_USEREMAIL>')}]"
)
def alert_context(event):
a_c = tines_alert_context(event)
a_c["token_name"] = event.deep_get("inputs", "inputs", "name", default="<NO_TOKENNAME>")
return a_c
def dedup(event):
return (
f"{event.deep_get('user_id', default='<NO_USERID>')}"
"_"
f"{event.deep_get('operation_name', default='<NO_OPERATION>')}"
"_"
f"{event.deep_get('inputs', 'inputs', 'name', default='<NO_TOKENNAME>')}"
)
Rule specification
AnalysisType: rule
Filename: tines_tenant_authtoken.py
RuleID: Tines.Tenant.AuthToken
DisplayName: Tines Tenant API Keys Added
Enabled: true
LogTypes:
- Tines.Audit
Tags:
- Tines
- IAM - Credential Security
Severity: Medium
Description: >
Detects when Tines Tenant API Keys are added
Reference: https://www.tines.com/api/authentication
DedupPeriodMinutes: 60
Threshold: 1
SummaryAttributes:
- user_id
- operation_name
- tenant_id
- request_ip
Stages and Predicates
Fires on Tines.Audit events when all of the conditions below hold.
Condition
operation_nameis one ofAuthenticationTokenCreationinputs.inputs.isServiceTokenis present
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
inputs.inputs.isServiceToken | is_not_null | field:"inputs.inputs.isServiceToken" kind:is_not_null | |
operation_name | in |
| field:"operation_name" kind:in value:"AuthenticationTokenCreation" |
Output fields
Fields the rule emits when it matches, drawn from the rule's alert_context.
| Field |
|---|
operation_name |
user_email |
Worked example
A sample event from the rule's unit tests that triggers a match.Sample Test Event
{
"created_at": "2023-05-18 22:54:01",
"id": 7222222,
"inputs": {
"inputs": {
"isServiceToken": true,
"name": "tenant-api-key"
}
},
"operation_name": "AuthenticationTokenCreation",
"request_ip": "12.12.12.12",
"request_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
"tenant_id": "8888",
"user_email": "user@company.com",
"user_id": "17171",
"user_name": "user at company dot com"
}