- Sources bring logs in from another service and write them to a stream. MoleSignal pulls CloudWatch Logs on a schedule. Amazon Data Firehose, Cloudflare Logpush, and Heroku push their logs to MoleSignal.
- Destinations receive the output of a scheduled pipeline: Amazon S3 and S3-compatible storage, Apache Kafka, and any HTTP endpoint.
Create a connector
1
Open the connectors
Go to Pipelines → Connectors. The page lists Sources and Destinations.
2
Choose the kind
Click New connector and choose what to connect to.
3
Fill in the settings
Enter a Name that is unique within the organization, fill in where the connector reads from or delivers to, and choose the Authentication.
4
Test and create
Click Test connection to try the settings before saving them, then click Create connector. A push source has nothing to connect to and offers no test.
name, a kind, and a config_json whose keys depend on the kind. auth in config_json names the way of authenticating, and each way takes its own keys. Settings that cannot work answer 400 when they are saved: a missing required key, half of a credential pair, or a key that the chosen auth does not use.
Secrets
These keys ofconfig_json hold secrets:
A secret never leaves through the API. A response shows
*** in its place and names the secrets that hold a value in secret_keys:
- An update that sends
***back keeps the stored value, so a connector can be renamed, turned off, or pointed elsewhere without entering its credentials again. In the UI, a saved secret left empty keeps its value. - A secret left out of an update is removed.
- An update that changes the
kindkeeps none of the stored secrets.
MS_CIPHER_KEY (AES-256-GCM) apart from the other settings, and stores no secret in plain text. A push source is found by the SHA-256 of its token. molesignal rewrap-kek re-seals the connector secrets together with the other secrets when the root key rotates. See Production checklist.
Sources
Push sources
The three push sources share one model: create a connector with apush_token and a target_stream, then point the platform at the matching endpoint. These endpoints do not use the JWT. The request authenticates with the push token, supplied whichever way the platform allows:
The UI generates the token when it creates the connector and shows it once, with the endpoint to give the platform. The token cannot be read back. Generate a new token replaces it when the connector is saved. Over the API, supply a
push_token of at least 16 characters. One token opens one connector of a kind: a token already in use answers 409. A request with a missing or unknown token, or for a connector that is turned off, answers 401. A connector without a token accepts nothing.
Bodies sent with Content-Encoding: gzip are decompressed automatically. Events flow through the same intake path as everything else: schema-on-write, pipelines, and masking all apply.
- Amazon Data Firehose
- Cloudflare Logpush
- Heroku
Create the connector with
kind: "aws_kinesis_firehose", then choose the HTTP endpoint destination for the Firehose stream:- HTTP endpoint URL:
https://molesignal.example.com/api/v1/_kinesis_firehose - Access key: the push token. Firehose sends it as
X-Amz-Firehose-Access-Key.
message field for plain text. MoleSignal returns the 200 acknowledgment that Firehose expects.CloudWatch Logs
CloudWatch Logs is a pull source: MoleSignal callsFilterLogEvents every 30 seconds instead of receiving a push. The first run reads the last 5 minutes. Each later run starts where the last successful run ended, so events that could not be read or written are read again on the next run.
One node polls a connector at a time. The
alert nodes divide the connectors between them, and a node claims a connector before it polls. See Work division between alert nodes. Each event becomes a log with message, log_stream, and log_group. A connector that is turned off is not polled.
Destinations
A destination receives every event that comes through the steps of a scheduled pipeline. Add the connector to the Destinations of the flow with Add destination → Connector. A delivery that fails is retried within the run, and events that the connector still does not take go to the dead letter stream. See Retries and dead letters. A destination that is turned off receives nothing. Each run skips the connector and names it in thewarning of the run. The skipped events do not count as failed, do not become dead letters, and are not sent when the connector is turned on again. In the editor, a connector that is off reads Off.
Amazon S3
Thes3 kind also delivers to S3-compatible storage such as MinIO, Cloudflare R2, and Alibaba Cloud OSS. In the UI, turn on S3-compatible storage to set the endpoint.
Apache Kafka
TLS and SASL combine: SCRAM over TLS connects as
SASL_SSL.
HTTP / Webhook
A custom header cannot be one that the delivery sets itself:
Host, Content-Type, Content-Length, Content-Encoding, Transfer-Encoding, Connection, X-MoleSignal-Timestamp, or X-MoleSignal-Signature.
A delivery follows these rules:
- A batch larger than 4 MiB is split into several requests. An event larger than that goes in a request of its own.
- Any
2xxstatus counts as delivered. Any other status fails the delivery, and so does a redirect: redirects are not followed. - A request times out after 30 seconds.
- MoleSignal resolves the host before the request and connects only to the addresses it resolved. An address where cloud metadata services answer is refused, whether it appears in the URL or comes from DNS:
169.254.0.0/16,fe80::/10,fd00:ec2::254, and100.100.100.200. Other private addresses are allowed.
Verify an HMAC signature
Withhmac, every request carries two headers:
To verify a request, compute the HMAC-SHA256 of the timestamp, a
., and the raw body bytes with the same secret, and compare the result with the signature in constant time. Refuse a timestamp older than a few minutes, so that a captured request cannot be sent again later.
AWS authentication
S3 and CloudWatch Logs authenticate to AWS in one of five ways:
Without
auth, the stored keys decide: an access key reads as access_key, a role_arn as assume_role, and neither as node_role. A role_arn has the form arn:aws:iam::<account>:role/<name>.
Node identity
node_role uses the identity that the AWS SDKs find on the node: EKS IAM roles for service accounts (IRSA) or EKS Pod Identity, an ECS task role, or an EC2 instance profile. A static key in the node’s environment, such as AWS_ACCESS_KEY_ID, is never used for connectors.
Assume a role
assume_role asks AWS STS for a one-hour key of the role and renews the key 5 minutes before it expires. The base credentials that assume the role are the node’s identity. For a deployment that does not run on AWS, select Assume it with an access key, not the node’s identity and enter the key of an IAM user.
Every organization assumes roles with its own external ID, molesignal-<organization ID>, which cannot be changed. The form shows it under External ID, and GET /api/v1/connectors/aws-external-id returns it. Require the external ID in the trust policy of the role, so that no other organization can assume the role even when it learns the ARN:
molesignal-<connector ID>, which is how it appears in AWS CloudTrail. The request goes to the regional STS endpoint of the connector’s region: us-east-1 when the region is empty, and the amazonaws.com.cn domain for the China regions.
Web identity
web_identity assumes the role with the web identity token whose path the node’s AWS_WEB_IDENTITY_TOKEN_FILE gives, such as the service account token that EKS projects for IRSA. A connector cannot name another file. The trust policy of the role must trust the OIDC provider that issues the token. On a node without AWS_WEB_IDENTITY_TOKEN_FILE, the connector has no credentials.
The token is exchanged at the regional STS endpoint of the connector’s region, or at AWS_ENDPOINT_URL_STS when the node’s environment sets it. The same applies to a node identity that comes from IRSA.
Test a connection
Test connection tries the settings as they stand in the form, before they are saved. A secret left empty is the saved one. Each kind does the least that proves a delivery or a pull can work:
A test gives up after 25 seconds. Over the API,
POST /api/v1/connectors/test takes the kind and the config_json to try. With the id of a saved connector of the same kind, *** stands for the secret that the connector holds. Settings that cannot work answer 400, as on save.
elapsed_ms is how long the test took. A failed test names the cause in code, and detail carries the words of the other side, up to 600 characters:
API
A connector reads as
id, name, kind, config_json with masked secrets, secret_keys, enabled, last_run_at_micros, created_at_micros, and updated_at_micros.
Permissions
pipelines.read lists and inspects connectors and reads the external ID. pipelines.edit creates, updates, deletes, and tests connectors. A test needs pipelines.edit because it uses the stored secrets and connects to another system for the caller. Push receivers authenticate with the push token and do not accept a normal login JWT as a replacement.
Intake API
Endpoint details for the Amazon Data Firehose, Cloudflare, and Heroku push receivers.