Confidential — Shared under NDA · Do Not Distribute
Document Architecture & Security Overview Version 1.0 Date 2026-06-23 Classification Confidential Owner Road Protect — Platform Engineering Intended audience Partner / external integrator security & architecture reviewers Status Approved for NDA distribution
This document describes the production architecture and security posture of the Road Protect Fleet platform for an external organisation evaluating a partnership or integration. It is written for a technical audience — security reviewers, solution architects, and engineering leads — and is intended to answer the questions a vendor due-diligence or onboarding process typically raises.
What this document is. A faithful, high-level description of how the system is built and protected: where it runs, how clients authenticate, how data and documents are stored, how the database is managed, how secrets are handled, how software is built and shipped, how activity is audited, and how a request flows end-to-end.
What this document is not. It contains no secrets, credentials, private keys, connection strings, or exploitable configuration values. Where a control has a tunable parameter (token lifetimes, cryptographic cost factors, specific managed-rule identifiers, rate-limit thresholds), the document describes the mechanism and its security property rather than the exact value, in line with responsible-disclosure practice for externally shared material.
How to read the diagrams. Diagrams follow the C4 model convention — System Context first, then Containers (deployable units), supported by data-flow and sequence diagrams. Trust boundaries are drawn as dashed groupings. Every diagram is rendered in Mermaid and is reproducible from the source of this document.
Confidential — Shared under NDA · Do Not Distribute
Road Protect Fleet is a cloud-native, multi-tenant SaaS platform that helps fleet operators and their partners manage traffic infringements end-to-end: ingesting and normalising fines onto a canonical data model, attributing them to vehicles, drivers and contracts, and driving downstream workflows such as nomination, appeal and payment automation.
The platform runs entirely on Google Cloud Platform (GCP) in the europe-west1 region (EU data residency), on a managed Kubernetes foundation (Google Kubernetes Engine) for the core microservices and on Cloud Run for the web UI. It is delivered through a GitOps continuous-delivery pipeline and operated under a defense-in-depth security model.
Security highlights covered in this document:
The remainder of the document walks the system top-down (Context → Containers), then through each control domain, and closes with a shared-responsibility matrix and compliance posture.
Confidential — Shared under NDA · Do Not Distribute
Road Protect Fleet is the core platform that manages infringements and fleets. It is complemented by an automation engine — an internal integration service that automates submission and payment workflows and returns their results to the platform asynchronously. The two communicate over authenticated HTTPS using a shared API key (see §5.5).
| Dimension | Detail |
|---|---|
| Cloud provider | Google Cloud Platform (GCP) |
| Region | europe-west1 (EU — single-region residency for primary data) |
| Core compute | Google Kubernetes Engine (GKE) — managed Kubernetes, private node pools, autoscaling |
| Web UI | Cloud Run (fully managed, serverless containers) |
| Primary database | Cloud SQL for PostgreSQL 15 (regional, high-availability) |
| Object storage | Google Cloud Storage (private buckets) |
| Analytics store | BigQuery (audit & reporting) |
The platform exposes its user-facing surface at a single public hostname, TLS-terminated by a Google-managed certificate:
| Surface | Domain | Hosting |
|---|---|---|
| Web UI | fleet-v2.roadprotect.co.il |
Cloud Run |
The UI is a server-rendered web application that calls the platform API over HTTPS. The API is fronted by the managed edge described in §4 (global load balancer + Cloud Armor WAF), and its CORS policy allowlists the permitted UI origins.
The platform runs as fully isolated environments — a production environment and a staging environment — on separate Kubernetes clusters, with separate databases, separate secrets, separate edge load balancers, and separate WAF policies. Code is promoted to production only after passing through staging. This separation is enforced structurally by the GitOps delivery model (§10), not by convention.
The platform is multi-tenant. Each customer (a Partner, and the Accounts/companies beneath it) is a logical tenant. Tenant isolation is enforced at the application layer: every authenticated request carries the caller's account context, and data-access queries are scoped to that context (see §6). Administrative roles that legitimately cross tenant boundaries are themselves audited (see §11).
Figure 2.1 — C4 System Context. Who and what interacts with the platform, and where it runs.
Confidential — Shared under NDA · Do Not Distribute
The platform follows a containerized microservices architecture orchestrated by Kubernetes. Each service is a single-purpose, independently deployable unit with a well-defined interface; services communicate over the cluster's private network, and only a curated subset is exposed publicly through the edge. State is externalised to managed services (database, object storage, cache), so application containers are stateless and horizontally scalable.
| Container (role) | Responsibility | Exposure |
|---|---|---|
| API service | Core REST API and business logic (NestJS) | Public, via WAF |
| Slow-query API | Isolated pool for heavy/long-running queries and exports | Public, via WAF |
| Web UI | Server-rendered front end | Public, via Cloud Run |
| Queue workers | Asynchronous background jobs (queue-driven) | Internal only |
| Scheduler | Time-based jobs (scheduled exports, maintenance) | Internal only |
| Messaging gateway | Outbound SMS / one-time-password delivery | Internal only |
| Document services | Document storage, rendering and OCR | Internal only |
| Analytics | Self-service reporting (Metabase) | Public, via WAF |
| Integration/automation engine | Browser-based workflow automation | Internal |
| Cache & queue backing store | In-cluster cache and job-queue state (Redis) | Internal only |
Managed GCP services underpin the containers: Cloud SQL (PostgreSQL) for transactional data, Cloud Storage for documents, BigQuery for audit/analytics, Secret Manager for secrets, and Artifact Registry for container images.
Figure 3.1 — C4 Container view. Deployable units, their exposure, and the managed services they depend on.
Confidential — Shared under NDA · Do Not Distribute
All external traffic enters through a single, hardened edge. The platform uses the Kubernetes Gateway API with Google's global external Application Load Balancer, fronted by Google Cloud Armor as the Web Application Firewall.
Figure 4.1 — Edge request path. Each stage is an independent control.
GKE runs with private node pools inside a dedicated Virtual Private Cloud (VPC). The database is reached over private VPC networking, not the public internet. Only services explicitly bound to an edge route are publicly reachable; all other services (workers, scheduler, messaging gateway, document/OCR services, cache) are cluster-internal only and have no public address.
Real-time features use WebSocket connections; the load balancer applies session affinity so a client's socket pins to a single backend instance for its lifetime, and WebSocket frames bypass payload inspection that would otherwise break the protocol — a deliberate, scoped carve-out rather than a blanket exception.
Confidential — Shared under NDA · Do Not Distribute
Authentication answers "who is calling?" The platform supports three caller classes — interactive human users, administrative/programmatic users, and partner integrations — each with an appropriate mechanism.
Users authenticate with an email/identifier and password over HTTPS. To avoid ever transmitting a plaintext password, the client hashes the password before it leaves the browser; the server then re-hashes that value with a salted, adaptive algorithm before comparison. Failed-attempt account lockout, optional CAPTCHA, and rate limiting protect the login endpoint against credential-stuffing and brute-force attacks.
| Property | Approach |
|---|---|
| In transit | TLS 1.2+, plus a client-side hash so the raw password is never sent |
| At rest | Salted, adaptively-hashed (bcrypt family) with a per-user salt and an industry-standard cost factor |
| Rehashing | Stored hashes are transparently upgraded to the current cost factor on successful login |
| Rotation | Password-age policy with proactive reminders before expiry |
| Reuse | The current password cannot be re-set to itself |
| Recovery | Password-reset and forced-change flows use a separate, short-lived, single-purpose token |
Plaintext passwords are never stored, never logged, and never recoverable — only verifiable.
Once authenticated, the user receives a signed JSON Web Token (JWT) that represents their session.
Bearer token (Authorization header) or as a hardened cookie — HttpOnly, Secure (HTTPS-only), and SameSite=Strict, which neutralises cross-site request forgery for the cookie path.Figure 5.1 — Login + 2FA sequence.
The platform provides two strong second factors, both standards-based:
2FA is opt-in per user, with the ability for administrators to require it for specific users or globally. A trusted-device option lets a user skip the second factor on a recognised device for a bounded period; trusted-device tokens are stored only as hashes and are revoked automatically on password change. The 2FA challenge itself is carried by a scoped, short-lived token that cannot be used as a full session token.
Machine-to-machine integration — including the platform↔automation-engine channel and inbound partner webhooks — is authenticated with a static API key presented in the x-api-key header over HTTPS. The key is a shared secret managed exclusively through Secret Manager (never in code or images), validated server-side on every integration request, and scoped to the specific integration endpoints. This is the integration mechanism for external systems working with the platform.
Beyond the edge rate limiter, the API enforces action-aware rate limits (e.g. stricter limits on login, password-reset, and OTP endpoints than on ordinary reads), keyed by authenticated user or source IP, returning standard 429 responses with rate-limit headers. This is a defense-in-depth complement to the WAF.
Confidential — Shared under NDA · Do Not Distribute
Where authentication establishes who is calling, authorization decides what they may do.
The platform implements role-based access control (RBAC) with database-driven roles and granular permissions, evaluated per request:
Multi-tenant isolation is enforced in the application's data-access layer: every query is scoped to the caller's account context derived from the validated session, and resource-ownership guards verify that a requested object belongs to the caller's tenant before it is returned or mutated. Cross-tenant access is possible only for explicitly privileged administrative roles, and every such access is recorded in the audit trail.
Support and administrative workflows may impersonate a user to reproduce an issue. Impersonation is first-class and fully audited: the acting administrator's identity is embedded in the session and carried into every audit record produced during the impersonated session, so the real actor behind every action is always attributable.
Figure 6.1 — Authorization decision path: authenticate → permission → tenant ownership.
Confidential — Shared under NDA · Do Not Distribute
The platform handles two broad data categories: structured transactional data (in PostgreSQL, §8) and unstructured documents — infringement images, appeal PDFs, identity/licence uploads, payment receipts, and nomination documents — in Google Cloud Storage (GCS).
| Control | How it is applied |
|---|---|
| Private by default | Document buckets are private — no anonymous or public access. |
| Uniform bucket-level access | Access is governed purely by IAM (no per-object ACLs), giving one consistent, auditable access model. |
| Public Access Prevention | Enforced on document buckets, so a misconfiguration cannot accidentally expose objects to the internet. |
| Encryption at rest | All objects are encrypted at rest with Google-managed AES-256 keys. |
| Least-privilege identities | Each workload uses a dedicated service-account identity granted only the storage role it needs (e.g. read-only for receipt consumers). |
| No direct browser access | Buckets are never exposed to browsers directly. |
Documents reach authorised users through two controlled paths, never by exposing a bucket:
Content-Disposition/no-sniff headers to prevent content-type confusion.Object keys are randomised (UUID-based) and sanitised to prevent path-traversal; the receipt-fetch path is locked to a single, explicitly-allowlisted bucket.
User uploads are validated for type and size (MIME allowlists, size caps) before storage, with an optional antivirus-scanning stage available in the pipeline. Bulk/spreadsheet uploads are processed through validated, idempotent pipelines with per-row error handling.
When documents were migrated to GCS, each object was uploaded with server-side checksum validation, then re-read and verified for both checksum and byte-size match against the source before the record was switched over — an integrity guarantee that remains the pattern for document writes.
Figure 7.1 — Document upload and controlled serving. The bucket is never public.
Confidential — Shared under NDA · Do Not Distribute
The system of record is Cloud SQL for PostgreSQL 15 — a fully managed relational database. Choosing a managed service means a large class of security and reliability controls are provided out of the box by the cloud provider, under a shared-responsibility model (§13).
| Capability | Benefit |
|---|---|
| Encryption at rest | All data and backups encrypted with Google-managed AES-256 keys, automatically. |
| Regional high availability | A synchronous standby in a second zone with automatic failover — no single-zone outage takes the database down. |
| Automated backups | Scheduled daily backups with multi-day retention, plus transaction-log retention, managed by the platform. |
| Automatic patching | The provider applies minor-version patches and security fixes during maintenance windows — no unpatched database drift. |
| Private networking | The database is reached over a private VPC path from the application cluster. |
| IAM-governed administration | Administrative access is governed by cloud IAM and logged in cloud audit logs. |
| Monitoring & insights | Built-in metrics, query insights, and alerting integrate with the platform's observability stack. |
503 + Retry-After responses rather than cascading failures.Figure 8.1 — Managed PostgreSQL: HA topology, private connectivity, role separation, and backups.
Confidential — Shared under NDA · Do Not Distribute
The platform's guiding rule is simple: no secret ever lives in source code, in a container image, or in a manifest. All secrets are centralised in Google Secret Manager and delivered to workloads at runtime.
Figure 9.1 — Secret delivery: Secret Manager → External Secrets Operator → Kubernetes Secret → pod.
This model means a leaked manifest, repository, or container image yields no usable secret.
Confidential — Shared under NDA · Do Not Distribute
The platform is built and shipped through an automated, auditable pipeline combining GitHub Actions (continuous integration) and Argo CD (GitOps continuous delivery). The defining property is that the desired state of production is whatever is committed to Git — deployments are reconciliations toward a reviewed, version-controlled state, not imperative pushes.
Figure 10.1 — CI → image build → GitOps reconciliation → migrate → rollout → verify.
Confidential — Shared under NDA · Do Not Distribute
Security- and business-sensitive actions are recorded to an immutable audit trail. Auditing is applied deliberately to the endpoints that matter — authentication and 2FA events, user/account changes, bulk uploads, contract/vehicle/infringement/payment/nomination mutations, partner webhooks, and administrative actions — capturing:
Audit records are written on a non-blocking path so auditing never degrades request latency, and personally-identifiable information is redacted from captured payloads before persistence, with the redaction explicitly recorded.
Figure 11.1 — Audit data flow: capture → hot store → 5-minute export → analytics store.
The hot tier (PostgreSQL) keeps recent records for fast operational queries; a scheduled job exports new records to BigQuery every few minutes for long-term, queryable retention, after which aged hot-tier rows are pruned. Access to the audit data is itself restricted to authorised administrators.
The platform emits structured logs to Cloud Logging (with a sink into BigQuery for analysis), application performance telemetry to an APM tool, and metrics to Cloud Monitoring. Alerting policies are maintained as code and route to the operations team's chat channels — covering edge/WAF blocks, certificate expiry, error-rate and resource thresholds, and queue health.
Confidential — Shared under NDA · Do Not Distribute
This section ties the controls together by following a single authenticated API request from the client to the database and back, naming the security checkpoint at each hop.
Figure 12.1 — End-to-end request lifecycle with security checkpoints and the trust boundary.
Walkthrough.
503 + Retry-After.Confidential — Shared under NDA · Do Not Distribute
Running on a managed cloud means security is a shared responsibility. The matrix below makes the boundary explicit — the single most important thing for a partner to understand.
| Layer | Google Cloud (provider) | Road Protect (vendor) | Partner / customer |
|---|---|---|---|
| Physical data centres, hardware | ✅ | ||
| Hypervisor, managed-service internals | ✅ | ||
| Network backbone, DDoS scrubbing | ✅ | (configures Cloud Armor) | |
| Database engine patching, encryption-at-rest, backups | ✅ | (configures HA, retention) | |
| OS / container runtime (GKE-managed) | ✅ (node OS) | (workloads) | |
| Application code & business logic | ✅ | ||
| Authentication, RBAC, tenant isolation | ✅ | ||
| Data classification & secrets configuration | ✅ | ||
| IAM, network & WAF configuration | ✅ | ||
| End-user / integration credentials | (enforces policy) | ✅ | |
| Their data & how it is used | (processes per agreement) | ✅ | |
| 2FA enrolment for their users | (provides capability) | ✅ |
By building on GCP, the platform inherits the provider's certified infrastructure controls (Google Cloud maintains SOC 1/2/3, ISO 27001/27017/27018, PCI DSS and other attestations at the infrastructure layer). The platform's own controls — described throughout this document — sit on top of that foundation.
| Area | Posture |
|---|---|
| Data residency | Primary data and backups in the EU (europe-west1). |
| Encryption in transit | TLS 1.2+ for all external traffic; internal traffic on a private VPC. |
| Encryption at rest | Google-managed AES-256 for database, object storage, and backups. |
| Vulnerability management | Weekly dependency auditing and DAST against staging; PR-gating secret scanning; container-image vulnerability scanning. |
| Secrets | Centralised in Secret Manager; no secrets in code/images; federated (key-less) access. |
| Access control | RBAC, least-privilege roles, account-scoped tenant isolation, audited admin access. |
| Auditability | Immutable, PII-redacted audit trail with multi-year retention in BigQuery. |
| Resilience / DR | Regional HA database with automatic failover; automated backups; zero-downtime rolling deploys; isolated staging environment. |
| Change management | GitOps — every production change is a reviewed, attributable, reversible commit. |
The platform's primary subprocessor is Google Cloud Platform (hosting, database, storage, analytics, secrets). Outbound SMS delivery uses a telephony provider via the internal messaging gateway. A current subprocessor list and the SOC 2 report of the underlying cloud provider can be made available under NDA on request.
Confidential — Shared under NDA · Do Not Distribute
| Concern | Technology |
|---|---|
| Core API | NestJS (Node.js / TypeScript) |
| Web UI | Server-rendered React (Next.js) on Cloud Run |
| Database | Cloud SQL for PostgreSQL 15 (regional HA), TypeORM |
| Object storage | Google Cloud Storage |
| Analytics / audit store | BigQuery |
| Cache & job queue | Redis (in-cluster) |
| Orchestration | Google Kubernetes Engine (GKE) |
| Serverless UI runtime | Cloud Run |
| Edge / WAF | Gateway API + global L7 ALB + Cloud Armor |
| TLS | Google Certificate Manager (managed certs) |
| Secrets | Secret Manager + External Secrets Operator + Workload Identity |
| CI | GitHub Actions |
| CD / GitOps | Argo CD |
| Container registry | Artifact Registry |
| 2FA | WebAuthn passkeys + SMS OTP |
| Observability | Cloud Logging, Cloud Monitoring, APM |
A simplified view of the canonical domain model. Column lists are illustrative, not exhaustive.
Figure 14.1 — Canonical data model (high-level). Tenancy roots at Partner → Account; inbound records enter as Raw Infringements and are mapped onto canonical Infringements.
| Term | Meaning |
|---|---|
| GKE | Google Kubernetes Engine — managed Kubernetes. |
| Cloud Run | GCP serverless container runtime. |
| Cloud SQL | GCP managed relational database. |
| GCS | Google Cloud Storage — object storage. |
| WAF | Web Application Firewall (Cloud Armor). |
| OWASP CRS | OWASP Core Rule Set — managed WAF rules. |
| JWT | JSON Web Token — signed session token. |
| WebAuthn / passkey | FIDO2 phishing-resistant public-key authentication. |
| OTP | One-time password. |
| RBAC | Role-based access control. |
| GitOps | Git as the source of truth for deployed state (Argo CD). |
| ESO | External Secrets Operator. |
| Workload Identity | Key-less federated identity for GKE workloads. |
| HA / failover | High availability with automatic standby promotion. |
| DAST | Dynamic Application Security Testing. |
| PII | Personally Identifiable Information. |
Detailed evidence — the underlying cloud provider's SOC 2 report, a current subprocessor list, and environment-specific configuration — is available to the partner's security team under NDA through the Road Protect engineering contact.
Confidential — Shared under NDA · Do Not Distribute Road Protect Fleet — Architecture & Security Overview · v1.0 · 2026-06-23