factcircuit
FactCircuit: an auditable claim-and-evidence verification loop with immutable provenance, staged checks, bounded retrieval, and reproducible evaluation.
Open-source, Table API-based ServiceNow connectors for Apache Kafka Connect.
DataJava · PythonGitHub @osodevopsOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Open-source ServiceNow connectors for Apache Kafka: Table API source with keyset polling and backfill, Table API CRUD sink. The Apache-2.0 alternative to Confluent's ServiceNow connectors.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Open-source ServiceNow connectors for Apache Kafka: Table API source and sink, Kafka Connect
kafka-connect-servicenow is a production-grade, Apache-2.0 pair of ServiceNow connectors for Kafka Connect, the open-source alternative to Confluent's proprietary ServiceNow connectors. A source and a sink deliver parity with Confluent's Platform and Cloud (V2) connectors, built clean-room on ServiceNow's public REST Table API with no ServiceNow-side application to install.Read the full README ↗kafka-connect-servicenow is a production-grade, Apache-2.0 pair of ServiceNow connectors for Kafka Connect, the open-source alternative to Confluent's proprietary ServiceNow connectors. A source and a sink deliver parity with Confluent's Platform and Cloud (V2) connectors, built clean-room on ServiceNow's public REST Table API with no ServiceNow-side application to install.
Running it in production? OSO, who build and maintain the connectors, offer an Enterprise support subscription: maintained releases and security patches, ServiceNow family release readiness, a 60-minute P1 response from the engineers who write the code, and an onboarding review. What it covers is on the Enterprise Support page and in SUPPORT.md.
(sys_updated_on, sys_id) keyset cursor with overlap and version dedup, so 10,000 rows updated in the same second are never skipped and restarts never lose a rowRetry-After, backs off with jitter, bounds retries by attempts and elapsed time, caps in-flight requests per instanceplugin.discovery=service_load readyDownload a connector plugin ZIP from GitHub Releases, unzip it onto your Connect worker's plugin.path, and restart the worker. Each release also carries a SHA-256 checksum per ZIP and a CycloneDX SBOM.
Or build from source (JDK 17+, Maven 3.6.3+):
mvn clean package -DskipTests
# ZIPs land in */target/*-kafka-connect-plugin.zip
Library artifacts are published to Maven Central under the sh.oso group.
The quickstart runs with no ServiceNow credentials: the fake profile starts the same fake ServiceNow the test suite uses.
cd examples
mkdir -p plugins && for z in ../*/target/*-kafka-connect-plugin.zip; do unzip -o "$z" -d plugins/; done
docker compose --profile fake up -d
curl -s -X POST -H 'Content-Type: application/json' \
--data @source-connector-fake.json localhost:8083/connectors
Watch the seeded incidents arrive:
docker compose exec kafka /opt/kafka/bin/kafka-console-consumer.sh \
--bootstrap-server localhost:19092 --topic servicenow.incident --from-beginning
Point it at a real instance by registering source-connector.json instead. Full walkthrough (integration user, OAuth application registry, connector configs): the documentation.
Backfill and then poll three tables into per-table topics:
{
"name": "servicenow-source",
"config": {
"connector.class": "sh.oso.servicenow.source.ServiceNowSourceConnector",
"tasks.max": "3",
"snow.url": "https://acme.service-now.com",
"snow.auth.type": "oauth2",
"snow.oauth.grant.type": "client_credentials",
"snow.oauth.client.id": "${file:/secrets/snow.properties:client.id}",
"snow.oauth.client.secret": "${file:/secrets/snow.properties:client.secret}",
"snow.tables": "incident,change,cmdb",
"snow.table.incident.name": "incident",
"snow.table.incident.topic": "servicenow.incident",
"snow.table.incident.start.timestamp": "2026-01-01 00:00:00",
"snow.table.incident.query": "active=true",
"snow.table.change.name": "change_request",
"snow.table.change.topic": "servicenow.change_request",
"snow.table.cmdb.name": "cmdb_ci_server",
"snow.table.cmdb.topic": "servicenow.cmdb_ci_server",
"snow.table.cmdb.fields": "sys_id,sys_updated_on,name,ip_address,os",
"snow.source.schema.mode": "schemaless"
}
}
Write Kafka records back into ServiceNow, patching by sys_id and deleting on tombstones:
{
"name": "servicenow-incident-sink",
"config": {
"connector.class": "sh.oso.servicenow.sink.ServiceNowSinkConnector",
"tasks.max": "2",
"topics": "incident-updates",
"snow.url": "https://acme.service-now.com",
"snow.auth.type": "basic",
"snow.auth.username": "${file:/secrets/snow.properties:username}",
"snow.auth.password": "${file:/secrets/snow.properties:password}",
"snow.sink.table": "incident",
"snow.sink.operation.mode": "key_value",
"snow.sink.update.method": "PATCH",
"snow.sink.create.ambiguous.behavior": "correlation_lookup",
"snow.sink.correlation.field": "correlation_id",
"snow.sink.reporter.bootstrap.servers": "kafka:19092",
"snow.sink.reporter.error.topic": "servicenow-incident-sink-errors",
"errors.tolerance": "all",
"errors.deadletterqueue.topic.name": "dlq-servicenow-incident-sink"
}
}
Every property is documented in the configuration reference, generated from the connectors' ConfigDef, so it always matches the release.
| Connector | Direction | ServiceNow APIs |
|---|---|---|
| Source (docs) | ServiceNow to Kafka | REST Table API (GET), keyset polling on sys_updated_on or sys_created_on |
| Sink (docs) | Kafka to ServiceNow | REST Table API (POST, PATCH, PUT, DELETE) |
All ServiceNow protocol logic lives in the shared snow-core library; the connectors stay thin. Deletes cannot be observed through the Table API; the optional, separately governed event bridge is the documented path for them.
A scripted path with verifiable evidence:
# translate your existing connector config
curl -s http://connect:8083/connectors/servicenow-incidents \
| tools/confluent-migration/confluent2oss.py - -o servicenow-incidents-oss.json
# after cutover, prove nothing was lost
tools/confluent-migration/verify_cutover.py --table incident \
--instance-url https://acme.service-now.com --username "$USER" --password "$PASS" \
--since "$T0" --topic-dump dump.tsv
The zero-loss cutover procedure is executed in CI on every build, publishing a migration-evidence artifact (row counts, SHA-256 digests, cursor continuity). See the migration guide.
Everything runs locally with no ServiceNow instance: the snow-core test-jar ships a fake ServiceNow (a WireMock Table API with an in-memory table store, encoded query evaluation, OAuth token endpoint and fault injection).
mvn clean verify # unit + fake-harness + docker e2e (Kafka + Connect worker)
mvn clean verify -DskipE2E # without Docker
mvn verify -Pcontract -DskipE2E -DskipUnitTests=true # against a real instance (SNOW_URL, SNOW_USERNAME, SNOW_PASSWORD)
Docs are built with Docusaurus from website/ and served at servicenowkafkaconnector.com. Design and clean-room documents live in docs/.
We welcome contributions of all kinds!
website/; docs pull requests are very welcome.Releases use conventional commits (feat:, fix:, ...); release-please turns them into versions and changelogs automatically.
OSO, who build and maintain these connectors, offer an annual Enterprise support subscription: maintained releases and security patches, ServiceNow family release readiness, production support with a 60-minute P1 response in UK business hours, an onboarding review, and help migrating from Confluent's connectors. What is covered, the response targets, the supported-version window and the maintenance commitments are on the Enterprise Support page and in SUPPORT.md. Contact [email protected] or book a call.
kafka-connect-servicenow is licensed under the Apache License 2.0 © OSO.
This is an independent open-source project, not affiliated with, endorsed, or sponsored by ServiceNow, Inc. or the Apache Software Foundation. ServiceNow is a trademark of ServiceNow, Inc. Apache, Apache Kafka, and Kafka are trademarks of the Apache Software Foundation.