Security model
How OBSESC is deployed inside your AWS account, where its trust boundaries sit, and which defaults you should change before production.
OBSESC runs entirely inside your own AWS account: the AMI, the EC2 node, the EBS volumes, the S3 bucket and the KMS key are all yours. This page explains what that means for your security posture, where the trust boundaries are, and what you need to switch on before you put production logs through it.
Where OBSESC runs
The CloudFormation stack you launch from AWS Marketplace creates:
| Component | What it holds | Encrypted with |
|---|---|---|
| EC2 node | Ingest listeners, the console and the query API | Root volume: your KMS key |
| EBS volumes | Incoming data and OBSESC’s working data | Your KMS key |
| S3 bucket (your existing bucket, or one the stack creates) | Original events in open formats, catalog, audit trail, legal holds | SSE-KMS with your key |
| Optional internal Application Load Balancer | Console access by name, with TLS and single sign-on | ACM certificate |
| IAM roles | Least-privilege access to the above | — |
The vendor has no IAM role, user or trust relationship in your account. The node role trusts only the EC2 service, and the snapshot role trusts only Amazon Data Lifecycle Manager. Nobody outside your organisation can reach the node unless your own network rules allow it.
See Encryption and IAM and permissions for the detail.
What leaves your account
Your log data does not leave your account. The node makes outbound calls to:
- AWS service APIs in your account: S3, KMS, STS, Secrets Manager and SSM Parameter Store, plus Elastic Load Balancing when you use the console load balancer.
- AWS Marketplace Metering Service, only when you set
MarketplaceProductCode. It reports usage only. It sends no log content. - Destinations you configure yourself: your Alertmanager, alert destinations (such as webhooks, Slack, PagerDuty, Opsgenie, Amazon SNS or email), and the AWS ALB public-keys endpoint if you enable automatic sign-in key rotation.
Trust boundaries
Each interface has its own authentication. Most of it is off until you configure it.
| Interface | Port | How callers authenticate | Default when unconfigured |
|---|---|---|---|
OTLP, Elasticsearch _bulk, Vector (and Loki, if enabled) | 4317, 4318, 9200, 9000 (Loki 3100) | Bearer or ApiKey token from your ingest tokens | Unauthenticated (the node warns at startup) |
| Splunk HEC | 8088 | Splunk <token> from your HEC tokens | Rejects everything |
| Fluent Forward | 24224 | Shared-key handshake | No handshake (the node warns at startup) |
| Firehose HTTP endpoint | 8555 | X-Amz-Firehose-Access-Key | Can’t be enabled without a key |
| GELF | 12201 | None (the protocol has no authentication) | Off |
| Console and query API | 18080 | Single sign-on through the load balancer, or a bearer token, then role-based access | Unauthenticated if AuthSecretArn isn’t set |
/metrics, /ready | 18080 | None (scrape and health-check surfaces) | Always unauthenticated |
Two consequences you should plan around:
- Without
AuthSecretArn, anyone who can reach port 18080 has full access to the console and the query API. Set it before production. With it set, sign users in through the load balancer withEnableUiPerUserRbac, so every console user gets their own role (see IAM and permissions). /metricsis never behind a token. It holds operational data, not log content, but you should still restrict who can reach port 18080 (see Network configuration).
Host hardening
The AMI runs the node as a dedicated system user with no login shell. Its systemd unit applies sandboxing:
NoNewPrivileges, an empty capability bounding set, andRestrictSUIDSGIDProtectSystem=strict, with write access only to OBSESC’s own data directoryProtectHome,PrivateTmp, and protected kernel tunables, modules and control groups- Network address families limited to
AF_UNIX,AF_INETandAF_INET6
The console is served by the node itself, so there is no separate web server. The built-in alerting component runs as its own non-login user and listens only on the loopback interface.
The stack takes no EC2 key pair and opens no SSH port. The node role carries the AWS-managed AmazonSSMManagedInstanceCore policy, so operators reach the node through AWS Systems Manager Session Manager. You can record those sessions with your own AWS logging.
Secrets handling
Tokens, keys and certificates don’t need to be stored in the node’s config file:
- Ingest and API tokens load from one Secrets Manager secret (stack parameter
AuthSecretArn) at startup. If the secret can’t be read, the node fails to start. - TLS certificates and keys load from SSM SecureString parameters (
TlsCertSsmParameter,TlsKeySsmParameter) at first boot. - The node role can read only the specific secret and parameters you name, and nothing else.
Tamper evidence
OBSESC offers optional custody verification, which lets you check that the records it keeps haven’t been altered. It is off by default. It makes tampering detectable, not impossible, and it doesn’t cover the raw events in your S3 bucket: protect those with S3 Object Lock. See Audit and verification.
Before production: hardening checklist
- Set
AuthSecretArnso the console and query API require authentication and enforce role-based access. - Put your ingest tokens, HEC tokens and Fluent shared key in that secret, and configure your shippers to send them.
- Set
TlsCertSsmParameterandTlsKeySsmParameterso the ingest listeners, the console and the query API serve TLS (see Encryption). - Narrow
AllowedIngestCidrto your shipper subnets, and restrict port 18080 further (see Network configuration). - Put the console behind the internal load balancer and turn on per-user sign-in with
EnableUiPerUserRbac. - Use a customer-managed KMS key whose key policy grants only the roles described in Encryption.
- Set
AlertmanagerEndpoint. OBSESC ships alert rules that deliver to your Alertmanager. Without it, the built-in alerts reach nobody. - If you need tamper evidence, turn on custody verification and use S3 Object Lock for the raw bucket.