TicketSync — bidirectional ticket synchronization across ITSM systems
Project description
TicketSync
Bidirectional ticket synchronization across ITSM, monitoring, and security systems.
TicketSync is a Python library, not a platform. You pip install it and use it in code.
No daemons, no YAML platform to self-host, no vendor lock-in.
Install
pip install ticketsync
For AWS adapters (CloudWatch, GuardDuty, Security Hub, OpsCenter):
pip install "ticketsync[integration]"
Requires Python 3.10+.
Quickstart — CloudWatch alarms into OpsCenter in 15 lines
import boto3
from ticketsync.adapters.cloudwatch_alarms import CloudWatchAlarmsAdapter
from ticketsync.adapters.opscenter import OpsCenterAdapter
from ticketsync.config import SyncConfig
from ticketsync.engine import SyncEngine
source = CloudWatchAlarmsAdapter(
client=boto3.client("cloudwatch", region_name="us-east-1"),
state_filter=["ALARM"],
)
dest = OpsCenterAdapter(
client=boto3.client("ssm", region_name="us-east-1"),
)
config = SyncConfig.from_dict({
"source": {"type": "cloudwatch_alarms"},
"destination": {"type": "opscenter"},
"deduplication": True,
"lookback_hours": 24,
})
engine = SyncEngine(source=source, dest=dest, config=config)
result = engine.run()
print(f"Synced {result.written} alarms to OpsCenter")
Adapter table
| Adapter class | System | Direction | Required IAM / auth |
|---|---|---|---|
CloudWatchAlarmsAdapter |
AWS CloudWatch Alarms | read | cloudwatch:DescribeAlarms |
GuardDutyFindingsAdapter |
AWS GuardDuty Findings | read | guardduty:ListFindings, guardduty:GetFindings |
SecurityHubFindingsAdapter |
AWS Security Hub (ASFF) | read | securityhub:GetFindings |
OpsCenterAdapter |
AWS Systems Manager OpsCenter | read/write | ssm:GetOpsItem, ssm:CreateOpsItem, ssm:UpdateOpsItem |
GitHubIssuesAdapter |
GitHub Issues REST API | read/write | GitHub PAT with repo scope |
LocalFilesystemAdapter |
Local JSON files | read/write | None |
Config YAML reference
source:
type: cloudwatch_alarms # adapter type key (see table above)
# any extra keys are passed as kwargs to the adapter constructor
destination:
type: opscenter
region: us-east-1
deduplication: true # skip tickets already written to destination
lookback_hours: 24 # only sync tickets updated in last N hours (0 = all)
Load config from a YAML string, file path, or open file object:
from ticketsync.config import SyncConfig
config = SyncConfig.from_yaml("path/to/sync.yaml")
# or
config = SyncConfig.from_dict({"source": {...}, "destination": {...}})
Example — GuardDuty findings into GitHub Issues
import boto3
import httpx
from ticketsync.adapters.guardduty import GuardDutyFindingsAdapter
from ticketsync.adapters.github_issues import GitHubIssuesAdapter
from ticketsync.config import SyncConfig
from ticketsync.engine import SyncEngine
class HttpxClient:
"""Thin httpx wrapper matching the GitHubIssuesAdapter client interface."""
def __init__(self, token: str) -> None:
self._headers = {"Authorization": f"Bearer {token}"}
def get(self, url: str, params: dict | None = None) -> object:
return httpx.get(url, params=params, headers=self._headers).json()
def post(self, url: str, json: dict | None = None) -> dict:
return httpx.post(url, json=json, headers=self._headers).json()
def patch(self, url: str, json: dict | None = None) -> dict:
return httpx.patch(url, json=json, headers=self._headers).json()
source = GuardDutyFindingsAdapter(
client=boto3.client("guardduty", region_name="us-east-1"),
detector_id="your-detector-id",
)
dest = GitHubIssuesAdapter(
client=HttpxClient("ghp_your_token"),
owner="your-org",
repo="security-issues",
)
config = SyncConfig.from_dict({
"source": {"type": "guardduty"},
"destination": {"type": "github_issues"},
"deduplication": True,
"lookback_hours": 6,
})
result = SyncEngine(source=source, dest=dest, config=config).run()
print(f"Opened {result.written} GitHub issues from GuardDuty findings")
Core data model
Every ticket, alarm, finding, and issue is normalized to the Ticket IR before
moving between adapters:
from ticketsync.models import Ticket
ticket = Ticket(
source_system="guardduty",
source_id="abc123",
title="Suspicious API call from known malicious IP",
description="GuardDuty detected an unusual API call pattern.",
severity="high", # critical / high / medium / low / informational
status="open", # open / in_progress / resolved / closed
category="Recon:EC2/Portscan",
tags=["region:us-east-1", "product:GuardDuty"],
)
See docs/ARCHITECTURE.md for the full field reference.
Documentation
- docs/ADAPTERS.md — required permissions, field mapping tables, and config examples for every adapter
- docs/ARCHITECTURE.md — Ticket IR fields, Protocol interface, SyncEngine behavior, deduplication logic
- docs/CONTRIBUTING.md — how to write a new adapter, test patterns, registry entry
License
Apache 2.0
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ticketsync-0.3.1.tar.gz.
File metadata
- Download URL: ticketsync-0.3.1.tar.gz
- Upload date:
- Size: 80.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ee409edeef1359dad206d5b84bc98b38ad5f91020e0198c2a78199e4d318a35
|
|
| MD5 |
7c073eca3b8e42babc7585af49b5f2cd
|
|
| BLAKE2b-256 |
a4b0dde46800eeccfd2874007b6b5d81c2794dc1617562cba2718d61806c2c73
|
Provenance
The following attestation bundles were made for ticketsync-0.3.1.tar.gz:
Publisher:
publish.yml on LeonardoSanBenitez/TicketSync
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ticketsync-0.3.1.tar.gz -
Subject digest:
6ee409edeef1359dad206d5b84bc98b38ad5f91020e0198c2a78199e4d318a35 - Sigstore transparency entry: 1485171401
- Sigstore integration time:
-
Permalink:
LeonardoSanBenitez/TicketSync@0d770216ab703b740812e07388ea3c96a48e71c6 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/LeonardoSanBenitez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0d770216ab703b740812e07388ea3c96a48e71c6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ticketsync-0.3.1-py3-none-any.whl.
File metadata
- Download URL: ticketsync-0.3.1-py3-none-any.whl
- Upload date:
- Size: 40.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac84a29ffc1343422ed0ba323c3daf5c7de6424b309ebc0f5d2bbf8434b1743e
|
|
| MD5 |
c03cc82aa03435c64ec996bd8406afc6
|
|
| BLAKE2b-256 |
c16b956cb338b92aeef8298523bbe84409e581b43516fe5b28014c68daeabbb0
|
Provenance
The following attestation bundles were made for ticketsync-0.3.1-py3-none-any.whl:
Publisher:
publish.yml on LeonardoSanBenitez/TicketSync
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ticketsync-0.3.1-py3-none-any.whl -
Subject digest:
ac84a29ffc1343422ed0ba323c3daf5c7de6424b309ebc0f5d2bbf8434b1743e - Sigstore transparency entry: 1485171634
- Sigstore integration time:
-
Permalink:
LeonardoSanBenitez/TicketSync@0d770216ab703b740812e07388ea3c96a48e71c6 -
Branch / Tag:
refs/tags/v0.3.1 - Owner: https://github.com/LeonardoSanBenitez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0d770216ab703b740812e07388ea3c96a48e71c6 -
Trigger Event:
release
-
Statement type: