Security Overview
v2.1 — September 2026SHIFT_ is built on Google Cloud infrastructure with multiple independent security layers protecting professional data. This document describes our security architecture for partners, professionals, and clients.
Executive Summary
SHIFT_ is built on Google Cloud infrastructure, using Firebase as its identity, database, and file storage layer, with all production services running on Google Cloud Run. The platform inherits enterprise-grade security guarantees from Google's infrastructure (SOC 2 Type II, ISO 27001, FedRAMP certified) while enforcing its own application-layer access controls, role-based permissions, and data isolation rules on top of that foundation.
Professional and client data — including contact information, service listings, client rosters, messages, and financial records — is protected by independent layers: Firebase Authentication, database security rules that scope every record to the people it belongs to, server-side authorization on every route that touches data, and role-based permissions in the AI assistant. Our database rules are regression-tested automatically on every change, and the platform went through a full pre-launch security review in September 2026.
1. Identity & Authentication
How Users Are Verified
- •Firebase Authentication handles all user identity — a Google-managed, battle-tested identity system. SHIFT_ does not store, handle, or transmit raw passwords.
- •Every authenticated request carries a Firebase ID Token — a signed JWT that expires after one hour. All API routes verify this token cryptographically before processing any request.
- •Unauthenticated requests to protected endpoints are rejected before any data query runs.
Role-Based Access Control (RBAC)
- •Every user account carries an explicit role: client, professional, organization, admin, or super-admin.
- •Role is verified server-side on every request — it cannot be elevated by a client-side payload.
- •Access to professional data is scoped to uid === professionalId. A professional can never query another professional's records by manipulating parameters.
Client Access Model (Invitation-Only)
Clients cannot self-register. Access requires a unique invitation code issued directly by a professional on the platform. Invitation codes are single-use, tied to a specific email address, and expire — fundamentally limiting the attack surface.
2. Database Security (Firestore)
Data is reached through two paths, each with its own enforcement:
Path 1 — Firestore Security Rules
When the web or mobile app reads the database directly, Google's servers enforce our rules — they cannot be bypassed from a browser or device. Records are scoped to the people they belong to: your own profile, the two parties to a booking, the participants of a conversation, the author and subject of a review. No one can change their own role or mark a payment as received on someone else's behalf.
Path 2 — Authenticated Server Routes
Operations that need privileged access run on our servers. Every such route verifies the caller's token itself, takes the acting user from that token — never from the request — and confirms they are a party to the booking, payment, or conversation involved.
Public directory data is served through server-side projections that return only what a directory needs — name, photo, sector, city — never contact details. Every change to our database rules runs through an automated test suite that checks both directions: legitimate flows must keep working, and cross-user reads, privilege escalation, and payment tampering must be refused.
3. API & Backend Security
Transport Security
All traffic is TLS 1.2+ encrypted in transit. Firebase Hosting, Cloud Run, and all API endpoints enforce HTTPS. WebSocket connections (voice sessions) use encrypted WSS.
API Authentication
Every protected request verifies the Firebase ID token before any handler runs. Token verification validates JWT signature, issuer, audience, and expiry against Google's public keys. Tokens are short-lived (1 hour). The acting user is always taken from the verified token — never from a user ID supplied in the request — and actions on a booking, payment, or conversation are refused unless the caller is a party to it.
Signed Sign-In Callbacks
Third-party connection flows (such as linking Google Calendar) carry a signed, short-lived state value, so an authorization can only complete for the account that started it.
Rate Limiting
The public-facing Agent Connect server enforces rate limits: 500 requests per 15 minutes globally, 60 per minute per IP on tool endpoints. AI endpoints on the web platform are rate-limited across all server instances, with input-length limits. Baseline defence against scraping, enumeration, and abuse.
Input Validation
The Python FastAPI backend uses Pydantic for all request body validation. Firestore queries use parameterised SDK calls — no raw query string construction, making traditional injection attacks structurally impossible.
CORS Restrictions
The messaging service allows cross-origin requests only from known origins: https://shiftsyndicate.ca and localhost:3000 (development only). All other origins are rejected before reaching any handler.
4. AI & Agent Shift Security
Key SectionAgent Shift (the AI assistant embedded in the platform) represents a distinct attack surface beyond traditional web security. The following controls prevent prompt injection, privilege escalation, and data exfiltration through the AI layer.
Prompt Injection Defence
Every Gemini session begins with a hardcoded server-side security instruction that cannot be overridden by user input. If a user attempts a jailbreak ("ignore previous instructions", "pretend you are a different AI"), the model is instructed to acknowledge and redirect — not comply. Message roles are structurally separate in the Gemini API; a user's chat input cannot modify or prepend to the system prompt.
Role-Scoped Function Registry
The AI does not have a general-purpose query interface. Every callable function is declared in a function registry that enforces role-based permissions at runtime. Before any function executes, is_function_allowed(function_name, role) is called — if the AI attempts to call a function outside its role's whitelist, the call is blocked and an access-denied response is returned. The AI cannot call a function not explicitly declared for its session's role.
Uid-Bound Tool Dispatch
All AI tool functions receive the authenticated user's uid as a pre-bound parameter at session initialisation — the user's chat message cannot supply or override this value. Even if a user typed "show me client data for uid=XXXX", the function would query Firestore using the server-bound uid of the authenticated session.
Conversation Ownership Enforcement
Every AI conversation is stored in Firestore with professional_id and client_id fields tied to the authenticated user's uid. Accessing a conversation requires matching uid — mismatches return HTTP 403 before any message content is loaded.
Agent Iteration Cap
The agentic loop is capped at 5 iterations per request, preventing a maliciously crafted prompt from causing the AI to run in an infinite function-call loop or trigger downstream operations repeatedly.
Voice Session Authentication
The voice WebSocket endpoint requires a valid Firebase ID token on connection upgrade. Unauthenticated WebSocket connections are rejected before an AI session is opened. Each voice session loads a role-specific tool set scoped to the authenticated user's uid.
AI Credential Isolation
The Gemini API key exists only in GCP Secret Manager and is injected into Cloud Run at runtime. It is never transmitted to the browser or included in any API response. All Gemini API calls originate from the server-side Python service.
Public AI Restrictions
The AI accessible to unauthenticated visitors uses a separate public role with access to only three functions: directory search (read-only), FAQ lookup, and contact info capture. A public session cannot read bookings, user records, financial data, or any authenticated data — enforced structurally by the role whitelist.
5. Secret Management & Payments
Secret & Credential Management
All production secrets (API keys, SMS credentials, Stripe keys, AI model keys) are stored in GCP Secret Manager or set directly on our Cloud Run services at runtime — never in source code or committed configuration files. A pre-commit scanner blocks credential-shaped values from entering the repository, history is scanned for the same patterns, and any credential that is ever exposed is rotated at the provider.
Payment Security
SHIFT_ never handles raw payment card data. All card collection and processing is handled by Stripe, a PCI DSS Level 1 certified payment processor. The platform stores only Stripe customer IDs and PaymentIntent IDs — not card numbers, CVVs, or account numbers. The client never touches the Stripe secret key.
6. Cloud Infrastructure
All compute runs on Google Cloud Run — fully managed, serverless containers. Each instance runs in its own isolated sandbox. Container images are built via Cloud Build and stored in Artifact Registry — not pulled from public Docker Hub.
GCP certifications that cover our infrastructure layer: SOC 1/2/3, ISO 27001, FedRAMP High, HIPAA, PCI DSS Level 1.
Firebase project access is controlled via Google Cloud IAM. Only the founding developers have project Owner access. Cloud Run services communicate with Firebase over Google's private internal network, not the public internet.
7. Monitoring & Incident Response
How a Data Breach Would Need to Happen
For an attacker to exfiltrate professional or client data at scale, they would need to succeed at one of:
- 1.Take over an administrator account — which requires compromising that person's Google or platform credentials, since roles cannot be changed from inside the app
- 2.Find a flaw in our database security rules — rules that are regression-tested automatically on every change
- 3.Find a server route that skips its authorization check — every data-touching route verifies the caller itself, and our routes were inventoried and re-tested in a pre-launch review
- 4.Compromise our Google Cloud project itself (requires project-level access, limited to the founding technical team)
For AI-specific attacks: a prompt injection attempt cannot escalate privileges because function access is enforced by a server-side role whitelist — not by the model's judgement. Even if the model were manipulated into trying to call an out-of-scope function, is_function_allowed() blocks the execution before any data query runs.
Security Questions
For third-party audits, formal penetration testing engagements, or security questions, contact the founding team:
security@shiftsyndicate.caSHIFT_ Security Overview v2.1 — September 2026 · SHIFT Syndicate Inc. · shiftsyndicate.ca