Skip to content

Security: aliadiill/streamml

Security

docs/security.md

Security boundaries and reviewed limitations

Identity and access

I implemented Cognito authorization code with PKCE for application sign-in. The browser generates a random verifier and state, validates returned state and exchanges the code with a public client. Access tokens live in session storage, expire after 15 minutes, and are sent only to the application's API. I keep credentials and client secrets out of the frontend. Session storage still depends on preventing XSS; it is not an HttpOnly cookie.

I configured API Gateway to validate JWT issuer, audience/client and the streamml/read scope before invoking the metrics handler. The handler independently requires the validated subject claim. The user pool accepts administrator-created users only. The optional MFA configuration allows TOTP; enforcing MFA for every user is an operational hardening step.

I gave each Lambda a separate role. The ingest role can write canonical/quarantine objects, transact on the metrics table, consume the one stream and send failure metadata to one queue. The API role reads bounded metric keys and the timeline index. The monitor role can change only CONTROL-prefixed coordination records and read/write defined ML prefixes.

I scoped the SageMaker role so it can read the project's raw/ML objects and write ML outputs; it cannot administer IAM or unrelated buckets. Resource-name wildcards are needed for SageMaker's generated job identifiers. ECR authorization and scoped CloudWatch metric publication require wildcard resources; their rationale is visible in the policy. I have not yet run IAM simulation or full-stack live denial tests.

Storage, transport and network

I configured S3 buckets to block public access, use server-side encryption, retain versions and deny non-TLS requests. The website bucket grants read access only to its CloudFront distribution through origin access control. DynamoDB, SQS and Kinesis use encryption at rest. Kinesis uses the AWS-managed streaming key.

I configured the AWS dashboard for HTTPS, a restrictive response-header policy, frame denial, MIME sniffing protection, HSTS and same-origin API requests. There are no third-party scripts or remote fonts in the shipped interface. API access logs contain request ID, route, status and latency, not tokens.

I left custom VPC and NAT resources out of the design. Lambda calls managed regional endpoints through AWS's managed environment. SageMaker processing, training and model serving enable network isolation. The image uses only standard-library ML code and has no runtime package-download dependency.

Input and artifact controls

I bounded events to 16 KiB at ingestion and reject them for extra fields, malformed identifiers, invalid timestamps, non-finite values or out-of-range features. Conflicting event IDs cannot silently replace raw data. Quarantine stores only a record identifier and reason, not an arbitrary supplied payload.

I avoided pickle and execution of downloaded model code in the ML container. It loads bounded JSON coefficients and extracts only an expected regular tar member. Images are immutable source-tagged artifacts and scanned before deployment. I treat my structural review as a starting point; independent penetration testing and IAM Access Analyzer review remain future work.

Remaining security work

My remaining cloud security tests cover unauthorized API denial, JWT scope, bucket denial, restricted IAM, encryption and notification handling. Supply-chain locking includes npm's lockfile and Terraform's provider lock; Python cloud-client requirements use bounded ranges rather than a full transitive lock. For a longer-lived service, I would pin a reviewed Python lock and image digest, automate dependency review, enforce MFA and arrange an independent IAM/IaC assessment.

There aren't any published security advisories