Lagniappe is designed to be installed as your own App Engine application, using your own Google Cloud project and Redis Cloud database. The most important security boundary is simple: the browser is a client, and the server is the authority.

A Lagniappe install does not depend on a centralized Lagniappe SaaS control plane. Your records, files, cache data, and provider accounts stay with the services you configure for your instance.

Security Model

Server-Enforced Access

Routes load entities on the server, check authentication and permissions, and render only the HTML or data the user may receive. Frontend code can hide controls for usability, but it is not the permission source of truth.

Provider-Owned Data

Datastore, Cloud Storage, App Engine, Identity Platform, Cloud Tasks, and optional AI services are in the operator’s Google Cloud project. Redis data lives in the Redis Cloud subscription selected during setup.

Going directly to Google Cloud removes one extra hosted application layer: there is no Lagniappe-hosted admin dashboard, tenant database, or licensing service that can inspect or mediate your instance. Google Cloud and Redis Cloud are still service providers, so protect those accounts and review their security settings when access changes.

Client and Server Split

Lagniappe uses server-rendered pages with JavaScript widgets layered on top. That shape is useful for security because private records are not shipped to the browser for the frontend to sort out later. The access decision is made once, on the server, before content is sent. Since the browser is never handed data it is not allowed to see, there is no client-side permission logic that can be bypassed or drift out of sync with the server.

  • Permission checks happen before rendering. Protected routes verify the current user and requested action before returning content.
  • Search and filters respect access. Restricted items are left out of rendered pages, search results, filter results, and direct route responses.
  • Mutations go through server routes. Forms, uploads, task changes, permissions, and settings changes use backend routes protected by CSRF and permission checks.
  • Cached pages still have server fingerprints. ETag values and service-worker invalidation headers help clients refresh stale private views after changes.

App Protections

HTTP and Browser Policy

  • Login cookies are configured defensively. They are set up to travel over HTTPS, resist ordinary JavaScript access, and avoid being sent too broadly in cross-site requests. The exact settings can be found in the Flask app configuration; MDN’s secure cookie guide explains the browser terms.
  • Form-changing requests include anti-forgery protection. This helps prevent a malicious site from tricking a signed-in user’s browser into submitting actions they did not intend. MDN has a plain overview of CSRF attacks.
  • Responses include browser security headers. Lagniappe sends HTTPS-only guidance through HSTS, framing and content-type protections, referrer limits, cache rules, and a Content Security Policy.
  • The Content Security Policy keeps the browser on a short leash. By default, resources come from this instance, with explicit allowances for the Google, Sentry, and YouTube no-cookie endpoints the app uses. Because the frontend is first-party JavaScript served from this instance rather than a large third-party framework bundle, that policy can stay narrow. MDN’s CSP guide is a good technical reference.

Auth and Internal Work

  • Identity Platform login tokens are checked for the exact project, issuer, and user before they become a Lagniappe session.
  • Google sign-in checks its anti-forgery token during the login flow.
  • Background jobs from Cloud Tasks must present a Google-signed identity token for the expected service account before process routes run.
  • Login routes slow down repeated attempts and validate redirect targets before sending a user onward.

Owner, Administrators, and Installation Secrets

Lagniappe has one configured primary Owner and may have additional Administrators. Administrators can operate the application, including ordinary Site Settings, user and group management, ingress, content, and content exports. AI entitlement remains a separate per-user choice.

The Owner alone changes the Administrator roster, changes or deletes an Administrator account, protects the canonical Owner account, and views or downloads installation configuration. That configuration can contain Redis passwords, API keys, SMTP credentials, and recovery material, so the Maintenance / Configuration control is not rendered for additional Administrators and its server routes reject them as well.

During a delegated installation, one exact saved installer email may use Google sign-in to create a temporary application Administrator only until the primary Owner’s first successful login. The email is never advertised on the public login page. Owner login closes automatic creation permanently; an already-created installer remains an Administrator until the Owner removes it. The later handoff deploy clears the saved bootstrap value before removing the installer’s managed cloud access.

Google Cloud Boundary

In the default production shape, Lagniappe runs on App Engine standard environment. App Engine is a managed Google Cloud runtime: Google runs the underlying infrastructure, starts and stops application instances, and isolates apps in the standard-environment sandbox. App Engine terminates HTTPS for app traffic, and the default Lagniappe configuration sends HSTS so browsers remember to use HTTPS for future requests. MDN’s HSTS reference explains the browser side of that header.

Google Cloud provides default encryption at rest for customer content and protects traffic moving within its infrastructure. Those provider controls reduce the infrastructure you have to operate yourself. The installer configures the access the application needs; protect the Google accounts that administer the project and review that administrator access when people or responsibilities change.

Datastore

Firestore in Datastore mode is the fully managed NoSQL database Lagniappe uses for entities and metadata. Google manages the service and encrypts the stored data at rest. Reference: Datastore overview.

Cloud Storage

Cloud Storage is the object store for uploaded files and generated assets. Objects are encrypted server-side before they are written to disk and decrypted for authorized reads. Reference: Cloud Storage encryption.

Redis Cloud Boundary

Lagniappe uses Redis for search indexes, filters, cache entries, rate limits, active viewer state, and collaboration/sync state. Redis should be treated as operational application data: it is not the long-term source of truth, but it can still contain meaningful names, keys, search text, session-adjacent state, and workflow context.

Redis Cloud is a hosted Redis service, but security is still shared responsibility. Redis operates the Redis Cloud software and platform, the selected cloud provider handles the underlying infrastructure, and the operator controls the plan, region, database security settings, credentials, connectivity, and what data is stored. Reference: Redis Cloud shared responsibility.

Think of Redis TLS as HTTPS for the server-to-server connection between Lagniappe and Redis Cloud. The Redis password is still required to authenticate the application. TLS adds another layer around that password-authenticated connection: it encrypts the traffic in transit and verifies that Lagniappe is talking to the expected Redis Cloud server. The password controls who may connect; TLS protects the connection carrying that password and the application data.

  • At rest: Redis Cloud supports encryption at rest for deployments, including databases hosted on Google Cloud.
  • In transit: Redis Cloud TLS encrypts application-to-database traffic when enabled. Paid Essentials/Flex and Pro plans can enable database TLS, but Free Essentials plans cannot. Lagniappe supports verified server TLS through its guided security setup.
  • Network exposure: Redis Cloud can use CIDR allow lists on supported plans, block public endpoints on Pro plans, and connect privately to Google Cloud through Private Service Connect. CIDR allow-list automation may be added later if there is demand, but it requires a stable App Engine outbound IP path through Google Cloud networking.
  • Current app boundary: Lagniappe connects to Redis from the server side on App Engine. That keeps Redis credentials out of the browser, but App Engine alone does not automatically make a Redis public endpoint private or encrypted in transit.
Run ./setup.sh security, or .\setup.cmd security in Windows PowerShell, to enable, refresh, or disable Redis TLS. Download the Redis Cloud certificate ZIP archive, unzip it, and place the extracted redis_ca.pem at config/files/redis_ca.pem. Setup verifies the server certificate and hostname, tests the new connection mode, and offers to redeploy. Mutual TLS client certificates are not currently supported, so leave that Redis Cloud option unchecked. CIDR allow lists and Private Service Connect remain advanced, operator-owned paths.

Redis references: encryption at rest, TLS, public endpoint blocking, CIDR allow lists, and Private Service Connect.

Optional Data Flows

  • Error reporting: Disabled unless the operator enables it during setup. The operator can send privacy-reduced reports to the maintainer or, after declining that destination, supply a DSN for their own Sentry project. When enabled, Lagniappe disables backend Sentry default PII collection, but may still attach diagnostic request or error context such as URL, endpoint, headers, form fields, JSON payloads, or file metadata. Read the maintainer error-reporting privacy notice before enabling the default destination.
  • Analytics: Optional Administrator-facing analytics can record page path, title, view type, referrer, navigation type, and user identifiers for authenticated visits.
  • AI generation observability: Setup explicitly offers the default-off AI_OBSERVABILITY choice. When enabled, it samples every text generation into an Administrator-only summary dataset. Records exclude prompts, generated text, tool arguments/results, messages, file content, and application identifiers; activity-driven cleanup deletes up to 500 records older than 30 days after each new summary, so stale records can remain when generation is inactive. SDK-internal retries are not visible.
  • AI and OCR: Vertex AI and Document AI receive the prompts, documents, images, or extracted context needed for the feature the user invokes.
  • Browser storage: The service worker caches app responses for responsiveness and offline behavior. The app can ask clients to clear cached Lagniappe responses after permission or content changes.
Optional integrations are part of the instance operator’s risk decision. If a field may contain sensitive information, assume it can appear in provider logs or diagnostics when a feature sends that field to a provider.

Owner Checklist

  • Use strong Google account protection and keep at least one recovery path for the Cloud project.
  • Give Lagniappe owner and administrative permissions only to people who need them, and review user and group access when responsibilities change.
  • Protect local settings files and recovery downloads; do not commit secrets to a public repository.
  • Review public pages, public files, public permissions, and group memberships from a non-owner account.
  • Decide whether optional analytics, AI generation observability, AI/OCR, and error reporting match your privacy expectations before enabling them.
  • For Redis, choose the strongest connectivity controls your plan supports and treat cache/search data as sensitive operational data.