A security-first connected-vehicle telemetry proof of concept built with Python, SQLite, AWS IoT Core, MQTT 5, mutual TLS, and infrastructure as code.
AutoShield Lab demonstrates how a fictional connected vehicle can produce validated telemetry, be checked against an authorised vehicle registry, trigger explainable security rules, and publish a tightly controlled message to AWS IoT Core.
The project was designed as a Solutions Architecture portfolio case study. It focuses on requirements, trust boundaries, least-privilege access, cost control, testability, and documented architectural decisions rather than on a generic CRUD application.
All vehicles, events, credentials, and scenarios used by the application are fictional or synthetic. AutoShield Lab never connects to a real vehicle or external target.
- A versioned telemetry contract rejects malformed or unsafe input.
- A local SQLite registry authorises only known vehicles with an active lifecycle status.
- Explainable detection rules identify authentication bursts and high battery temperature.
- Unknown or inactive vehicle identities are rejected before processing.
- A dedicated publishing boundary prevents vehicle and MQTT-topic mismatches.
- One fictional device authenticates to AWS IoT Core using an X.509 certificate and mutual TLS.
- Its IoT policy permits only the approved MQTT client ID and telemetry topic.
- Cloud publishing uses MQTT 5 with QoS 1 and a dynamically discovered regional endpoint.
- Infrastructure is reproducible through AWS CloudFormation.
- The automated suite completes with 28 tests and 4 subtests passing.
flowchart LR
S["Synthetic vehicle scenario"] --> V["Telemetry contract validation"]
V --> A["Vehicle registry authorisation"]
R[("SQLite vehicle registry")] --> A
A --> D["Explainable detection rules"]
D --> I["Local incident results"]
V --> P["Cloud publish authorisation"]
P --> M["MQTT 5 / mTLS / QoS 1"]
C["X.509 device certificate"] --> M
M --> AWS["AWS IoT Core - eu-west-2"]
CF["CloudFormation: Thing + least-privilege policy"] --> AWS
AWS --> T["AWS MQTT test client"]
The local security pipeline and cloud publishing proof share the same validated telemetry model. Detection remains local in this MVP; the AWS portion proves secure device identity, topic-level authorisation, and encrypted transport without adding databases, queues, or continuously running compute.
| Control | Implementation | Architectural purpose |
|---|---|---|
| Input trust boundary | Strict TelemetryEvent validation |
Reject malformed data before business processing |
| Vehicle authorisation | SQLite registry and lifecycle status | Prevent unknown, maintenance, or retired identities from being processed |
| Explainable detection | Deterministic rules with severity and evidence | Produce findings that an operator can understand and test |
| Publish authorisation | Vehicle ID, Thing name, client ID, and topic checks | Prevent confused-deputy and topic-substitution mistakes |
| Device authentication | One X.509 certificate attached to one fictional Thing | Give the demonstration vehicle a distinct machine identity |
| Least privilege | Exact iot:Connect and iot:Publish resource ARNs |
Permit only the intended client ID and telemetry topic |
| Transport security | MQTT 5 over mutual TLS | Encrypt traffic and authenticate both sides of the connection |
| Secret handling | Certificates and keys stored under Git-ignored data/ |
Keep private key material out of source control |
| Cost boundary | One Thing, one policy, one certificate, manual one-message demo | Avoid continuously running or unnecessary cloud resources |
The IoT policy intentionally does not grant subscribe, receive, wildcard publish, fleet-wide access, or administrative actions.
The repeatable local demonstration covers three outcomes:
- Normal telemetry - accepted with no incident.
- Suspicious telemetry - accepted and evaluated into two explainable incidents:
- authentication failure burst;
- high battery temperature.
- Identity impersonation - rejected because the claimed vehicle is not registered.
The cloud demonstration publishes one validated synthetic event to:
autoshield/vehicles/autoshield-demo-vehicle-001/telemetry
The client certificate cannot connect using a different client ID or publish to a different topic.
Account identifiers and local usernames are redacted. No endpoint, access token, certificate, or private key is included in these images.
- Python 3.13 - domain logic, validation, detection, orchestration, and demos
- SQLite - zero-cost local vehicle registry with database constraints
- pytest and unittest - automated behaviour and transport-boundary testing
- AWS IoT Device SDK v2 - MQTT 5 mutual-TLS connectivity
- AWS IoT Core - managed device gateway and policy enforcement
- AWS CloudFormation - reproducible IoT Thing and policy configuration
- Git - milestone-based development and architectural history
- Python 3.13 or later
- Git
PowerShell example:
git clone https://github.com/arshhunerkar-security/AutoShield-Lab.git
cd AutoShield-Lab
python -m venv .venv
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"Run the automated suite:
python -m pytest -qRun the local security demonstration:
python -m autoshield_lab.demoThe local demonstration is repeatable and requires no AWS account.
The cloud proof is deliberately optional. The core application and tests work entirely locally.
Before using it:
- Review
infra/README.mdand the cost-control ADR. - Use an IAM identity rather than the AWS root user.
- Deploy only the provided CloudFormation stack in the intended Region.
- Create a dedicated demonstration certificate and keep its private key under
data/. - Subscribe the AWS MQTT test client to the exact AutoShield telemetry topic.
- Run the cloud demo once, capture the result, and clean up the AWS resources when finished.
Example after secure local certificate setup:
$autoShieldEndpoint = (aws iot describe-endpoint `
--endpoint-type iot:Data-ATS `
--query "endpointAddress" `
--output text `
--region eu-west-2 `
--profile autoshield-admin).Trim()
python -m autoshield_lab.cloud_demo --endpoint $autoShieldEndpointNever commit certificate files, private keys, cached AWS credentials, account identifiers, or endpoint values.
AutoShield-Lab/
|-- docs/
| |-- adr/ # Architecture decision records
| |-- assets/ # Redacted portfolio evidence
| |-- CLEAN_ROOM.md # Synthetic-data safety boundary
| |-- DETECTION_RULES.md # Rule definitions and thresholds
| `-- TELEMETRY_CONTRACT.md # Event schema and validation contract
|-- infra/
| |-- iot-core.yaml # Cost-controlled IoT infrastructure
| `-- README.md # Deployment and cleanup guidance
|-- src/autoshield_lab/
| |-- cloud_demo.py # One-message cloud demonstration
| |-- cloud_publisher.py # Publishing authorisation boundary
| |-- database.py # SQLite initialisation
| |-- demo.py # Repeatable local scenarios
| |-- detection.py # Explainable security rules
| |-- mqtt_transport.py # MQTT 5 mutual-TLS transport
| |-- pipeline.py # Authorised processing pipeline
| `-- telemetry.py # Validated telemetry domain model
|-- tests/ # Local and mocked transport tests
`-- pyproject.toml # Package and test configuration
ADR-001: Vehicle-status authorisationexplains why registry status is enforced before detection.ADR-002: Free-plan cost guardrailsrecords the intentionally small AWS footprint and excluded services.TELEMETRY_CONTRACT.mddefines the accepted event boundary.DETECTION_RULES.mddocuments thresholds, severity, and rule behaviour.
The automated tests cover:
- database constraints and repeatable initialisation;
- telemetry validation and serialisation;
- known, unknown, active, maintenance, and retired vehicle states;
- detection thresholds and multi-incident events;
- pipeline acceptance and rejection outcomes;
- publish-topic and identity authorisation;
- MQTT configuration, success, failure, and cleanup paths;
- local and cloud-demo orchestration.
Cloud transport tests use controlled fakes, so pytest does not create AWS traffic or require credentials. The screenshots document the separate manual end-to-end proof.
- SQLite instead of a managed database: sufficient for deterministic local learning and zero-cost testing; not intended for fleet-scale concurrency.
- Deterministic rules instead of machine learning: easier to explain, verify, and audit for an MVP.
- One certificate and one Thing: demonstrates device identity and least privilege while limiting cost and operational risk.
- No cloud persistence or compute: avoids claiming an ingestion platform that the MVP does not implement and prevents idle resources.
- Manual certificate lifecycle: acceptable for one demonstration device; production fleets require automated provisioning, rotation, revocation, and audit processes.
AutoShield Lab is a portfolio proof of concept, not a production vehicle-security product. It does not currently provide:
- real-vehicle or CAN-bus integration;
- cloud-side storage, stream processing, dashboards, or alert delivery;
- automated certificate provisioning and rotation;
- multi-account or multi-Region resilience;
- production observability, SLOs, or incident-management integrations;
- a formal automotive safety or cybersecurity certification.
These boundaries are deliberate and keep the repository safe, reproducible, and honest about its scope.
- Add a threat model and data-flow diagram.
- Add CI for automated tests and secret scanning.
- Introduce pluggable local persistence for incidents.
- Design a cost-estimated cloud ingestion option using managed, event-driven services.
- Define certificate provisioning, rotation, revocation, and fleet onboarding workflows.
- Add operational metrics, alarms, retention requirements, and recovery objectives.
All vehicles, electronic control units, messages, events, and telemetry in this repository must remain fictional and synthetic. See docs/CLEAN_ROOM.md for the complete rules.

