Browse documentation

🧭 Start Here

Blackcap Overview ✨ Blackcap Feature Catalog Installation First Run

🚀 Deploy Blackcap

Platform Stacks and Raspberry Pi Hardware Raspberry Pi Deployment Raspberry Pi Client Services GCP Deployment Application Updates Environment Variables and Secrets Reverse Proxy and TLS Background Jobs and Schedules

🛠️ Administer Blackcap

Organizations Users, Permissions, and Authentication Configuration Workspace Backups and Restore Database Administration Regression Testing Performance and Job Status Audit, Access Activity, and Logging GeoIP and Access Location Data Retention and Purge Support Requests API Tester and Postman Instance Reporting

🍽️ Use Recipes

Recipes and the Recipe Library Recipe Import and Discovery Recipe Editing and Cache Artifacts Recipe Sharing Social Recipe Import AI Recipe Image Generation

📅 Plan Meals

Meal Planner

🛒 Use Shopping Lists

Shopping Lists and Shop a List External and Household Shopping 🧩 Chrome Extension Shop With

🧺 Manage Kitchen Inventory

🧺 Kitchen Inventory

🖥️ Use Displays

Displays and Connections Assigning and Scheduling Display Content Remote Pi Client E-Ink Rendering Menu Refresh and Rendering Noun Project Footer Images

🧑‍🍳 Cook with Let’s Cook

🧑‍🍳 Let’s Cook 🧑‍🍳 Let’s Cook Controls and Timers

🤖 Use and Administer AI

🤖 AI in Blackcap 🤖 AI Providers and Connections 🤖 AI Seeds and Usage

🧩 Use the Chrome Extension

🧩 Blackcap Chrome Extension 🧩 Chrome Extension Recipe Capture 🧩 Chrome Extension Shop With 🧩 Chrome Extension Release and Privacy

🎮 Play Games

🎮 Games and Trivia

🔌 Integrations

Email Integration Cloud Storage Integrations Voice Assistants Shop With Integrations Authentication Providers

⚙️ Develop Blackcap

Application Architecture Database Service and Data Access SQLite and PostgreSQL Database Migrations Background Job Architecture Testing API Architecture Security and Organization Scoping UI, Icons, and Documentation Assets Blackcap-Safe Emoji Documentation Standards Terminology

⚠️ Troubleshoot Blackcap

⚠️ Troubleshooting Deployment Troubleshooting Display Troubleshooting Recipe Import Troubleshooting 🤖 AI Troubleshooting Backup Troubleshooting Database Troubleshooting Diagnostic Organization Clones Support Requests

Security and Organization Scoping

Audience: Developer, System Admin, Support Related: Organizations · Users Permissions And Authentication · Database Service · Environment And Secrets

Security is enforced through authentication, account status, role permissions, Active Organization context, resource ownership, CSRF protection, rate limiting, safe external fetch rules, secret handling, provider request validation, and audit logging.

Organization-scoped queries must include organization identity explicitly. Platform-scoped settings and System Admin operations are exceptions that require deliberate authorization. User-global resources such as personal authentication state or personal AI Seeds must not be mistaken for organization-owned data.

Blackcap Pi treats operational/business content as organization-owned. This document summarizes the current scoping rules for Database Admin and the major data domains.


🔐 Core rule

Organization-scoped resources are visible and editable only in the active organization context.

  • Org admins see permitted resources for their own organization.
  • Lower roles see only the resources/actions allowed by their permissions.
  • System admins in the Default organization context see Default organization-scoped business data only.
  • A system admin must intentionally switch organization context to inspect or affect another organization.
  • Direct URLs, form values, and API/POST calls must not override the active context.

Platform/global resources remain system-admin-only where appropriate.


🗄️ Database Admin scope behavior

The Database Admin resource registry defines each resource's scope. Organization filtering is enforced by the provider/service layer for:

  • resource counts
  • resource lists
  • filter dropdowns
  • search results
  • detail drawer reads
  • safe edits
  • exports/direct route calls that use resource pages

Resources can be scoped by:

  • a direct organization_id-style column
  • a parent ownership join, such as shopping-list items through shopping lists
  • scoped settings columns, such as scope_type='organization' and scope_id=<active org>
  • organization key suffixes, such as recipe_cart:org:<organization_id> in app state

Organization-scoped provider queries fail closed if no active organization context is available.


✅ Resources explicitly treated as organization-scoped

The Database Admin registry treats these as organization-scoped when shown through Resource Explorer:

  • Recipes
  • Recipe Edit Content
  • Recipe Ingredients
  • Recipe Tags
  • Meal Planner Settings
  • Meal Slots
  • Meal Plan Entries
  • Meal Plan Shopping List Links
  • Shopping Lists
  • Shopping List Items
  • Shopping List Item Sources
  • Recipe Shares
  • Recipe Share Recipient Targets
  • Recipe Share Notifications
  • Recipe Share Consumptions
  • Recipe Share Audit
  • Background Jobs
  • Cache Status
  • Devices
  • Displays
  • Connections
  • Organization Memberships
  • Organization Backup Runs
  • Cloud Backup Provider Tokens
  • Cloud Backup State
  • Organization Noun Project Rules/cache resources
  • Settings where scope_type='organization'
  • Setting Audit Log rows where scope_type='organization'
  • App State rows whose keys belong to the active organization, such as recipe_cart:org:<organization_id>
  • Audit Log rows where organization_id is present

Platform/global resources include organizations, organization lifecycle events, setting definitions, connection types, provider configuration metadata, schema migrations, and platform-level emoji registry/cache data.


🍲 Recipes and recipe content

Recipes are scoped by organization_id + recipe_id. A recipe lookup by recipe_id alone is unsafe unless organization context is applied by the service.

Expected behavior:

  • same recipe_id can exist in multiple organizations
  • create/update/delete/cache-status lookup is organization-scoped
  • recipe image/PDF endpoints must resolve through the active organization or an authorized share token
  • recipe search and ingredient search are organization-scoped
  • recipe sharing/import writes new data into the recipient organization
  • recipe edit content and recipe ingredients are scoped directly or through recipe ownership

📅 Meal Planner

Meal Planner data is organization-owned. Settings, slots, entries, review/shopping-list generation, and move operations all resolve through the active organization context.

Expected behavior:

  • week start day and meal slot configuration belong to the active organization;
  • meal slots are not shared across organizations;
  • meal plan entries reference recipes using the current organization plus recipe id;
  • Recipe Discovery return context creates meal plan entries only in the active organization;
  • shopping lists generated from Meal Planner are created inside the active organization;
  • item/slot/day move endpoints cannot move records across organizations;
  • recipe archive/delete dependency checks consider only the current organization.

A system admin must switch organization context before viewing or managing another organization's meal plans. Forged organization_id, slot_id, entry_id, or recipe_id values should not override the active context.

🧂 Ingredients and canonical cleanup

Recipe ingredients and shopping-list items are organization-owned. Ingredient search/typeahead and canonical cleanup should stay inside the active organization.

Canonical maintenance now uses strict active-org filters. Missing organization context means no rows, not all rows.


🛒 Shopping lists and shopping-list items

Shopping lists are organization-owned by direct organization_id.

Shopping-list items are also organization-owned and are enforced in Database Admin with both:

  1. the item row's organization_id, and
  2. the parent shopping list's organization_id.

This defense-in-depth check prevents an orphaned or mismatched child row from leaking through Resource Explorer.


⚙️ Settings, Setting Audit Log, and App State

Settings and Setting Audit Log are not treated as platform-wide in Database Admin when they represent organization settings. Resource Explorer shows organization settings where:

scope_type = organization
scope_id = active organization id

System Admin users also see platform-scoped settings in the Settings resource so platform and active-organization settings can be reviewed together. That mixed view still does not include settings from other organizations unless the system admin intentionally switches organization context.

App State is organization-scoped when it stores operational state for an organization. The current recipe-cart app-state pattern uses keys like:

recipe_cart:org:<organization_id>

Platform/global app state should be represented separately and should stay system-admin-only. Platform settings are allowed in the System Admin Settings view, but only alongside the active organization's settings.


☁️ Backup and Noun Project data

Backup provider connections, encrypted provider token payloads, backup status/state, and backup run records are organization-scoped. The Default organization additionally shows full/platform backup runs in organization_backup_runs with backup_scope='platform'.

Noun Project API credentials are platform/provider configuration, but Noun Project keyword rules are organization-scoped rows in noun_project_rules. Downloaded icon files remain filesystem cache artifacts under noun_cache/ and org-specific subfolders.

👥 Users, security, and activity pages

The Admin Users, Security, and Activity pages use the same active-organization rule as Database Admin organization resources. A System Admin in the Default organization context sees Default users, tokens, invites, security activity, and audit events. To inspect another organization, the System Admin must intentionally switch organization context first. Org admins can view their organization's Security dashboard, including org user counts, Google-linked users, API-token status, and scoped security activity; platform security configuration links remain hidden from org admins.


🧪 Isolation test checklist

  • Org admin can see Settings, Setting Audit Log, Shopping List Items, and App State for their org.
  • Org admin cannot see another org's records through lists, details, search, filters, exports, or crafted URLs.
  • System admin in the Default organization context sees only Default organization-scoped business data, users, tokens, security activity, and audit events.
  • System admin sees platform settings together with active-org settings, without seeing settings from other organizations.
  • System admin switches context intentionally and then sees that selected org's business data and org-owned admin data.
  • Direct detail/edit calls with a forged organization_id do not override active context.
  • The same recipe_id can exist in two organizations and resolves only in active context.
  • Meal Planner settings, slots, entries, moves, review, and shopping-list generation stay in the active organization.
  • Recipe Discovery return context cannot create a meal plan entry in another organization.
  • Shopping-list items require both child and parent org ownership.
  • SQL Console is System Admin only. It allows read-only inspection of organization-scoped tables, but it does not automatically inject the active organization context; production queries should add explicit organization_id filters and exclude regression/diagnostic clone organizations when appropriate.
  • SQL Console can query tables that contain hidden/masked fields, but protected fields cannot be selected. Use explicit safe columns instead of SELECT * / alias.* for those tables.
  • Secret settings, token hashes/encrypted tokens, password hashes, provider config JSON, cloud-backup token payloads/state JSON, and token references are hidden or masked in Database Admin.
  • Recipe Library, recipe add/edit/delete, recipe sharing, shopping lists, completed shopping lists, cache queue, backup, mobile UI, and Chrome Extension still work.

🧹 Purge and organization isolation

Manual purge is scoped to the active organization context. A system admin in the default organization purges only default-organization records unless they intentionally switch organization context first. Org admins can purge eligible content in their own organization only.

Scheduled purge is controlled by platform-level configuration and iterates across all non-deleted organizations using the same retention rules. Purge ordering is domain-aware: shopping lists are evaluated before recipes so shopping-list references are cleaned before recipe parent records are removed.

On this page