[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"portal-settings:stajic:en":3,"public-menus:all":38,"post:rbac-vs-tenant-isolation-two-different-security-boundaries:en":205,"related:post:rbac-vs-tenant-isolation-two-different-security-boundaries:en:1":2039},{"statusCode":4,"data":5,"message":37},200,{"tenantId":6,"lang":7,"defaultLang":8,"siteUrl":9,"contactEmail":10,"brandName":11,"logoUrl":12,"siteName":11,"siteDescription":13,"ogImage":10,"robotsIndex":14,"socialLinks":10,"reservedSlugs":10,"seoPolicy":15},"stajic","en","de","https:\u002F\u002Fstajic.de",null,"Stajic Platform","\u002FLogo_Planet.svg","Stajic Portal",true,{"branding":16,"relatedContent":17,"crossDomainLinks":18},{"logoUrl":12},{"enabled":14},[19,22,25,28,31,34],{"url":20,"label":21,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Ffigure.rocks","figure.rocks",{"url":23,"label":24,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Floving.rocks","loving.rocks",{"url":26,"label":27,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Fbazify.com","bazify.com",{"url":29,"label":30,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Fbazify.de","bazify.de",{"url":32,"label":33,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Fbazify.at","bazify.at",{"url":35,"label":36,"isActive":14,"showInFooter":14,"includeInSameAs":14},"https:\u002F\u002Fbazify.ba","bazify.ba","Portal settings resolved",[39,45],{"id":40,"name":41,"location":42,"isActive":14,"isDefault":43,"items":44},1,"main-navigation","header",false,[],{"id":46,"name":47,"location":48,"isActive":14,"isDefault":14,"items":49},4,"main-menu","sidebar",[50,66,79,93,103,118,133],{"id":51,"title":52,"url":60,"target":61,"icon":62,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":64,"portfolioId":10,"children":65},"item-18",{"de":53,"en":54,"es":55,"fr":56,"it":54,"ru":57,"sr":58,"zh":59},"Startseite","Home","Inicio","Accueil","Главная","Почетна","首页","\u002Ffull-stack-web-developer-munich-performance-seo-and-maintainable-builds","_self","i-lucide-home","page",111,[],{"id":67,"title":68,"url":75,"target":61,"icon":76,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":77,"portfolioId":10,"children":78},"item-22",{"de":69,"en":69,"es":70,"fr":69,"it":71,"ru":72,"sr":73,"zh":74},"Vision","Visión","Visione","Видение","Визија","想象","\u002Fueber-uns-webdesign-muenchen-webaplikation","i-lucide-eye",113,[],{"id":80,"title":81,"url":89,"target":61,"icon":90,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":91,"portfolioId":10,"children":92},"item-19",{"de":82,"en":83,"es":84,"fr":83,"it":85,"ru":86,"sr":87,"zh":88},"Leistungen","Services","Servicios","Servizi","Услуги","Услуге","服务","\u002Fservices-dienstleistungen-muenchen","i-lucide-wrench",116,[],{"id":94,"title":95,"url":99,"target":61,"icon":100,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":101,"portfolioId":10,"children":102},"item-23",{"de":96,"en":96,"es":96,"fr":96,"it":96,"ru":97,"sr":97,"zh":98},"Blog","Блог","博客","\u002Fblog","i-lucide-book-open",112,[],{"id":104,"title":105,"url":114,"target":61,"icon":115,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":116,"portfolioId":10,"children":117},"item-32",{"de":106,"en":107,"es":108,"fr":109,"it":110,"ru":111,"sr":112,"zh":113},"Neue Technologien","New Technologies","Nuevas tecnologías","Nouvelles technologies","Nuove tecnologie","Новые технологии","Нове технологије","新技术！","\u002Fneue-webtechnologien","i-lucide-sparkles",122,[],{"id":119,"title":120,"url":129,"target":61,"icon":130,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":131,"portfolioId":10,"children":132},"item-20",{"de":121,"en":122,"es":123,"fr":124,"it":125,"ru":126,"sr":127,"zh":128},"Kontakt","Contact us!","Contacto","Contact","Contatto","Контакт","Контактирајте нас","联系我们！","\u002Fcontact","i-lucide-mail",115,[],{"id":134,"title":135,"url":144,"target":61,"icon":145,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":146,"portfolioId":10,"children":147},"item-21",{"de":136,"en":137,"es":138,"fr":139,"it":140,"ru":141,"sr":142,"zh":143},"Unsere Arbeit","Our Work","Nuestro trabajo","Nos réalisations","I nostri lavori","Наши работы","Наши радови","文件夹","\u002Fportfolio","i-lucide-briefcase",114,[148,161,175,181,193],{"id":149,"title":150,"url":144,"target":61,"icon":159,"isActive":14,"type":63,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":146,"portfolioId":10,"children":160},"item-24",{"de":151,"en":152,"es":153,"fr":154,"it":155,"ru":156,"sr":157,"zh":158},"Alle Projekte","All Projects","Todos los proyectos","Tous les projets","Tutti i progetti","Все проекты","Сви пројекти","所有项目","i-lucide-grid-3x3",[],{"id":162,"title":163,"url":171,"target":61,"icon":172,"isActive":14,"type":173,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":10,"portfolioId":10,"children":174},"item-29",{"de":164,"en":165,"es":166,"fr":167,"it":168,"ru":169,"sr":170,"zh":143},"Local Roots, Global Reach","Local Roots - Global Reach","Empresa local ","Entreprise locale","Azienda locale","Местная компания","Локално предузеће глобално тржиште","\u002Fportfolio\u002Flocal-roots-global-reach-communication-media-systems-for-modern-business","i-lucide-folder","custom",[],{"id":176,"title":177,"url":179,"target":61,"icon":172,"isActive":14,"type":173,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":10,"portfolioId":10,"children":180},"item-28",{"de":178,"en":178,"es":178,"fr":178,"it":178,"ru":178,"sr":178,"zh":178},"Solr Suggester","\u002Fportfolio\u002Fsolr-fuzzy-suggester-und-solr-infix-suggester-abfrage-ueber-ajax-und-filterung",[],{"id":182,"title":183,"url":191,"target":61,"icon":172,"isActive":14,"type":173,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":10,"portfolioId":10,"children":192},"item-27",{"de":184,"en":185,"es":186,"fr":187,"it":188,"ru":189,"sr":190,"zh":185},"Firmenwebseite SEO","Company Website SEO","Sitio web corporativo SEO","Site web d’entreprise SEO","Sito web aziendale SEO","Корпоративный сайт SEO","Пословна веб-страница SEO","\u002Fportfolio\u002Fseo-sem-branding-mobile-webseite-muenchen",[],{"id":194,"title":195,"url":203,"target":61,"icon":172,"isActive":14,"type":173,"productId":10,"categoryId":10,"shopCategoryId":10,"articleId":10,"pageId":10,"portfolioId":10,"children":204},"item-31",{"de":196,"en":197,"es":198,"fr":199,"it":200,"ru":201,"sr":202,"zh":197},"Digitalisierungsportal","Digitalization Portal","Portal de digitalización","Portail de numérisation","Portale di digitalizzazione","Портал цифровизации","Портал за дигитализацију","\u002Fportfolio\u002Fdigitalisierungsportal-archiv-museum-bibliothek-ead-lido-mets-mods",[],{"statusCode":4,"data":206,"message":2038},{"id":207,"title":208,"slug":209,"content":210,"contentJson":211,"excerpt":1410,"featuredImage":1411,"featuredImageAlt":1412,"featuredImageCaption":10,"featuredImageTitle":10,"featuredImageCopyright":10,"featuredImageAuthor":10,"featuredImageSourceUrl":10,"featuredImageLicense":10,"featuredImageIsAiGenerated":43,"status":1413,"publishedAt":1414,"createdAt":1415,"updatedAt":1416,"seoLocalePaths":1417,"categories":1426,"author":1439,"translations":1444},"490","RBAC vs Tenant Isolation: Two Different Security Boundaries","rbac-vs-tenant-isolation-two-different-security-boundaries","{\"time\":1791485112883,\"blocks\":[{\"id\":\"intro\",\"type\":\"paragraph\",\"data\":{\"text\":\"RBAC and tenant isolation solve two different security problems in multi-tenant systems. Role-Based Access Control (RBAC) determines what an authenticated principal is allowed to do, such as read orders, edit products or manage users. Tenant isolation determines which tenant's data, resources and execution context that principal is allowed to access. A user can be correctly authenticated and correctly assigned an RBAC role yet still experience a security failure if the application lets that role operate on another tenant's resources.\"},\"tunes\":{}},{\"id\":\"direct\",\"type\":\"callout\",\"data\":{\"variant\":\"info\",\"title\":\"Direct answer\",\"body\":\"\u003Cstrong>RBAC answers “what may this identity do?” Tenant isolation answers “inside whose boundary may it do it?”\u003C\u002Fstrong>\u003Cbr>\u003Cbr>A secure multi-tenant application normally needs both. A tenant administrator may have broad permissions, but those permissions should remain constrained to the administrator's tenant unless an explicitly separate platform-level authority exists.\"},\"tunes\":{}},{\"id\":\"boundary\",\"type\":\"callout\",\"data\":{\"variant\":\"warning\",\"title\":\"A role is not a tenant boundary\",\"body\":\"Giving a user the role \u003Ccode>ADMIN\u003C\u002Fcode> does not automatically imply “administrator of tenant A only.” The role must be evaluated together with verified tenant context and the target resource's tenant ownership. Otherwise a valid role can become a cross-tenant privilege.\"},\"tunes\":{}},{\"id\":\"current\",\"type\":\"callout\",\"data\":{\"variant\":\"note\",\"title\":\"Current-source note — 8 October 2026\",\"body\":\"The underlying distinction is stable. NIST defines RBAC around users, roles, permissions, operations and objects. Current AWS SaaS guidance explicitly states that authentication and authorization are not equal to tenant isolation, and that a user can be authenticated and authorized while still accessing another tenant's resources if isolation is not separately enforced. OWASP's current Multi-Tenant Security guidance likewise treats tenant isolation as a cross-layer requirement covering APIs, databases, caches, storage, queues and other shared resources.\"},\"tunes\":{}},{\"id\":\"toc\",\"type\":\"tableOfContents\",\"data\":{\"title\":\"Contents\",\"minLevel\":2,\"maxLevel\":3},\"tunes\":{}},{\"id\":\"h-meaning\",\"type\":\"header\",\"data\":{\"text\":\"What RBAC really controls\",\"level\":2},\"tunes\":{}},{\"id\":\"p-rbac-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"RBAC is an authorization model in which permissions are associated with roles and users are assigned to those roles. The role acts as an administrative abstraction between identities and permissions.\"},\"tunes\":{}},{\"id\":\"p-rbac-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"NIST's classic RBAC work formalizes this around users, roles, permissions, operations and objects. The practical benefit is that an organization can manage authorization through relatively stable job or responsibility roles rather than attaching every permission directly to every user.\"},\"tunes\":{}},{\"id\":\"p-rbac-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"A role such as EDITOR can therefore mean: may read content, write content and publish content. A role such as ACCOUNTANT may mean: may read billing data, reconcile invoices and approve settlements.\"},\"tunes\":{}},{\"id\":\"h-tenant\",\"type\":\"header\",\"data\":{\"text\":\"What tenant isolation really controls\",\"level\":2},\"tunes\":{}},{\"id\":\"p-tenant-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Tenant isolation is the set of mechanisms that prevents one tenant from reading, modifying, influencing or accidentally receiving another tenant's resources in a shared system.\"},\"tunes\":{}},{\"id\":\"p-tenant-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"The protected boundary is broader than database rows. Tenant-specific state can exist in relational tables, object storage, vector indexes, caches, search indexes, queue messages, files, temporary artifacts, background jobs, analytics, rate limits and infrastructure resources.\"},\"tunes\":{}},{\"id\":\"p-tenant-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"AWS's SaaS guidance makes the distinction explicit: authorization grants access to resources, while tenant isolation ensures those resources cannot cross the wrong tenant boundary even when infrastructure is shared.\"},\"tunes\":{}},{\"id\":\"h-simple\",\"type\":\"header\",\"data\":{\"text\":\"The simplest example\",\"level\":2},\"tunes\":{}},{\"id\":\"p-simple-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Suppose Alice is an administrator for Tenant A and Bob is an administrator for Tenant B. Both users legitimately hold the same ADMIN role.\"},\"tunes\":{}},{\"id\":\"p-simple-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"RBAC can correctly conclude that both users may execute an operation such as users.read. But when Alice requests user ID 847, the application must still verify that user 847 belongs to Tenant A.\"},\"tunes\":{}},{\"id\":\"p-simple-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"If the API checks only “Alice has ADMIN” and then executes SELECT * FROM users WHERE id = 847, RBAC succeeded while tenant isolation failed.\"},\"tunes\":{}},{\"id\":\"simple-flow\",\"type\":\"processFlow\",\"data\":{\"title\":\"A correct multi-tenant authorization decision\",\"orientation\":\"auto\",\"steps\":[{\"label\":\"1. Authenticate principal\",\"description\":\"Establish who the user, service or agent is.\"},{\"label\":\"2. Resolve verified tenant context\",\"description\":\"Determine which tenant context applies from trusted server-side identity\u002Fmembership information.\"},{\"label\":\"3. Resolve permission\",\"description\":\"Evaluate whether the principal's role or policy permits the requested operation.\"},{\"label\":\"4. Scope the target resource\",\"description\":\"Verify that the target object belongs to the permitted tenant or explicitly shared scope.\"},{\"label\":\"5. Enforce at the access boundary\",\"description\":\"Perform the database, cache, storage, queue or service operation with tenant constraints applied.\"},{\"label\":\"6. Audit both dimensions\",\"description\":\"Record principal, tenant, operation, target and result so cross-tenant attempts are visible.\"}]},\"tunes\":{}},{\"id\":\"h-stops\",\"type\":\"header\",\"data\":{\"text\":\"Where the simple example stops\",\"level\":2},\"tunes\":{}},{\"id\":\"p-stops-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Real systems often contain several classes of identity: tenant users, platform administrators, background workers, integrations, agents and cross-tenant operational services. Some of these legitimately cross tenant boundaries.\"},\"tunes\":{}},{\"id\":\"p-stops-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"That does not remove the need for isolation. It means cross-tenant authority must be explicit, narrow and separately auditable rather than emerging accidentally from a global role or unscoped database connection.\"},\"tunes\":{}},{\"id\":\"p-stops-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Tenant isolation can also vary by layer. A product may share application servers while separating databases, or use a shared database with row-level policies while giving premium tenants isolated storage or compute. There is no single universal isolation topology.\"},\"tunes\":{}},{\"id\":\"h-compare\",\"type\":\"header\",\"data\":{\"text\":\"RBAC vs tenant isolation\",\"level\":2},\"tunes\":{}},{\"id\":\"core-comparison\",\"type\":\"comparison\",\"data\":{\"title\":\"Two different security dimensions\",\"layout\":\"table\",\"columns\":[{\"id\":\"rbac\",\"label\":\"RBAC\"},{\"id\":\"tenant\",\"label\":\"Tenant isolation\"}],\"rows\":[{\"id\":\"question\",\"label\":\"Primary question\",\"values\":[\"\",\"\"]},{\"id\":\"unit\",\"label\":\"Typical unit\",\"values\":[\"\",\"\"]},{\"id\":\"example\",\"label\":\"Example\",\"values\":[\"\",\"\"]},{\"id\":\"failure\",\"label\":\"Typical failure\",\"values\":[\"\",\"\"]},{\"id\":\"implementation\",\"label\":\"Typical implementation\",\"values\":[\"\",\"\"]},{\"id\":\"scope\",\"label\":\"Can it exist alone?\",\"values\":[\"\",\"\"]}]},\"tunes\":{}},{\"id\":\"h-authn\",\"type\":\"header\",\"data\":{\"text\":\"Authentication, authorization and isolation are three different checks\",\"level\":2},\"tunes\":{}},{\"id\":\"three-checks\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Layer\",\"Question\",\"Example failure\"],[\"Authentication\",\"Who is this principal?\",\"Attacker impersonates Alice\"],[\"Authorization \u002F RBAC\",\"May this principal perform this operation?\",\"Viewer can delete users\"],[\"Tenant isolation\",\"May this operation reach this tenant\u002Fresource boundary?\",\"Tenant A admin reads Tenant B order\"]]},\"tunes\":{}},{\"id\":\"p-authn-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"These checks are related but non-substitutable. Authentication can be perfect while authorization fails. Authorization can be correct while tenant isolation fails. A secure SaaS request path needs all applicable boundaries.\"},\"tunes\":{}},{\"id\":\"h-role-scope\",\"type\":\"header\",\"data\":{\"text\":\"Roles need a scope\",\"level\":2},\"tunes\":{}},{\"id\":\"p-role-scope-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"The word ADMIN is incomplete without scope. It can mean platform administrator, tenant administrator, project administrator, workspace administrator or administrator of one subsystem.\"},\"tunes\":{}},{\"id\":\"p-role-scope-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"In multi-tenant systems, role assignment should normally be associated with tenant membership or another explicit resource scope. The same user may legitimately be ADMIN in Tenant A and VIEWER in Tenant B.\"},\"tunes\":{}},{\"id\":\"p-role-scope-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"A global role model that ignores this distinction can create privilege leakage even when the permission map itself is correct.\"},\"tunes\":{}},{\"id\":\"h-context\",\"type\":\"header\",\"data\":{\"text\":\"Tenant context must come from a trusted path\",\"level\":2},\"tunes\":{}},{\"id\":\"p-context-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"A tenant ID supplied by the client is useful as a selector, but it is not proof of authority. The server must derive or verify tenant membership against authenticated identity and current authorization data.\"},\"tunes\":{}},{\"id\":\"p-context-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"OWASP's current multi-tenant guidance recommends establishing tenant context early in the request lifecycle and explicitly warns against treating client headers or request parameters as authorization proof.\"},\"tunes\":{}},{\"id\":\"p-context-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"This matters because a trivial request modification from tenant=A to tenant=B must not be sufficient to cross the isolation boundary.\"},\"tunes\":{}},{\"id\":\"h-query\",\"type\":\"header\",\"data\":{\"text\":\"Tenant scope belongs in the resource lookup\",\"level\":2},\"tunes\":{}},{\"id\":\"p-query-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"A common application-level isolation pattern is to include tenant scope in the same query that resolves the resource.\"},\"tunes\":{}},{\"id\":\"query-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Weak lookup\",\"Stronger tenant-scoped lookup\"],[\"findFirst({ where: { id } })\",\"findFirst({ where: { id, tenantId } })\"],[\"UPDATE orders SET ... WHERE id = ?\",\"UPDATE orders SET ... WHERE id = ? AND tenant_id = ?\"],[\"cache.get('user:' + id)\",\"cache.get('tenant:' + tenantId + ':user:' + id)\"]]},\"tunes\":{}},{\"id\":\"p-query-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"This pattern is not the only possible isolation mechanism, but it keeps tenant ownership close to the data access operation and prevents an object ID from becoming a cross-tenant capability.\"},\"tunes\":{}},{\"id\":\"h-defense\",\"type\":\"header\",\"data\":{\"text\":\"Application checks are useful, but isolation should not depend on perfect developer behavior\",\"level\":2},\"tunes\":{}},{\"id\":\"p-defense-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"AWS's isolation guidance explicitly warns against leaving isolation enforcement only to service developers. In a large codebase, eventually one query, cache key or worker path may omit tenant scope.\"},\"tunes\":{}},{\"id\":\"p-defense-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Defense in depth can therefore move isolation into shared middleware, repository\u002Fservice layers, policy engines, database Row-Level Security, dedicated credentials, separate schemas or separate databases depending on risk and architecture.\"},\"tunes\":{}},{\"id\":\"defense-rule\",\"type\":\"callout\",\"data\":{\"variant\":\"success\",\"title\":\"Isolation should be hard to forget\",\"body\":\"The strongest boundary is one that ordinary application code cannot casually bypass by omitting one \u003Ccode>tenantId\u003C\u002Fcode> condition.\"},\"tunes\":{}},{\"id\":\"h-db\",\"type\":\"header\",\"data\":{\"text\":\"Database isolation strategies\",\"level\":2},\"tunes\":{}},{\"id\":\"db-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Strategy\",\"Boundary\",\"Strength \u002F trade-off\"],[\"Shared tables + tenant key\",\"Row\u002Fapplication policy\",\"Operationally efficient; requires exhaustive tenant scoping and strong tests\"],[\"Shared tables + database RLS\",\"Database policy boundary\",\"Reduces dependence on every application query; requires correct roles, session\u002Ftransaction tenant context and policy coverage\"],[\"Separate schemas\",\"Namespace \u002F DB-role boundary\",\"Stronger logical separation; more operational complexity\"],[\"Separate databases\",\"Database \u002F credential boundary\",\"Strong isolation and simpler blast-radius story; higher provisioning and operations cost\"],[\"Separate infrastructure\u002Faccount\",\"Infrastructure boundary\",\"Strongest coarse-grained separation; highest cost and operational overhead\"],[\"Hybrid\",\"Per workload\u002Fdata class\",\"Allows stronger isolation only where risk\u002Fcompliance justifies it\"]]},\"tunes\":{}},{\"id\":\"p-db-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"OWASP's current Multi-Tenant Security Cheat Sheet lists separate databases, separate schemas, shared tables with row-level controls and hybrid models. The correct model depends on threat level, compliance, performance and operational cost.\"},\"tunes\":{}},{\"id\":\"h-rls\",\"type\":\"header\",\"data\":{\"text\":\"PostgreSQL Row-Level Security can provide defense in depth\",\"level\":2},\"tunes\":{}},{\"id\":\"p-rls-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"With shared tables, PostgreSQL Row-Level Security can enforce a tenant predicate at the database layer so ordinary queries cannot see rows outside the active tenant policy.\"},\"tunes\":{}},{\"id\":\"p-rls-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"However, RLS is not magic. PostgreSQL superusers and roles with BYPASSRLS can bypass row policies. OWASP therefore recommends using a least-privileged request-path role and testing the same connection\u002Fpooling mode used in production.\"},\"tunes\":{}},{\"id\":\"p-rls-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Connection reuse is another important edge: tenant context must be set and reset safely for every transaction\u002Frequest so one pooled connection cannot leak prior tenant state.\"},\"tunes\":{}},{\"id\":\"h-cache\",\"type\":\"header\",\"data\":{\"text\":\"Tenant isolation must include caches\",\"level\":2},\"tunes\":{}},{\"id\":\"p-cache-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"A database query can be perfectly scoped and still leak data through a shared cache key.\"},\"tunes\":{}},{\"id\":\"p-cache-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"If user:42 exists in both Tenant A and Tenant B, a global cache key can return the wrong tenant's value. Tenant-sensitive cache keys should include every attribute that changes visibility or result semantics, commonly tenant, user, locale, feature set or permission version.\"},\"tunes\":{}},{\"id\":\"p-cache-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Cache partitioning is defense in depth, not a replacement for authorization. The request still needs to be authorized before protected cached content is returned.\"},\"tunes\":{}},{\"id\":\"h-storage\",\"type\":\"header\",\"data\":{\"text\":\"Files and object storage need their own tenant boundary\",\"level\":2},\"tunes\":{}},{\"id\":\"p-storage-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Object storage should distinguish global, tenant-scoped and user-scoped objects. A folder prefix alone is only a naming convention unless access policy actually constrains reads and writes.\"},\"tunes\":{}},{\"id\":\"p-storage-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Stronger designs may use tenant-aware object keys, bucket policies, separate buckets\u002Faccounts or tenant-specific encryption keys where risk or compliance requires stronger isolation.\"},\"tunes\":{}},{\"id\":\"p-storage-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Signed URLs must be authorized before issuance and scoped to the exact object and operation. Possession of an object identifier should not itself grant cross-tenant access.\"},\"tunes\":{}},{\"id\":\"h-queues\",\"type\":\"header\",\"data\":{\"text\":\"Background jobs and queues can break isolation\",\"level\":2},\"tunes\":{}},{\"id\":\"p-queue-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Async jobs often leave the original HTTP request context, which makes tenant propagation easy to mishandle. A queue message containing tenantId is not sufficient proof that the producer was authorized.\"},\"tunes\":{}},{\"id\":\"p-queue-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"The worker should carry a verified service\u002Fuser identity or trusted job envelope, re-establish tenant context and re-authorize consequential operations at the consumer boundary.\"},\"tunes\":{}},{\"id\":\"p-queue-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Tenant isolation also includes availability. One tenant should not be able to monopolize shared workers, queues, connection pools or compute in ways that materially degrade other tenants.\"},\"tunes\":{}},{\"id\":\"h-search\",\"type\":\"header\",\"data\":{\"text\":\"Search and RAG need tenant-aware retrieval\",\"level\":2},\"tunes\":{}},{\"id\":\"p-search-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Multi-tenant AI introduces another copy of the isolation problem. Documents may be chunked, embedded and stored in a vector index after ingestion.\"},\"tunes\":{}},{\"id\":\"p-search-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"OWASP's current RAG security guidance states that access control must be enforced at retrieval time and that chunks from Tenant A must not be retrieved by queries from Tenant B. Document-level permissions cannot simply be assumed to survive chunking automatically.\"},\"tunes\":{}},{\"id\":\"p-search-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"The vector index therefore needs tenant\u002Faccess metadata or physically\u002Flogically separate collections according to the isolation design. Retrieval filters should be applied before unauthorized content can enter model context.\"},\"tunes\":{}},{\"id\":\"rag-rule\",\"type\":\"callout\",\"data\":{\"variant\":\"warning\",\"title\":\"The model must never be the tenant filter\",\"body\":\"Do not retrieve cross-tenant chunks and then instruct the language model to ignore them. Once protected data enters model context, the isolation boundary has already failed.\"},\"tunes\":{}},{\"id\":\"h-derived\",\"type\":\"header\",\"data\":{\"text\":\"Derived data inherits tenant sensitivity\",\"level\":2},\"tunes\":{}},{\"id\":\"p-derived-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Embeddings, search indexes, thumbnails, generated summaries, caches, analytics rows and AI responses are derived from source data. Their tenant scope should follow the source unless an explicit transformation creates a legitimate shared\u002Fglobal artifact.\"},\"tunes\":{}},{\"id\":\"p-derived-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Deletion and offboarding must therefore propagate beyond the canonical row. Removing a tenant document while leaving searchable chunks or cached summaries can retain cross-tenant or post-retention exposure.\"},\"tunes\":{}},{\"id\":\"h-shared\",\"type\":\"header\",\"data\":{\"text\":\"Not everything belongs to a tenant\",\"level\":2},\"tunes\":{}},{\"id\":\"p-shared-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Multi-tenant platforms often have intentionally global resources: product taxonomies, public templates, system permissions, feature definitions or public content.\"},\"tunes\":{}},{\"id\":\"p-shared-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"The safest model is explicit classification: global, tenant-scoped, user-scoped or explicitly cross-tenant. Ambiguous resources are where accidental leakage begins.\"},\"tunes\":{}},{\"id\":\"p-shared-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"An intentionally shared object should have a documented reason for being global rather than simply lacking a tenant association.\"},\"tunes\":{}},{\"id\":\"h-platform-admin\",\"type\":\"header\",\"data\":{\"text\":\"Platform administrators require a different authority model\",\"level\":2},\"tunes\":{}},{\"id\":\"p-platform-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"A platform operator may need to inspect multiple tenants for support, compliance or infrastructure operations. Modeling this as an ordinary tenant ADMIN with accidental global database access weakens both security and auditability.\"},\"tunes\":{}},{\"id\":\"p-platform-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"A better design uses a distinct platform identity or explicit cross-tenant permission, stronger authentication, purpose limitation, detailed audit and, where appropriate, approval or break-glass controls.\"},\"tunes\":{}},{\"id\":\"p-platform-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Cross-tenant access should therefore be a named capability, not the absence of a tenant filter.\"},\"tunes\":{}},{\"id\":\"h-abac\",\"type\":\"header\",\"data\":{\"text\":\"RBAC can be combined with attributes\",\"level\":2},\"tunes\":{}},{\"id\":\"p-abac-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"Some decisions depend on more than role. Tenant membership, region, resource owner, subscription tier, time, project membership or data classification can all affect access.\"},\"tunes\":{}},{\"id\":\"p-abac-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"RBAC and ABAC are not mutually exclusive. AWS's current multi-tenant authorization guidance discusses RBAC, ABAC and hybrid models. A role can define broad responsibility while attributes constrain which concrete resource instance can be accessed.\"},\"tunes\":{}},{\"id\":\"p-abac-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"The key architecture rule remains: do not encode tenant isolation only as an incidental role name if tenant identity is a first-class resource boundary.\"},\"tunes\":{}},{\"id\":\"h-matrix\",\"type\":\"header\",\"data\":{\"text\":\"Authorization decisions are at least two-dimensional\",\"level\":2},\"tunes\":{}},{\"id\":\"matrix-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Principal\",\"Role permission\",\"Tenant relationship\",\"Decision\"],[\"Alice\",\"orders.read\",\"Order belongs to Alice's tenant\",\"Allow\"],[\"Alice\",\"orders.read\",\"Order belongs to another tenant\",\"Deny\"],[\"Alice\",\"orders.write\",\"Order belongs to Alice's tenant\",\"Allow if role includes write\"],[\"Alice\",\"orders.write\",\"Order belongs to another tenant\",\"Deny\"],[\"Platform support\",\"support.cross_tenant.read\",\"Explicit support scope + audited target tenant\",\"Potentially allow under platform policy\"],[\"Background worker\",\"orders.process\",\"Trusted service scope for job tenant\",\"Allow only for verified job tenant\"]]},\"tunes\":{}},{\"id\":\"h-implementation\",\"type\":\"header\",\"data\":{\"text\":\"Original implementation evidence: Aaasaasa AI CMS\",\"level\":2},\"tunes\":{}},{\"id\":\"impl-note\",\"type\":\"callout\",\"data\":{\"variant\":\"note\",\"title\":\"Original implementation evidence\",\"body\":\"Aaasaasa AI CMS contains a concrete tenant-scoped RBAC implementation. It is useful evidence for how role authorization and tenant scope can be combined, but it should not be presented as proof that every storage, cache or infrastructure layer has complete tenant isolation.\"},\"tunes\":{}},{\"id\":\"p-impl-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"The RBAC service defines typed permission codes such as cms.content.read, shop.orders.write, billing.reconcile and users.roles. System roles map those permissions into named responsibility sets.\"},\"tunes\":{}},{\"id\":\"p-impl-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Role records are created and resolved with a tenantId. System roles are upserted using a composite tenant\u002Fcode identity, and role listing is filtered by tenant.\"},\"tunes\":{}},{\"id\":\"p-impl-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Role update and deletion first resolve the role using both role ID and tenant ID. User-role assignments are also stored and replaced under the current tenant context.\"},\"tunes\":{}},{\"id\":\"p-impl-4\",\"type\":\"paragraph\",\"data\":{\"text\":\"Permission resolution reads explicit user-role assignments scoped by both tenantId and userId. This prevents one tenant's role assignment from automatically becoming another tenant's role assignment.\"},\"tunes\":{}},{\"id\":\"p-impl-5\",\"type\":\"paragraph\",\"data\":{\"text\":\"At API level, administrative RBAC routes resolve a tenant context before creating or modifying roles. This is the correct direction: permission administration itself must respect tenancy.\"},\"tunes\":{}},{\"id\":\"impl-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Observed implementation pattern\",\"Security meaning\"],[\"Typed permission codes\",\"RBAC operation vocabulary is explicit\"],[\"System role → permission maps\",\"Roles aggregate permissions rather than hard-coding users\"],[\"tenantId_code role identity\",\"Same logical role can exist separately per tenant\"],[\"Role lookup uses id + tenantId\",\"Role mutation is tenant-scoped\"],[\"User-role relation stores tenantId\",\"Membership is not globally inferred from role alone\"],[\"Permission resolution uses tenantId + userId\",\"Authorization is evaluated inside tenant context\"]]},\"tunes\":{}},{\"id\":\"impl-boundary\",\"type\":\"callout\",\"data\":{\"variant\":\"warning\",\"title\":\"What this evidence does not prove\",\"body\":\"Tenant-scoped RBAC is one layer. Complete tenant isolation must also cover all tenant-owned resource lookups, databases, caches, files, search\u002Fvector indexes, background jobs, integrations and operational paths. The repository evidence here supports the RBAC\u002Ftenant-scope design pattern, not a claim of independently audited SaaS isolation.\"},\"tunes\":{}},{\"id\":\"h-ai\",\"type\":\"header\",\"data\":{\"text\":\"Why this distinction matters even more for AI agents\",\"level\":2},\"tunes\":{}},{\"id\":\"p-ai-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"AI agents can turn a permission mistake into a sequence of actions. If an agent is given a broad orders.read tool without tenant-scoped enforcement, a reasoning or prompt-injection failure can cause cross-tenant reads at machine speed.\"},\"tunes\":{}},{\"id\":\"p-ai-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Agent tool descriptions can mention tenant constraints, but enforcement must still happen in the trusted runtime\u002Fservice\u002Fdata layer. Natural-language instructions are not an authorization boundary.\"},\"tunes\":{}},{\"id\":\"p-ai-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"The same applies to RAG: an agent can have permission to use the search tool while the search backend must still prevent Tenant A's query from returning Tenant B's chunks.\"},\"tunes\":{}},{\"id\":\"h-tests\",\"type\":\"header\",\"data\":{\"text\":\"Test RBAC and tenant isolation separately\",\"level\":2},\"tunes\":{}},{\"id\":\"tests-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Test family\",\"What it should prove\"],[\"Role demotion test\",\"A user without a permission cannot perform the operation even inside their own tenant\"],[\"Cross-tenant object test\",\"A user with the correct role still cannot access the same resource type in another tenant\"],[\"Identifier tampering\",\"Changing object\u002Ftenant IDs does not cross scope\"],[\"List\u002Fbulk endpoint test\",\"Broad queries return only authorized tenant data\"],[\"Cache reuse test\",\"Two tenants using reused processes\u002Fconnections never receive each other's cached state\"],[\"RLS request-role test\",\"Production request role cannot bypass row policies\"],[\"Async worker test\",\"Tenant context survives queueing and is revalidated at consumption\"],[\"Vector retrieval test\",\"Tenant A query never retrieves Tenant B chunks\"],[\"Platform-admin test\",\"Cross-tenant capability is explicit, narrow and auditable\"],[\"Offboarding test\",\"Tenant data and derived indexes\u002Fcaches are removed according to policy\"]]},\"tunes\":{}},{\"id\":\"p-tests-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"OWASP's authorization regression guidance specifically calls out cross-tenant boundary tests because code changes in caching, queries or shared services can silently break isolation even when role tests continue to pass.\"},\"tunes\":{}},{\"id\":\"h-failures\",\"type\":\"header\",\"data\":{\"text\":\"Common failure modes\",\"level\":2},\"tunes\":{}},{\"id\":\"failures-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Failure mode\",\"Why it fails\"],[\"Check role but not tenant\",\"Valid role becomes cross-tenant authority\"],[\"Trust tenant ID from request\",\"Client controls the isolation selector\"],[\"Scope UI but not API\",\"Hidden buttons do not protect backend resources\"],[\"Tenant-aware detail endpoint, unscoped list endpoint\",\"Bulk reads leak other tenants\"],[\"Tenant filter in most queries\",\"One forgotten path breaks the boundary\"],[\"Global cache keys\",\"Correct database isolation is bypassed by cached data\"],[\"Shared vector index without enforced metadata filters\",\"RAG retrieves another tenant's chunks\"],[\"Queue message tenant ID treated as authorization\",\"Forged or wrongly produced job can cross tenant boundary\"],[\"Platform admin modeled as ordinary ADMIN\",\"Cross-tenant power becomes implicit and difficult to audit\"],[\"Role copied globally across tenant memberships\",\"User receives permissions in tenants where they were never assigned\"],[\"Separate databases but shared privileged credential\",\"Application can still cross databases if its credential is too broad\"],[\"RLS with BYPASSRLS request role\",\"Database policy exists but does not protect the actual request path\"],[\"Random UUIDs treated as isolation\",\"Hard-to-guess identifiers reduce enumeration but do not authorize access\"]]},\"tunes\":{}},{\"id\":\"h-misconceptions\",\"type\":\"header\",\"data\":{\"text\":\"Common misconceptions\",\"level\":2},\"tunes\":{}},{\"id\":\"misconceptions-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Misconception\",\"Correction\"],[\"“RBAC provides tenant isolation.”\",\"RBAC controls permissions; isolation also requires tenant\u002Fresource scoping.\"],[\"“If the user is an admin, tenant checks are unnecessary.”\",\"Admin authority must still have an explicit scope.\"],[\"“Tenant ID in JWT is enough.”\",\"It can be a trusted input only if validated and applied consistently to every protected resource path.\"],[\"“Separate databases remove authorization requirements.”\",\"Users still need operation-level permissions inside their tenant.\"],[\"“A tenant_id column means the system is isolated.”\",\"The field only helps if access paths enforce it.\"],[\"“UUIDs prevent cross-tenant access.”\",\"Unpredictable identifiers are defense in depth, not authorization.\"],[\"“RLS means application code needs no security checks.”\",\"Application authorization, correct DB roles and policy coverage still matter.\"],[\"“One shared vector DB is unsafe.”\",\"It can be safe if isolation is enforceable and verified; physical separation is one option, not the only one.\"],[\"“Platform support needs global ADMIN.”\",\"Cross-tenant support should be a distinct, constrained and auditable authority.\"],[\"“Internal services can skip tenant checks.”\",\"Internal paths can still be compromised or misconfigured and must preserve tenant context.\"]]},\"tunes\":{}},{\"id\":\"h-design\",\"type\":\"header\",\"data\":{\"text\":\"A practical design sequence\",\"level\":2},\"tunes\":{}},{\"id\":\"design-flow\",\"type\":\"processFlow\",\"data\":{\"title\":\"Design permissions and isolation as separate dimensions\",\"orientation\":\"auto\",\"steps\":[{\"label\":\"1. Define tenant ownership\",\"description\":\"Classify which entities and resources are global, tenant-scoped, user-scoped or intentionally cross-tenant.\"},{\"label\":\"2. Define operations\",\"description\":\"Create explicit permissions for reads, writes, publishing, approvals, administration and other business actions.\"},{\"label\":\"3. Define roles\",\"description\":\"Group permissions according to responsibilities without embedding accidental global scope.\"},{\"label\":\"4. Define membership scope\",\"description\":\"Bind role assignments to the tenant\u002Fworkspace\u002Fproject context in which they apply.\"},{\"label\":\"5. Resolve trusted tenant context\",\"description\":\"Derive tenant identity from authenticated, server-verified membership or service authorization.\"},{\"label\":\"6. Enforce resource ownership\",\"description\":\"Apply tenant scope at every tenant-owned data\u002Fservice boundary.\"},{\"label\":\"7. Add defense in depth\",\"description\":\"Use RLS, separate credentials, schemas\u002Fdatabases, storage policies or policy engines where risk justifies them.\"},{\"label\":\"8. Carry scope through derived systems\",\"description\":\"Preserve tenant metadata in cache, search, vector indexes, queues, files and analytics.\"},{\"label\":\"9. Model cross-tenant operations explicitly\",\"description\":\"Separate platform administration and service identities from ordinary tenant roles.\"},{\"label\":\"10. Test both axes\",\"description\":\"Run negative tests for missing permission and for wrong tenant independently.\"},{\"label\":\"11. Audit tenant + permission together\",\"description\":\"Log who acted, in which tenant, on what target and under which authority.\"},{\"label\":\"12. Re-test after schema\u002Fruntime changes\",\"description\":\"Isolation can break when new tables, caches, queues or retrieval paths are introduced.\"}]},\"tunes\":{}},{\"id\":\"h-checklist\",\"type\":\"header\",\"data\":{\"text\":\"RBAC + tenant isolation checklist\",\"level\":2},\"tunes\":{}},{\"id\":\"checklist-table\",\"type\":\"table\",\"data\":{\"withHeadings\":true,\"stretched\":false,\"content\":[[\"Question\",\"Expected answer\"],[\"Who is the principal?\",\"Authenticated user\u002Fservice\u002Fagent identity\"],[\"Which tenant context applies?\",\"Server-verified membership or service scope\"],[\"Which operation is requested?\",\"Typed permission or policy action\"],[\"Does the principal have that permission?\",\"Role\u002Fpolicy decision\"],[\"Who owns the target resource?\",\"Explicit tenant\u002Fglobal\u002Fuser classification\"],[\"Does resource scope match authority?\",\"Tenant-aware lookup\u002Fpolicy\"],[\"Can storage bypass application checks?\",\"Defense-in-depth decision documented\"],[\"Are caches tenant-safe?\",\"Keys\u002Fnamespaces and authorization preserve tenant scope\"],[\"Are files\u002Fblobs tenant-safe?\",\"Object policy and signed URL issuance enforce scope\"],[\"Are async jobs tenant-safe?\",\"Verified context propagates and is revalidated\"],[\"Is RAG\u002Fsearch tenant-safe?\",\"Metadata\u002Fcollection isolation enforced before model context\"],[\"Are cross-tenant admins explicit?\",\"Separate authority, controls and audit\"],[\"Can ordinary credentials bypass isolation?\",\"No, or tightly documented exceptional path\"],[\"Are negative cross-tenant tests automated?\",\"Yes for every relevant access layer\"]]},\"tunes\":{}},{\"id\":\"h-edge\",\"type\":\"header\",\"data\":{\"text\":\"Edge cases and limitations\",\"level\":2},\"tunes\":{}},{\"id\":\"p-edge-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"A user can belong to multiple tenants. The current tenant should therefore be an explicit execution context, not inferred permanently from the user account.\"},\"tunes\":{}},{\"id\":\"p-edge-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"Some resources are intentionally shared between selected tenants, such as collaboration spaces or consortium data. This requires an explicit sharing model; pretending the resource belongs to one tenant and adding exceptions later usually creates ambiguous authorization.\"},\"tunes\":{}},{\"id\":\"p-edge-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"Noisy-neighbor isolation is related but different from confidentiality isolation. A tenant may never see another tenant's data yet still exhaust shared CPU, queue capacity or database connections. Rate limits and resource quotas can therefore be tenant-aware as an availability boundary.\"},\"tunes\":{}},{\"id\":\"p-edge-4\",\"type\":\"paragraph\",\"data\":{\"text\":\"Physical isolation is not automatically secure if control-plane credentials or administrative paths can cross boundaries. Logical isolation is not automatically weak if policies are centrally enforced, least-privileged and thoroughly tested.\"},\"tunes\":{}},{\"id\":\"p-edge-5\",\"type\":\"paragraph\",\"data\":{\"text\":\"Tenant isolation requirements can differ by data class. Public catalog data, billing records and private AI documents may justify different storage and encryption boundaries inside the same SaaS product.\"},\"tunes\":{}},{\"id\":\"h-change\",\"type\":\"header\",\"data\":{\"text\":\"What would change this answer?\",\"level\":2},\"tunes\":{}},{\"id\":\"p-change-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"The exact implementation changes with architecture: serverless APIs, Kubernetes, PostgreSQL, object storage, vector databases and policy engines expose different isolation primitives.\"},\"tunes\":{}},{\"id\":\"p-change-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"The required strength also changes with regulation, customer contracts, data sensitivity, threat model and operational scale. Some tenants may justify siloed databases or infrastructure while others share pooled resources.\"},\"tunes\":{}},{\"id\":\"p-change-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"The conceptual distinction does not change: permission to perform an operation is not the same thing as permission to cross a tenant boundary.\"},\"tunes\":{}},{\"id\":\"h-related\",\"type\":\"header\",\"data\":{\"text\":\"Related canonical knowledge\",\"level\":2},\"tunes\":{}},{\"id\":\"p-related-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"S01 is a security-boundary prerequisite for Enterprise AI Architecture and AI Governance. Once AI tools, RAG or agents operate over multi-tenant data, tenant identity must travel through retrieval, tool execution, memory, caches and audit traces.\"},\"tunes\":{}},{\"id\":\"p-related-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"It also connects directly to Agentic AI: tool capability and role permission must still be constrained by tenant ownership before an agent can read or mutate business resources.\"},\"tunes\":{}},{\"id\":\"ref-agentic\",\"type\":\"referralArticle\",\"data\":{\"url\":\"https:\u002F\u002Fstajic.de\u002Fde\u002Fblog\u002Fmcp-vs-a2a-vs-ucp-vs-ap2-vs-a2ui-the-agent-protocol-stack-explained\",\"title\":\"MCP vs A2A vs UCP vs AP2 vs A2UI: The Agent Protocol Stack Explained\",\"excerpt\":\"Protocol interoperability does not replace authorization or tenant isolation. Capability discovery and business authority remain separate architecture concerns.\",\"ctaLabel\":\"Read the protocol stack article\"},\"tunes\":{}},{\"id\":\"p-related-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"For RAG, tenant isolation must be enforced before protected chunks reach model context.\"},\"tunes\":{}},{\"id\":\"ref-rag\",\"type\":\"referralArticle\",\"data\":{\"url\":\"https:\u002F\u002Fstajic.de\u002Fblog\u002Fwhat-is-rag-the-simplest-explanation-of-how-it-works\",\"title\":\"What Is RAG? The Simplest Explanation of How It Works\",\"excerpt\":\"The retrieval foundation for understanding where tenant-aware source filtering and vector-store isolation must be enforced.\",\"ctaLabel\":\"Read the RAG foundation\"},\"tunes\":{}},{\"id\":\"h-faq\",\"type\":\"header\",\"data\":{\"text\":\"Frequently asked questions\",\"level\":2},\"tunes\":{}},{\"id\":\"faq\",\"type\":\"faq\",\"data\":{\"title\":\"RBAC vs tenant isolation FAQ\",\"items\":[{\"id\":\"faq1\",\"question\":\"What is the difference between RBAC and tenant isolation?\",\"answer\":\"RBAC determines which operations a principal may perform. Tenant isolation determines which tenant's resources those operations may access. Secure multi-tenant applications normally need both.\"},{\"id\":\"faq2\",\"question\":\"Does an ADMIN role automatically allow access to all tenants?\",\"answer\":\"No. ADMIN should have an explicit scope. A tenant administrator normally has broad permissions only inside that tenant, while cross-tenant platform administration should be modeled separately.\"},{\"id\":\"faq3\",\"question\":\"Is authentication enough for tenant isolation?\",\"answer\":\"No. Authentication proves identity. Authorization controls permitted actions. Tenant isolation additionally prevents those actions from reaching the wrong tenant's resources.\"},{\"id\":\"faq4\",\"question\":\"Should tenantId be stored in the JWT?\",\"answer\":\"It can be one input to tenant context, but the server must verify current membership\u002Fauthority and enforce the scope at protected resource boundaries. A claim alone does not replace isolation controls.\"},{\"id\":\"faq5\",\"question\":\"Do I need a separate database per tenant?\",\"answer\":\"Not necessarily. Shared-table, RLS, schema, database, infrastructure and hybrid isolation models can all be valid depending on risk and operational requirements.\"},{\"id\":\"faq6\",\"question\":\"Can PostgreSQL RLS replace tenant filters in application code?\",\"answer\":\"RLS can provide strong defense in depth, but correct database roles, request context, policy coverage and application-level authorization still matter.\"},{\"id\":\"faq7\",\"question\":\"How should RAG enforce tenant isolation?\",\"answer\":\"Tenant\u002Faccess scope should be enforced during retrieval so unauthorized chunks never enter model context. Preserve access metadata through chunking and indexing.\"},{\"id\":\"faq8\",\"question\":\"Can one user have different roles in different tenants?\",\"answer\":\"Yes. This is common in B2B SaaS and is a strong reason to scope role assignments by tenant membership rather than treating roles as globally attached to the user.\"},{\"id\":\"faq9\",\"question\":\"What is the best test for tenant isolation?\",\"answer\":\"Use negative cross-tenant tests: create at least two tenants, give a user valid permissions in one tenant, then prove every protected path denies access to the other tenant's resources.\"}]},\"tunes\":{}},{\"id\":\"h-glossary\",\"type\":\"header\",\"data\":{\"text\":\"Glossary\",\"level\":2},\"tunes\":{}},{\"id\":\"glossary\",\"type\":\"glossary\",\"data\":{\"title\":\"Key multi-tenant security terms\",\"entries\":[{\"term\":\"RBAC\",\"definition\":\"Role-Based Access Control: an authorization model that associates permissions with roles and assigns users or principals to those roles.\",\"anchor\":\"rbac\"},{\"term\":\"Tenant\",\"definition\":\"A customer, organization, workspace or other isolated logical consumer of a shared multi-tenant system.\",\"anchor\":\"tenant\"},{\"term\":\"Tenant isolation\",\"definition\":\"Mechanisms that prevent one tenant from accessing, modifying or receiving another tenant's resources in a shared system.\",\"anchor\":\"tenant-isolation\"},{\"term\":\"Authentication\",\"definition\":\"Verification of the identity of a user, service or other principal.\",\"anchor\":\"authentication\"},{\"term\":\"Authorization\",\"definition\":\"Decision process that determines whether a principal may perform a requested operation on a resource.\",\"anchor\":\"authorization\"},{\"term\":\"Permission\",\"definition\":\"A defined allowed operation or capability such as orders.read or users.write.\",\"anchor\":\"permission\"},{\"term\":\"Role\",\"definition\":\"A named grouping of permissions associated with a responsibility or function.\",\"anchor\":\"role\"},{\"term\":\"ABAC\",\"definition\":\"Attribute-Based Access Control: authorization based on attributes of the principal, resource, action or environment.\",\"anchor\":\"abac\"},{\"term\":\"Row-Level Security\",\"definition\":\"Database policy mechanism that restricts which rows a database role or session may read or modify.\",\"anchor\":\"row-level-security\"},{\"term\":\"Cross-tenant access\",\"definition\":\"Any access path in which a principal operating under one tenant context reaches resources belonging to another tenant.\",\"anchor\":\"cross-tenant-access\"},{\"term\":\"Platform administrator\",\"definition\":\"A privileged operational identity with explicitly modeled authority that may span multiple tenants.\",\"anchor\":\"platform-administrator\"},{\"term\":\"Tenant context\",\"definition\":\"The verified tenant scope under which the current request, job or agent operation executes.\",\"anchor\":\"tenant-context\"}]},\"tunes\":{}},{\"id\":\"h-conclusion\",\"type\":\"header\",\"data\":{\"text\":\"Conclusion\",\"level\":2},\"tunes\":{}},{\"id\":\"p-conclusion-1\",\"type\":\"paragraph\",\"data\":{\"text\":\"RBAC and tenant isolation are complementary, not competing security mechanisms. RBAC structures operational permission; tenant isolation constrains the resource boundary inside which that permission can apply.\"},\"tunes\":{}},{\"id\":\"p-conclusion-2\",\"type\":\"paragraph\",\"data\":{\"text\":\"A robust multi-tenant request therefore needs more than “user has role ADMIN.” It needs a verified principal, verified tenant context, an allowed operation, a tenant-scoped target and enforcement at every resource layer that can carry tenant-owned data.\"},\"tunes\":{}},{\"id\":\"p-conclusion-3\",\"type\":\"paragraph\",\"data\":{\"text\":\"The shortest reliable rule is: authorize the action, then isolate the scope — and never assume one proves the other.\"},\"tunes\":{}},{\"id\":\"h-sources\",\"type\":\"header\",\"data\":{\"text\":\"Primary sources and current guidance\",\"level\":2},\"tunes\":{}},{\"id\":\"p-sources-note\",\"type\":\"paragraph\",\"data\":{\"text\":\"The sources below support the RBAC definition and current tenant-isolation guidance. The Aaasaasa AI CMS section is original implementation evidence and is intentionally bounded to the code patterns that were verified.\"},\"tunes\":{}},{\"id\":\"src-nist-rbac\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fcsrc.nist.gov\u002Fprojects\u002Frole-based-access-control\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"NIST — Role Based Access Control\",\"description\":\"NIST overview of RBAC models and the INCITS RBAC standard, including users, roles, permissions, operations and objects.\"}},\"tunes\":{}},{\"id\":\"src-nist-glossary\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fcsrc.nist.gov\u002Fglossary\u002Fterm\u002Frole_based_access_control\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"NIST CSRC — RBAC glossary\",\"description\":\"Current NIST glossary definitions of role-based access control as permission assignment through roles.\"}},\"tunes\":{}},{\"id\":\"src-aws-isolation\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fdocs.aws.amazon.com\u002Fwhitepapers\u002Flatest\u002Fsaas-tenant-isolation-strategies\u002Fthe-isolation-mindset.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"AWS — The isolation mindset\",\"description\":\"AWS SaaS guidance explicitly distinguishing authentication\u002Fauthorization from tenant isolation and recommending shared isolation mechanisms.\"}},\"tunes\":{}},{\"id\":\"src-aws-faq\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsaas-multitenant-api-access-authorization\u002Ffaq.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"AWS — Multi-tenant authorization FAQ\",\"description\":\"Current guidance explaining the difference between authorization and tenant isolation in SaaS applications.\"}},\"tunes\":{}},{\"id\":\"src-aws-avp\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsaas-multitenant-api-access-authorization\u002Favp-design-considerations.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"AWS — Multi-tenant design considerations\",\"description\":\"Current SaaS guidance distinguishing tenant isolation from authorization and discussing pooled\u002Fsiloed authorization policy models.\"}},\"tunes\":{}},{\"id\":\"src-owasp-multi\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FMulti_Tenant_Security_Cheat_Sheet.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"OWASP — Multi-Tenant Application Security Cheat Sheet\",\"description\":\"Current practical guidance for tenant context, database isolation, caches, storage, queues, testing and cross-tenant access prevention.\"}},\"tunes\":{}},{\"id\":\"src-owasp-rag\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FRAG_Security_Cheat_Sheet.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"OWASP — RAG Security Cheat Sheet\",\"description\":\"Current guidance requiring access control at retrieval time and tenant isolation for multi-tenant vector stores.\"}},\"tunes\":{}},{\"id\":\"src-owasp-auth-test\",\"type\":\"linkTool\",\"data\":{\"link\":\"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FAuthorization_Regression_Testing_Cheat_Sheet.html\",\"meta\":{\"image\":{\"url\":\"\"},\"title\":\"OWASP — Authorization Regression Testing\",\"description\":\"Current testing guidance including role-demotion and cross-tenant boundary tests.\"}},\"tunes\":{}}],\"version\":\"2.31.6\"}",{"time":212,"blocks":213,"version":1409},1791485112883,[214,220,228,235,242,250,255,260,265,270,275,280,285,290,295,300,305,310,336,341,346,351,356,361,401,406,426,431,436,441,446,451,456,461,466,471,476,481,498,503,508,513,518,525,530,563,568,573,578,583,588,593,598,603,608,613,618,623,628,633,638,643,648,653,658,663,668,674,679,684,689,694,699,704,709,714,719,724,729,734,739,744,749,754,786,791,797,802,807,812,817,822,848,854,859,864,869,874,879,917,922,927,974,979,1017,1022,1064,1069,1118,1123,1128,1133,1138,1143,1148,1153,1158,1163,1168,1173,1178,1183,1192,1197,1205,1210,1252,1257,1306,1311,1316,1321,1326,1331,1336,1346,1355,1364,1373,1382,1391,1400],{"id":215,"data":216,"type":218,"tunes":219},"intro",{"text":217},"RBAC and tenant isolation solve two different security problems in multi-tenant systems. Role-Based Access Control (RBAC) determines what an authenticated principal is allowed to do, such as read orders, edit products or manage users. Tenant isolation determines which tenant's data, resources and execution context that principal is allowed to access. A user can be correctly authenticated and correctly assigned an RBAC role yet still experience a security failure if the application lets that role operate on another tenant's resources.","paragraph",{},{"id":221,"data":222,"type":226,"tunes":227},"direct",{"body":223,"title":224,"variant":225},"\u003Cstrong>RBAC answers “what may this identity do?” Tenant isolation answers “inside whose boundary may it do it?”\u003C\u002Fstrong>\u003Cbr>\u003Cbr>A secure multi-tenant application normally needs both. A tenant administrator may have broad permissions, but those permissions should remain constrained to the administrator's tenant unless an explicitly separate platform-level authority exists.","Direct answer","info","callout",{},{"id":229,"data":230,"type":226,"tunes":234},"boundary",{"body":231,"title":232,"variant":233},"Giving a user the role \u003Ccode>ADMIN\u003C\u002Fcode> does not automatically imply “administrator of tenant A only.” The role must be evaluated together with verified tenant context and the target resource's tenant ownership. Otherwise a valid role can become a cross-tenant privilege.","A role is not a tenant boundary","warning",{},{"id":236,"data":237,"type":226,"tunes":241},"current",{"body":238,"title":239,"variant":240},"The underlying distinction is stable. NIST defines RBAC around users, roles, permissions, operations and objects. Current AWS SaaS guidance explicitly states that authentication and authorization are not equal to tenant isolation, and that a user can be authenticated and authorized while still accessing another tenant's resources if isolation is not separately enforced. OWASP's current Multi-Tenant Security guidance likewise treats tenant isolation as a cross-layer requirement covering APIs, databases, caches, storage, queues and other shared resources.","Current-source note — 8 October 2026","note",{},{"id":243,"data":244,"type":248,"tunes":249},"toc",{"title":245,"maxLevel":246,"minLevel":247},"Contents",3,2,"tableOfContents",{},{"id":251,"data":252,"type":42,"tunes":254},"h-meaning",{"text":253,"level":247},"What RBAC really controls",{},{"id":256,"data":257,"type":218,"tunes":259},"p-rbac-1",{"text":258},"RBAC is an authorization model in which permissions are associated with roles and users are assigned to those roles. The role acts as an administrative abstraction between identities and permissions.",{},{"id":261,"data":262,"type":218,"tunes":264},"p-rbac-2",{"text":263},"NIST's classic RBAC work formalizes this around users, roles, permissions, operations and objects. The practical benefit is that an organization can manage authorization through relatively stable job or responsibility roles rather than attaching every permission directly to every user.",{},{"id":266,"data":267,"type":218,"tunes":269},"p-rbac-3",{"text":268},"A role such as EDITOR can therefore mean: may read content, write content and publish content. A role such as ACCOUNTANT may mean: may read billing data, reconcile invoices and approve settlements.",{},{"id":271,"data":272,"type":42,"tunes":274},"h-tenant",{"text":273,"level":247},"What tenant isolation really controls",{},{"id":276,"data":277,"type":218,"tunes":279},"p-tenant-1",{"text":278},"Tenant isolation is the set of mechanisms that prevents one tenant from reading, modifying, influencing or accidentally receiving another tenant's resources in a shared system.",{},{"id":281,"data":282,"type":218,"tunes":284},"p-tenant-2",{"text":283},"The protected boundary is broader than database rows. Tenant-specific state can exist in relational tables, object storage, vector indexes, caches, search indexes, queue messages, files, temporary artifacts, background jobs, analytics, rate limits and infrastructure resources.",{},{"id":286,"data":287,"type":218,"tunes":289},"p-tenant-3",{"text":288},"AWS's SaaS guidance makes the distinction explicit: authorization grants access to resources, while tenant isolation ensures those resources cannot cross the wrong tenant boundary even when infrastructure is shared.",{},{"id":291,"data":292,"type":42,"tunes":294},"h-simple",{"text":293,"level":247},"The simplest example",{},{"id":296,"data":297,"type":218,"tunes":299},"p-simple-1",{"text":298},"Suppose Alice is an administrator for Tenant A and Bob is an administrator for Tenant B. Both users legitimately hold the same ADMIN role.",{},{"id":301,"data":302,"type":218,"tunes":304},"p-simple-2",{"text":303},"RBAC can correctly conclude that both users may execute an operation such as users.read. But when Alice requests user ID 847, the application must still verify that user 847 belongs to Tenant A.",{},{"id":306,"data":307,"type":218,"tunes":309},"p-simple-3",{"text":308},"If the API checks only “Alice has ADMIN” and then executes SELECT * FROM users WHERE id = 847, RBAC succeeded while tenant isolation failed.",{},{"id":311,"data":312,"type":334,"tunes":335},"simple-flow",{"steps":313,"title":332,"orientation":333},[314,317,320,323,326,329],{"label":315,"description":316},"1. Authenticate principal","Establish who the user, service or agent is.",{"label":318,"description":319},"2. Resolve verified tenant context","Determine which tenant context applies from trusted server-side identity\u002Fmembership information.",{"label":321,"description":322},"3. Resolve permission","Evaluate whether the principal's role or policy permits the requested operation.",{"label":324,"description":325},"4. Scope the target resource","Verify that the target object belongs to the permitted tenant or explicitly shared scope.",{"label":327,"description":328},"5. Enforce at the access boundary","Perform the database, cache, storage, queue or service operation with tenant constraints applied.",{"label":330,"description":331},"6. Audit both dimensions","Record principal, tenant, operation, target and result so cross-tenant attempts are visible.","A correct multi-tenant authorization decision","auto","processFlow",{},{"id":337,"data":338,"type":42,"tunes":340},"h-stops",{"text":339,"level":247},"Where the simple example stops",{},{"id":342,"data":343,"type":218,"tunes":345},"p-stops-1",{"text":344},"Real systems often contain several classes of identity: tenant users, platform administrators, background workers, integrations, agents and cross-tenant operational services. Some of these legitimately cross tenant boundaries.",{},{"id":347,"data":348,"type":218,"tunes":350},"p-stops-2",{"text":349},"That does not remove the need for isolation. It means cross-tenant authority must be explicit, narrow and separately auditable rather than emerging accidentally from a global role or unscoped database connection.",{},{"id":352,"data":353,"type":218,"tunes":355},"p-stops-3",{"text":354},"Tenant isolation can also vary by layer. A product may share application servers while separating databases, or use a shared database with row-level policies while giving premium tenants isolated storage or compute. There is no single universal isolation topology.",{},{"id":357,"data":358,"type":42,"tunes":360},"h-compare",{"text":359,"level":247},"RBAC vs tenant isolation",{},{"id":362,"data":363,"type":399,"tunes":400},"core-comparison",{"rows":364,"title":390,"layout":391,"columns":392},[365,370,374,378,382,386],{"id":366,"label":367,"values":368},"question","Primary question",[369,369],"",{"id":371,"label":372,"values":373},"unit","Typical unit",[369,369],{"id":375,"label":376,"values":377},"example","Example",[369,369],{"id":379,"label":380,"values":381},"failure","Typical failure",[369,369],{"id":383,"label":384,"values":385},"implementation","Typical implementation",[369,369],{"id":387,"label":388,"values":389},"scope","Can it exist alone?",[369,369],"Two different security dimensions","table",[393,396],{"id":394,"label":395},"rbac","RBAC",{"id":397,"label":398},"tenant","Tenant isolation","comparison",{},{"id":402,"data":403,"type":42,"tunes":405},"h-authn",{"text":404,"level":247},"Authentication, authorization and isolation are three different checks",{},{"id":407,"data":408,"type":391,"tunes":425},"three-checks",{"content":409,"stretched":43,"withHeadings":14},[410,414,418,422],[411,412,413],"Layer","Question","Example failure",[415,416,417],"Authentication","Who is this principal?","Attacker impersonates Alice",[419,420,421],"Authorization \u002F RBAC","May this principal perform this operation?","Viewer can delete users",[398,423,424],"May this operation reach this tenant\u002Fresource boundary?","Tenant A admin reads Tenant B order",{},{"id":427,"data":428,"type":218,"tunes":430},"p-authn-1",{"text":429},"These checks are related but non-substitutable. Authentication can be perfect while authorization fails. Authorization can be correct while tenant isolation fails. A secure SaaS request path needs all applicable boundaries.",{},{"id":432,"data":433,"type":42,"tunes":435},"h-role-scope",{"text":434,"level":247},"Roles need a scope",{},{"id":437,"data":438,"type":218,"tunes":440},"p-role-scope-1",{"text":439},"The word ADMIN is incomplete without scope. It can mean platform administrator, tenant administrator, project administrator, workspace administrator or administrator of one subsystem.",{},{"id":442,"data":443,"type":218,"tunes":445},"p-role-scope-2",{"text":444},"In multi-tenant systems, role assignment should normally be associated with tenant membership or another explicit resource scope. The same user may legitimately be ADMIN in Tenant A and VIEWER in Tenant B.",{},{"id":447,"data":448,"type":218,"tunes":450},"p-role-scope-3",{"text":449},"A global role model that ignores this distinction can create privilege leakage even when the permission map itself is correct.",{},{"id":452,"data":453,"type":42,"tunes":455},"h-context",{"text":454,"level":247},"Tenant context must come from a trusted path",{},{"id":457,"data":458,"type":218,"tunes":460},"p-context-1",{"text":459},"A tenant ID supplied by the client is useful as a selector, but it is not proof of authority. The server must derive or verify tenant membership against authenticated identity and current authorization data.",{},{"id":462,"data":463,"type":218,"tunes":465},"p-context-2",{"text":464},"OWASP's current multi-tenant guidance recommends establishing tenant context early in the request lifecycle and explicitly warns against treating client headers or request parameters as authorization proof.",{},{"id":467,"data":468,"type":218,"tunes":470},"p-context-3",{"text":469},"This matters because a trivial request modification from tenant=A to tenant=B must not be sufficient to cross the isolation boundary.",{},{"id":472,"data":473,"type":42,"tunes":475},"h-query",{"text":474,"level":247},"Tenant scope belongs in the resource lookup",{},{"id":477,"data":478,"type":218,"tunes":480},"p-query-1",{"text":479},"A common application-level isolation pattern is to include tenant scope in the same query that resolves the resource.",{},{"id":482,"data":483,"type":391,"tunes":497},"query-table",{"content":484,"stretched":43,"withHeadings":14},[485,488,491,494],[486,487],"Weak lookup","Stronger tenant-scoped lookup",[489,490],"findFirst({ where: { id } })","findFirst({ where: { id, tenantId } })",[492,493],"UPDATE orders SET ... WHERE id = ?","UPDATE orders SET ... WHERE id = ? AND tenant_id = ?",[495,496],"cache.get('user:' + id)","cache.get('tenant:' + tenantId + ':user:' + id)",{},{"id":499,"data":500,"type":218,"tunes":502},"p-query-2",{"text":501},"This pattern is not the only possible isolation mechanism, but it keeps tenant ownership close to the data access operation and prevents an object ID from becoming a cross-tenant capability.",{},{"id":504,"data":505,"type":42,"tunes":507},"h-defense",{"text":506,"level":247},"Application checks are useful, but isolation should not depend on perfect developer behavior",{},{"id":509,"data":510,"type":218,"tunes":512},"p-defense-1",{"text":511},"AWS's isolation guidance explicitly warns against leaving isolation enforcement only to service developers. In a large codebase, eventually one query, cache key or worker path may omit tenant scope.",{},{"id":514,"data":515,"type":218,"tunes":517},"p-defense-2",{"text":516},"Defense in depth can therefore move isolation into shared middleware, repository\u002Fservice layers, policy engines, database Row-Level Security, dedicated credentials, separate schemas or separate databases depending on risk and architecture.",{},{"id":519,"data":520,"type":226,"tunes":524},"defense-rule",{"body":521,"title":522,"variant":523},"The strongest boundary is one that ordinary application code cannot casually bypass by omitting one \u003Ccode>tenantId\u003C\u002Fcode> condition.","Isolation should be hard to forget","success",{},{"id":526,"data":527,"type":42,"tunes":529},"h-db",{"text":528,"level":247},"Database isolation strategies",{},{"id":531,"data":532,"type":391,"tunes":562},"db-table",{"content":533,"stretched":43,"withHeadings":14},[534,538,542,546,550,554,558],[535,536,537],"Strategy","Boundary","Strength \u002F trade-off",[539,540,541],"Shared tables + tenant key","Row\u002Fapplication policy","Operationally efficient; requires exhaustive tenant scoping and strong tests",[543,544,545],"Shared tables + database RLS","Database policy boundary","Reduces dependence on every application query; requires correct roles, session\u002Ftransaction tenant context and policy coverage",[547,548,549],"Separate schemas","Namespace \u002F DB-role boundary","Stronger logical separation; more operational complexity",[551,552,553],"Separate databases","Database \u002F credential boundary","Strong isolation and simpler blast-radius story; higher provisioning and operations cost",[555,556,557],"Separate infrastructure\u002Faccount","Infrastructure boundary","Strongest coarse-grained separation; highest cost and operational overhead",[559,560,561],"Hybrid","Per workload\u002Fdata class","Allows stronger isolation only where risk\u002Fcompliance justifies it",{},{"id":564,"data":565,"type":218,"tunes":567},"p-db-1",{"text":566},"OWASP's current Multi-Tenant Security Cheat Sheet lists separate databases, separate schemas, shared tables with row-level controls and hybrid models. The correct model depends on threat level, compliance, performance and operational cost.",{},{"id":569,"data":570,"type":42,"tunes":572},"h-rls",{"text":571,"level":247},"PostgreSQL Row-Level Security can provide defense in depth",{},{"id":574,"data":575,"type":218,"tunes":577},"p-rls-1",{"text":576},"With shared tables, PostgreSQL Row-Level Security can enforce a tenant predicate at the database layer so ordinary queries cannot see rows outside the active tenant policy.",{},{"id":579,"data":580,"type":218,"tunes":582},"p-rls-2",{"text":581},"However, RLS is not magic. PostgreSQL superusers and roles with BYPASSRLS can bypass row policies. OWASP therefore recommends using a least-privileged request-path role and testing the same connection\u002Fpooling mode used in production.",{},{"id":584,"data":585,"type":218,"tunes":587},"p-rls-3",{"text":586},"Connection reuse is another important edge: tenant context must be set and reset safely for every transaction\u002Frequest so one pooled connection cannot leak prior tenant state.",{},{"id":589,"data":590,"type":42,"tunes":592},"h-cache",{"text":591,"level":247},"Tenant isolation must include caches",{},{"id":594,"data":595,"type":218,"tunes":597},"p-cache-1",{"text":596},"A database query can be perfectly scoped and still leak data through a shared cache key.",{},{"id":599,"data":600,"type":218,"tunes":602},"p-cache-2",{"text":601},"If user:42 exists in both Tenant A and Tenant B, a global cache key can return the wrong tenant's value. Tenant-sensitive cache keys should include every attribute that changes visibility or result semantics, commonly tenant, user, locale, feature set or permission version.",{},{"id":604,"data":605,"type":218,"tunes":607},"p-cache-3",{"text":606},"Cache partitioning is defense in depth, not a replacement for authorization. The request still needs to be authorized before protected cached content is returned.",{},{"id":609,"data":610,"type":42,"tunes":612},"h-storage",{"text":611,"level":247},"Files and object storage need their own tenant boundary",{},{"id":614,"data":615,"type":218,"tunes":617},"p-storage-1",{"text":616},"Object storage should distinguish global, tenant-scoped and user-scoped objects. A folder prefix alone is only a naming convention unless access policy actually constrains reads and writes.",{},{"id":619,"data":620,"type":218,"tunes":622},"p-storage-2",{"text":621},"Stronger designs may use tenant-aware object keys, bucket policies, separate buckets\u002Faccounts or tenant-specific encryption keys where risk or compliance requires stronger isolation.",{},{"id":624,"data":625,"type":218,"tunes":627},"p-storage-3",{"text":626},"Signed URLs must be authorized before issuance and scoped to the exact object and operation. Possession of an object identifier should not itself grant cross-tenant access.",{},{"id":629,"data":630,"type":42,"tunes":632},"h-queues",{"text":631,"level":247},"Background jobs and queues can break isolation",{},{"id":634,"data":635,"type":218,"tunes":637},"p-queue-1",{"text":636},"Async jobs often leave the original HTTP request context, which makes tenant propagation easy to mishandle. A queue message containing tenantId is not sufficient proof that the producer was authorized.",{},{"id":639,"data":640,"type":218,"tunes":642},"p-queue-2",{"text":641},"The worker should carry a verified service\u002Fuser identity or trusted job envelope, re-establish tenant context and re-authorize consequential operations at the consumer boundary.",{},{"id":644,"data":645,"type":218,"tunes":647},"p-queue-3",{"text":646},"Tenant isolation also includes availability. One tenant should not be able to monopolize shared workers, queues, connection pools or compute in ways that materially degrade other tenants.",{},{"id":649,"data":650,"type":42,"tunes":652},"h-search",{"text":651,"level":247},"Search and RAG need tenant-aware retrieval",{},{"id":654,"data":655,"type":218,"tunes":657},"p-search-1",{"text":656},"Multi-tenant AI introduces another copy of the isolation problem. Documents may be chunked, embedded and stored in a vector index after ingestion.",{},{"id":659,"data":660,"type":218,"tunes":662},"p-search-2",{"text":661},"OWASP's current RAG security guidance states that access control must be enforced at retrieval time and that chunks from Tenant A must not be retrieved by queries from Tenant B. Document-level permissions cannot simply be assumed to survive chunking automatically.",{},{"id":664,"data":665,"type":218,"tunes":667},"p-search-3",{"text":666},"The vector index therefore needs tenant\u002Faccess metadata or physically\u002Flogically separate collections according to the isolation design. Retrieval filters should be applied before unauthorized content can enter model context.",{},{"id":669,"data":670,"type":226,"tunes":673},"rag-rule",{"body":671,"title":672,"variant":233},"Do not retrieve cross-tenant chunks and then instruct the language model to ignore them. Once protected data enters model context, the isolation boundary has already failed.","The model must never be the tenant filter",{},{"id":675,"data":676,"type":42,"tunes":678},"h-derived",{"text":677,"level":247},"Derived data inherits tenant sensitivity",{},{"id":680,"data":681,"type":218,"tunes":683},"p-derived-1",{"text":682},"Embeddings, search indexes, thumbnails, generated summaries, caches, analytics rows and AI responses are derived from source data. Their tenant scope should follow the source unless an explicit transformation creates a legitimate shared\u002Fglobal artifact.",{},{"id":685,"data":686,"type":218,"tunes":688},"p-derived-2",{"text":687},"Deletion and offboarding must therefore propagate beyond the canonical row. Removing a tenant document while leaving searchable chunks or cached summaries can retain cross-tenant or post-retention exposure.",{},{"id":690,"data":691,"type":42,"tunes":693},"h-shared",{"text":692,"level":247},"Not everything belongs to a tenant",{},{"id":695,"data":696,"type":218,"tunes":698},"p-shared-1",{"text":697},"Multi-tenant platforms often have intentionally global resources: product taxonomies, public templates, system permissions, feature definitions or public content.",{},{"id":700,"data":701,"type":218,"tunes":703},"p-shared-2",{"text":702},"The safest model is explicit classification: global, tenant-scoped, user-scoped or explicitly cross-tenant. Ambiguous resources are where accidental leakage begins.",{},{"id":705,"data":706,"type":218,"tunes":708},"p-shared-3",{"text":707},"An intentionally shared object should have a documented reason for being global rather than simply lacking a tenant association.",{},{"id":710,"data":711,"type":42,"tunes":713},"h-platform-admin",{"text":712,"level":247},"Platform administrators require a different authority model",{},{"id":715,"data":716,"type":218,"tunes":718},"p-platform-1",{"text":717},"A platform operator may need to inspect multiple tenants for support, compliance or infrastructure operations. Modeling this as an ordinary tenant ADMIN with accidental global database access weakens both security and auditability.",{},{"id":720,"data":721,"type":218,"tunes":723},"p-platform-2",{"text":722},"A better design uses a distinct platform identity or explicit cross-tenant permission, stronger authentication, purpose limitation, detailed audit and, where appropriate, approval or break-glass controls.",{},{"id":725,"data":726,"type":218,"tunes":728},"p-platform-3",{"text":727},"Cross-tenant access should therefore be a named capability, not the absence of a tenant filter.",{},{"id":730,"data":731,"type":42,"tunes":733},"h-abac",{"text":732,"level":247},"RBAC can be combined with attributes",{},{"id":735,"data":736,"type":218,"tunes":738},"p-abac-1",{"text":737},"Some decisions depend on more than role. Tenant membership, region, resource owner, subscription tier, time, project membership or data classification can all affect access.",{},{"id":740,"data":741,"type":218,"tunes":743},"p-abac-2",{"text":742},"RBAC and ABAC are not mutually exclusive. AWS's current multi-tenant authorization guidance discusses RBAC, ABAC and hybrid models. A role can define broad responsibility while attributes constrain which concrete resource instance can be accessed.",{},{"id":745,"data":746,"type":218,"tunes":748},"p-abac-3",{"text":747},"The key architecture rule remains: do not encode tenant isolation only as an incidental role name if tenant identity is a first-class resource boundary.",{},{"id":750,"data":751,"type":42,"tunes":753},"h-matrix",{"text":752,"level":247},"Authorization decisions are at least two-dimensional",{},{"id":755,"data":756,"type":391,"tunes":785},"matrix-table",{"content":757,"stretched":43,"withHeadings":14},[758,763,768,771,774,775,780],[759,760,761,762],"Principal","Role permission","Tenant relationship","Decision",[764,765,766,767],"Alice","orders.read","Order belongs to Alice's tenant","Allow",[764,765,769,770],"Order belongs to another tenant","Deny",[764,772,766,773],"orders.write","Allow if role includes write",[764,772,769,770],[776,777,778,779],"Platform support","support.cross_tenant.read","Explicit support scope + audited target tenant","Potentially allow under platform policy",[781,782,783,784],"Background worker","orders.process","Trusted service scope for job tenant","Allow only for verified job tenant",{},{"id":787,"data":788,"type":42,"tunes":790},"h-implementation",{"text":789,"level":247},"Original implementation evidence: Aaasaasa AI CMS",{},{"id":792,"data":793,"type":226,"tunes":796},"impl-note",{"body":794,"title":795,"variant":240},"Aaasaasa AI CMS contains a concrete tenant-scoped RBAC implementation. It is useful evidence for how role authorization and tenant scope can be combined, but it should not be presented as proof that every storage, cache or infrastructure layer has complete tenant isolation.","Original implementation evidence",{},{"id":798,"data":799,"type":218,"tunes":801},"p-impl-1",{"text":800},"The RBAC service defines typed permission codes such as cms.content.read, shop.orders.write, billing.reconcile and users.roles. System roles map those permissions into named responsibility sets.",{},{"id":803,"data":804,"type":218,"tunes":806},"p-impl-2",{"text":805},"Role records are created and resolved with a tenantId. System roles are upserted using a composite tenant\u002Fcode identity, and role listing is filtered by tenant.",{},{"id":808,"data":809,"type":218,"tunes":811},"p-impl-3",{"text":810},"Role update and deletion first resolve the role using both role ID and tenant ID. User-role assignments are also stored and replaced under the current tenant context.",{},{"id":813,"data":814,"type":218,"tunes":816},"p-impl-4",{"text":815},"Permission resolution reads explicit user-role assignments scoped by both tenantId and userId. This prevents one tenant's role assignment from automatically becoming another tenant's role assignment.",{},{"id":818,"data":819,"type":218,"tunes":821},"p-impl-5",{"text":820},"At API level, administrative RBAC routes resolve a tenant context before creating or modifying roles. This is the correct direction: permission administration itself must respect tenancy.",{},{"id":823,"data":824,"type":391,"tunes":847},"impl-table",{"content":825,"stretched":43,"withHeadings":14},[826,829,832,835,838,841,844],[827,828],"Observed implementation pattern","Security meaning",[830,831],"Typed permission codes","RBAC operation vocabulary is explicit",[833,834],"System role → permission maps","Roles aggregate permissions rather than hard-coding users",[836,837],"tenantId_code role identity","Same logical role can exist separately per tenant",[839,840],"Role lookup uses id + tenantId","Role mutation is tenant-scoped",[842,843],"User-role relation stores tenantId","Membership is not globally inferred from role alone",[845,846],"Permission resolution uses tenantId + userId","Authorization is evaluated inside tenant context",{},{"id":849,"data":850,"type":226,"tunes":853},"impl-boundary",{"body":851,"title":852,"variant":233},"Tenant-scoped RBAC is one layer. Complete tenant isolation must also cover all tenant-owned resource lookups, databases, caches, files, search\u002Fvector indexes, background jobs, integrations and operational paths. The repository evidence here supports the RBAC\u002Ftenant-scope design pattern, not a claim of independently audited SaaS isolation.","What this evidence does not prove",{},{"id":855,"data":856,"type":42,"tunes":858},"h-ai",{"text":857,"level":247},"Why this distinction matters even more for AI agents",{},{"id":860,"data":861,"type":218,"tunes":863},"p-ai-1",{"text":862},"AI agents can turn a permission mistake into a sequence of actions. If an agent is given a broad orders.read tool without tenant-scoped enforcement, a reasoning or prompt-injection failure can cause cross-tenant reads at machine speed.",{},{"id":865,"data":866,"type":218,"tunes":868},"p-ai-2",{"text":867},"Agent tool descriptions can mention tenant constraints, but enforcement must still happen in the trusted runtime\u002Fservice\u002Fdata layer. Natural-language instructions are not an authorization boundary.",{},{"id":870,"data":871,"type":218,"tunes":873},"p-ai-3",{"text":872},"The same applies to RAG: an agent can have permission to use the search tool while the search backend must still prevent Tenant A's query from returning Tenant B's chunks.",{},{"id":875,"data":876,"type":42,"tunes":878},"h-tests",{"text":877,"level":247},"Test RBAC and tenant isolation separately",{},{"id":880,"data":881,"type":391,"tunes":916},"tests-table",{"content":882,"stretched":43,"withHeadings":14},[883,886,889,892,895,898,901,904,907,910,913],[884,885],"Test family","What it should prove",[887,888],"Role demotion test","A user without a permission cannot perform the operation even inside their own tenant",[890,891],"Cross-tenant object test","A user with the correct role still cannot access the same resource type in another tenant",[893,894],"Identifier tampering","Changing object\u002Ftenant IDs does not cross scope",[896,897],"List\u002Fbulk endpoint test","Broad queries return only authorized tenant data",[899,900],"Cache reuse test","Two tenants using reused processes\u002Fconnections never receive each other's cached state",[902,903],"RLS request-role test","Production request role cannot bypass row policies",[905,906],"Async worker test","Tenant context survives queueing and is revalidated at consumption",[908,909],"Vector retrieval test","Tenant A query never retrieves Tenant B chunks",[911,912],"Platform-admin test","Cross-tenant capability is explicit, narrow and auditable",[914,915],"Offboarding test","Tenant data and derived indexes\u002Fcaches are removed according to policy",{},{"id":918,"data":919,"type":218,"tunes":921},"p-tests-1",{"text":920},"OWASP's authorization regression guidance specifically calls out cross-tenant boundary tests because code changes in caching, queries or shared services can silently break isolation even when role tests continue to pass.",{},{"id":923,"data":924,"type":42,"tunes":926},"h-failures",{"text":925,"level":247},"Common failure modes",{},{"id":928,"data":929,"type":391,"tunes":973},"failures-table",{"content":930,"stretched":43,"withHeadings":14},[931,934,937,940,943,946,949,952,955,958,961,964,967,970],[932,933],"Failure mode","Why it fails",[935,936],"Check role but not tenant","Valid role becomes cross-tenant authority",[938,939],"Trust tenant ID from request","Client controls the isolation selector",[941,942],"Scope UI but not API","Hidden buttons do not protect backend resources",[944,945],"Tenant-aware detail endpoint, unscoped list endpoint","Bulk reads leak other tenants",[947,948],"Tenant filter in most queries","One forgotten path breaks the boundary",[950,951],"Global cache keys","Correct database isolation is bypassed by cached data",[953,954],"Shared vector index without enforced metadata filters","RAG retrieves another tenant's chunks",[956,957],"Queue message tenant ID treated as authorization","Forged or wrongly produced job can cross tenant boundary",[959,960],"Platform admin modeled as ordinary ADMIN","Cross-tenant power becomes implicit and difficult to audit",[962,963],"Role copied globally across tenant memberships","User receives permissions in tenants where they were never assigned",[965,966],"Separate databases but shared privileged credential","Application can still cross databases if its credential is too broad",[968,969],"RLS with BYPASSRLS request role","Database policy exists but does not protect the actual request path",[971,972],"Random UUIDs treated as isolation","Hard-to-guess identifiers reduce enumeration but do not authorize access",{},{"id":975,"data":976,"type":42,"tunes":978},"h-misconceptions",{"text":977,"level":247},"Common misconceptions",{},{"id":980,"data":981,"type":391,"tunes":1016},"misconceptions-table",{"content":982,"stretched":43,"withHeadings":14},[983,986,989,992,995,998,1001,1004,1007,1010,1013],[984,985],"Misconception","Correction",[987,988],"“RBAC provides tenant isolation.”","RBAC controls permissions; isolation also requires tenant\u002Fresource scoping.",[990,991],"“If the user is an admin, tenant checks are unnecessary.”","Admin authority must still have an explicit scope.",[993,994],"“Tenant ID in JWT is enough.”","It can be a trusted input only if validated and applied consistently to every protected resource path.",[996,997],"“Separate databases remove authorization requirements.”","Users still need operation-level permissions inside their tenant.",[999,1000],"“A tenant_id column means the system is isolated.”","The field only helps if access paths enforce it.",[1002,1003],"“UUIDs prevent cross-tenant access.”","Unpredictable identifiers are defense in depth, not authorization.",[1005,1006],"“RLS means application code needs no security checks.”","Application authorization, correct DB roles and policy coverage still matter.",[1008,1009],"“One shared vector DB is unsafe.”","It can be safe if isolation is enforceable and verified; physical separation is one option, not the only one.",[1011,1012],"“Platform support needs global ADMIN.”","Cross-tenant support should be a distinct, constrained and auditable authority.",[1014,1015],"“Internal services can skip tenant checks.”","Internal paths can still be compromised or misconfigured and must preserve tenant context.",{},{"id":1018,"data":1019,"type":42,"tunes":1021},"h-design",{"text":1020,"level":247},"A practical design sequence",{},{"id":1023,"data":1024,"type":334,"tunes":1063},"design-flow",{"steps":1025,"title":1062,"orientation":333},[1026,1029,1032,1035,1038,1041,1044,1047,1050,1053,1056,1059],{"label":1027,"description":1028},"1. Define tenant ownership","Classify which entities and resources are global, tenant-scoped, user-scoped or intentionally cross-tenant.",{"label":1030,"description":1031},"2. Define operations","Create explicit permissions for reads, writes, publishing, approvals, administration and other business actions.",{"label":1033,"description":1034},"3. Define roles","Group permissions according to responsibilities without embedding accidental global scope.",{"label":1036,"description":1037},"4. Define membership scope","Bind role assignments to the tenant\u002Fworkspace\u002Fproject context in which they apply.",{"label":1039,"description":1040},"5. Resolve trusted tenant context","Derive tenant identity from authenticated, server-verified membership or service authorization.",{"label":1042,"description":1043},"6. Enforce resource ownership","Apply tenant scope at every tenant-owned data\u002Fservice boundary.",{"label":1045,"description":1046},"7. Add defense in depth","Use RLS, separate credentials, schemas\u002Fdatabases, storage policies or policy engines where risk justifies them.",{"label":1048,"description":1049},"8. Carry scope through derived systems","Preserve tenant metadata in cache, search, vector indexes, queues, files and analytics.",{"label":1051,"description":1052},"9. Model cross-tenant operations explicitly","Separate platform administration and service identities from ordinary tenant roles.",{"label":1054,"description":1055},"10. Test both axes","Run negative tests for missing permission and for wrong tenant independently.",{"label":1057,"description":1058},"11. Audit tenant + permission together","Log who acted, in which tenant, on what target and under which authority.",{"label":1060,"description":1061},"12. Re-test after schema\u002Fruntime changes","Isolation can break when new tables, caches, queues or retrieval paths are introduced.","Design permissions and isolation as separate dimensions",{},{"id":1065,"data":1066,"type":42,"tunes":1068},"h-checklist",{"text":1067,"level":247},"RBAC + tenant isolation checklist",{},{"id":1070,"data":1071,"type":391,"tunes":1117},"checklist-table",{"content":1072,"stretched":43,"withHeadings":14},[1073,1075,1078,1081,1084,1087,1090,1093,1096,1099,1102,1105,1108,1111,1114],[412,1074],"Expected answer",[1076,1077],"Who is the principal?","Authenticated user\u002Fservice\u002Fagent identity",[1079,1080],"Which tenant context applies?","Server-verified membership or service scope",[1082,1083],"Which operation is requested?","Typed permission or policy action",[1085,1086],"Does the principal have that permission?","Role\u002Fpolicy decision",[1088,1089],"Who owns the target resource?","Explicit tenant\u002Fglobal\u002Fuser classification",[1091,1092],"Does resource scope match authority?","Tenant-aware lookup\u002Fpolicy",[1094,1095],"Can storage bypass application checks?","Defense-in-depth decision documented",[1097,1098],"Are caches tenant-safe?","Keys\u002Fnamespaces and authorization preserve tenant scope",[1100,1101],"Are files\u002Fblobs tenant-safe?","Object policy and signed URL issuance enforce scope",[1103,1104],"Are async jobs tenant-safe?","Verified context propagates and is revalidated",[1106,1107],"Is RAG\u002Fsearch tenant-safe?","Metadata\u002Fcollection isolation enforced before model context",[1109,1110],"Are cross-tenant admins explicit?","Separate authority, controls and audit",[1112,1113],"Can ordinary credentials bypass isolation?","No, or tightly documented exceptional path",[1115,1116],"Are negative cross-tenant tests automated?","Yes for every relevant access layer",{},{"id":1119,"data":1120,"type":42,"tunes":1122},"h-edge",{"text":1121,"level":247},"Edge cases and limitations",{},{"id":1124,"data":1125,"type":218,"tunes":1127},"p-edge-1",{"text":1126},"A user can belong to multiple tenants. The current tenant should therefore be an explicit execution context, not inferred permanently from the user account.",{},{"id":1129,"data":1130,"type":218,"tunes":1132},"p-edge-2",{"text":1131},"Some resources are intentionally shared between selected tenants, such as collaboration spaces or consortium data. This requires an explicit sharing model; pretending the resource belongs to one tenant and adding exceptions later usually creates ambiguous authorization.",{},{"id":1134,"data":1135,"type":218,"tunes":1137},"p-edge-3",{"text":1136},"Noisy-neighbor isolation is related but different from confidentiality isolation. A tenant may never see another tenant's data yet still exhaust shared CPU, queue capacity or database connections. Rate limits and resource quotas can therefore be tenant-aware as an availability boundary.",{},{"id":1139,"data":1140,"type":218,"tunes":1142},"p-edge-4",{"text":1141},"Physical isolation is not automatically secure if control-plane credentials or administrative paths can cross boundaries. Logical isolation is not automatically weak if policies are centrally enforced, least-privileged and thoroughly tested.",{},{"id":1144,"data":1145,"type":218,"tunes":1147},"p-edge-5",{"text":1146},"Tenant isolation requirements can differ by data class. Public catalog data, billing records and private AI documents may justify different storage and encryption boundaries inside the same SaaS product.",{},{"id":1149,"data":1150,"type":42,"tunes":1152},"h-change",{"text":1151,"level":247},"What would change this answer?",{},{"id":1154,"data":1155,"type":218,"tunes":1157},"p-change-1",{"text":1156},"The exact implementation changes with architecture: serverless APIs, Kubernetes, PostgreSQL, object storage, vector databases and policy engines expose different isolation primitives.",{},{"id":1159,"data":1160,"type":218,"tunes":1162},"p-change-2",{"text":1161},"The required strength also changes with regulation, customer contracts, data sensitivity, threat model and operational scale. Some tenants may justify siloed databases or infrastructure while others share pooled resources.",{},{"id":1164,"data":1165,"type":218,"tunes":1167},"p-change-3",{"text":1166},"The conceptual distinction does not change: permission to perform an operation is not the same thing as permission to cross a tenant boundary.",{},{"id":1169,"data":1170,"type":42,"tunes":1172},"h-related",{"text":1171,"level":247},"Related canonical knowledge",{},{"id":1174,"data":1175,"type":218,"tunes":1177},"p-related-1",{"text":1176},"S01 is a security-boundary prerequisite for Enterprise AI Architecture and AI Governance. Once AI tools, RAG or agents operate over multi-tenant data, tenant identity must travel through retrieval, tool execution, memory, caches and audit traces.",{},{"id":1179,"data":1180,"type":218,"tunes":1182},"p-related-2",{"text":1181},"It also connects directly to Agentic AI: tool capability and role permission must still be constrained by tenant ownership before an agent can read or mutate business resources.",{},{"id":1184,"data":1185,"type":1190,"tunes":1191},"ref-agentic",{"url":1186,"title":1187,"excerpt":1188,"ctaLabel":1189},"https:\u002F\u002Fstajic.de\u002Fde\u002Fblog\u002Fmcp-vs-a2a-vs-ucp-vs-ap2-vs-a2ui-the-agent-protocol-stack-explained","MCP vs A2A vs UCP vs AP2 vs A2UI: The Agent Protocol Stack Explained","Protocol interoperability does not replace authorization or tenant isolation. Capability discovery and business authority remain separate architecture concerns.","Read the protocol stack article","referralArticle",{},{"id":1193,"data":1194,"type":218,"tunes":1196},"p-related-3",{"text":1195},"For RAG, tenant isolation must be enforced before protected chunks reach model context.",{},{"id":1198,"data":1199,"type":1190,"tunes":1204},"ref-rag",{"url":1200,"title":1201,"excerpt":1202,"ctaLabel":1203},"https:\u002F\u002Fstajic.de\u002Fblog\u002Fwhat-is-rag-the-simplest-explanation-of-how-it-works","What Is RAG? The Simplest Explanation of How It Works","The retrieval foundation for understanding where tenant-aware source filtering and vector-store isolation must be enforced.","Read the RAG foundation",{},{"id":1206,"data":1207,"type":42,"tunes":1209},"h-faq",{"text":1208,"level":247},"Frequently asked questions",{},{"id":1211,"data":1212,"type":1211,"tunes":1251},"faq",{"items":1213,"title":1250},[1214,1218,1222,1226,1230,1234,1238,1242,1246],{"id":1215,"answer":1216,"question":1217},"faq1","RBAC determines which operations a principal may perform. Tenant isolation determines which tenant's resources those operations may access. Secure multi-tenant applications normally need both.","What is the difference between RBAC and tenant isolation?",{"id":1219,"answer":1220,"question":1221},"faq2","No. ADMIN should have an explicit scope. A tenant administrator normally has broad permissions only inside that tenant, while cross-tenant platform administration should be modeled separately.","Does an ADMIN role automatically allow access to all tenants?",{"id":1223,"answer":1224,"question":1225},"faq3","No. Authentication proves identity. Authorization controls permitted actions. Tenant isolation additionally prevents those actions from reaching the wrong tenant's resources.","Is authentication enough for tenant isolation?",{"id":1227,"answer":1228,"question":1229},"faq4","It can be one input to tenant context, but the server must verify current membership\u002Fauthority and enforce the scope at protected resource boundaries. A claim alone does not replace isolation controls.","Should tenantId be stored in the JWT?",{"id":1231,"answer":1232,"question":1233},"faq5","Not necessarily. Shared-table, RLS, schema, database, infrastructure and hybrid isolation models can all be valid depending on risk and operational requirements.","Do I need a separate database per tenant?",{"id":1235,"answer":1236,"question":1237},"faq6","RLS can provide strong defense in depth, but correct database roles, request context, policy coverage and application-level authorization still matter.","Can PostgreSQL RLS replace tenant filters in application code?",{"id":1239,"answer":1240,"question":1241},"faq7","Tenant\u002Faccess scope should be enforced during retrieval so unauthorized chunks never enter model context. Preserve access metadata through chunking and indexing.","How should RAG enforce tenant isolation?",{"id":1243,"answer":1244,"question":1245},"faq8","Yes. This is common in B2B SaaS and is a strong reason to scope role assignments by tenant membership rather than treating roles as globally attached to the user.","Can one user have different roles in different tenants?",{"id":1247,"answer":1248,"question":1249},"faq9","Use negative cross-tenant tests: create at least two tenants, give a user valid permissions in one tenant, then prove every protected path denies access to the other tenant's resources.","What is the best test for tenant isolation?","RBAC vs tenant isolation FAQ",{},{"id":1253,"data":1254,"type":42,"tunes":1256},"h-glossary",{"text":1255,"level":247},"Glossary",{},{"id":1258,"data":1259,"type":1258,"tunes":1305},"glossary",{"title":1260,"entries":1261},"Key multi-tenant security terms",[1262,1264,1267,1270,1273,1277,1281,1285,1289,1293,1297,1301],{"term":395,"anchor":394,"definition":1263},"Role-Based Access Control: an authorization model that associates permissions with roles and assigns users or principals to those roles.",{"term":1265,"anchor":397,"definition":1266},"Tenant","A customer, organization, workspace or other isolated logical consumer of a shared multi-tenant system.",{"term":398,"anchor":1268,"definition":1269},"tenant-isolation","Mechanisms that prevent one tenant from accessing, modifying or receiving another tenant's resources in a shared system.",{"term":415,"anchor":1271,"definition":1272},"authentication","Verification of the identity of a user, service or other principal.",{"term":1274,"anchor":1275,"definition":1276},"Authorization","authorization","Decision process that determines whether a principal may perform a requested operation on a resource.",{"term":1278,"anchor":1279,"definition":1280},"Permission","permission","A defined allowed operation or capability such as orders.read or users.write.",{"term":1282,"anchor":1283,"definition":1284},"Role","role","A named grouping of permissions associated with a responsibility or function.",{"term":1286,"anchor":1287,"definition":1288},"ABAC","abac","Attribute-Based Access Control: authorization based on attributes of the principal, resource, action or environment.",{"term":1290,"anchor":1291,"definition":1292},"Row-Level Security","row-level-security","Database policy mechanism that restricts which rows a database role or session may read or modify.",{"term":1294,"anchor":1295,"definition":1296},"Cross-tenant access","cross-tenant-access","Any access path in which a principal operating under one tenant context reaches resources belonging to another tenant.",{"term":1298,"anchor":1299,"definition":1300},"Platform administrator","platform-administrator","A privileged operational identity with explicitly modeled authority that may span multiple tenants.",{"term":1302,"anchor":1303,"definition":1304},"Tenant context","tenant-context","The verified tenant scope under which the current request, job or agent operation executes.",{},{"id":1307,"data":1308,"type":42,"tunes":1310},"h-conclusion",{"text":1309,"level":247},"Conclusion",{},{"id":1312,"data":1313,"type":218,"tunes":1315},"p-conclusion-1",{"text":1314},"RBAC and tenant isolation are complementary, not competing security mechanisms. RBAC structures operational permission; tenant isolation constrains the resource boundary inside which that permission can apply.",{},{"id":1317,"data":1318,"type":218,"tunes":1320},"p-conclusion-2",{"text":1319},"A robust multi-tenant request therefore needs more than “user has role ADMIN.” It needs a verified principal, verified tenant context, an allowed operation, a tenant-scoped target and enforcement at every resource layer that can carry tenant-owned data.",{},{"id":1322,"data":1323,"type":218,"tunes":1325},"p-conclusion-3",{"text":1324},"The shortest reliable rule is: authorize the action, then isolate the scope — and never assume one proves the other.",{},{"id":1327,"data":1328,"type":42,"tunes":1330},"h-sources",{"text":1329,"level":247},"Primary sources and current guidance",{},{"id":1332,"data":1333,"type":218,"tunes":1335},"p-sources-note",{"text":1334},"The sources below support the RBAC definition and current tenant-isolation guidance. The Aaasaasa AI CMS section is original implementation evidence and is intentionally bounded to the code patterns that were verified.",{},{"id":1337,"data":1338,"type":1344,"tunes":1345},"src-nist-rbac",{"link":1339,"meta":1340},"https:\u002F\u002Fcsrc.nist.gov\u002Fprojects\u002Frole-based-access-control",{"image":1341,"title":1342,"description":1343},{"url":369},"NIST — Role Based Access Control","NIST overview of RBAC models and the INCITS RBAC standard, including users, roles, permissions, operations and objects.","linkTool",{},{"id":1347,"data":1348,"type":1344,"tunes":1354},"src-nist-glossary",{"link":1349,"meta":1350},"https:\u002F\u002Fcsrc.nist.gov\u002Fglossary\u002Fterm\u002Frole_based_access_control",{"image":1351,"title":1352,"description":1353},{"url":369},"NIST CSRC — RBAC glossary","Current NIST glossary definitions of role-based access control as permission assignment through roles.",{},{"id":1356,"data":1357,"type":1344,"tunes":1363},"src-aws-isolation",{"link":1358,"meta":1359},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fwhitepapers\u002Flatest\u002Fsaas-tenant-isolation-strategies\u002Fthe-isolation-mindset.html",{"image":1360,"title":1361,"description":1362},{"url":369},"AWS — The isolation mindset","AWS SaaS guidance explicitly distinguishing authentication\u002Fauthorization from tenant isolation and recommending shared isolation mechanisms.",{},{"id":1365,"data":1366,"type":1344,"tunes":1372},"src-aws-faq",{"link":1367,"meta":1368},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsaas-multitenant-api-access-authorization\u002Ffaq.html",{"image":1369,"title":1370,"description":1371},{"url":369},"AWS — Multi-tenant authorization FAQ","Current guidance explaining the difference between authorization and tenant isolation in SaaS applications.",{},{"id":1374,"data":1375,"type":1344,"tunes":1381},"src-aws-avp",{"link":1376,"meta":1377},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fsaas-multitenant-api-access-authorization\u002Favp-design-considerations.html",{"image":1378,"title":1379,"description":1380},{"url":369},"AWS — Multi-tenant design considerations","Current SaaS guidance distinguishing tenant isolation from authorization and discussing pooled\u002Fsiloed authorization policy models.",{},{"id":1383,"data":1384,"type":1344,"tunes":1390},"src-owasp-multi",{"link":1385,"meta":1386},"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FMulti_Tenant_Security_Cheat_Sheet.html",{"image":1387,"title":1388,"description":1389},{"url":369},"OWASP — Multi-Tenant Application Security Cheat Sheet","Current practical guidance for tenant context, database isolation, caches, storage, queues, testing and cross-tenant access prevention.",{},{"id":1392,"data":1393,"type":1344,"tunes":1399},"src-owasp-rag",{"link":1394,"meta":1395},"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FRAG_Security_Cheat_Sheet.html",{"image":1396,"title":1397,"description":1398},{"url":369},"OWASP — RAG Security Cheat Sheet","Current guidance requiring access control at retrieval time and tenant isolation for multi-tenant vector stores.",{},{"id":1401,"data":1402,"type":1344,"tunes":1408},"src-owasp-auth-test",{"link":1403,"meta":1404},"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FAuthorization_Regression_Testing_Cheat_Sheet.html",{"image":1405,"title":1406,"description":1407},{"url":369},"OWASP — Authorization Regression Testing","Current testing guidance including role-demotion and cross-tenant boundary tests.",{},"2.31.6","RBAC controls what a user may do; tenant isolation controls which tenant’s resources that action may reach. Learn why multi-tenant SaaS security requires both boundaries.","\u002Fuploads\u002F2026\u002F10\u002Frbac-vs-tenant-isolation-two-different-security-boundaries-1791485111528-qqtzby.webp","rbac-vs-tenant-isolation-two-different-security-boundaries-1791485111528-qqtzby","PUBLISHED","2026-10-08T14:43:00.000Z","2026-10-08T18:43:57.878Z","2026-10-08T18:56:28.335Z",{"en":1418,"de":1419,"sr":1420,"es":1421,"fr":1422,"it":1423,"ru":1424,"zh":1425},"\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fde\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fsr\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fes\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Ffr\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fit\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fru\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries","\u002Fzh\u002Fblog\u002Frbac-vs-tenant-isolation-two-different-security-boundaries",[1427,1431,1435],{"id":1428,"name":1429,"slug":1430},84,"Policy & Data Boundaries","policy-and-data",{"id":1432,"name":1433,"slug":1434},57,"Data Boundaries","data-boundaries",{"id":1436,"name":1437,"slug":1438},64,"Information Architecture","information-architecture",{"id":1440,"login":1441,"email":1442,"displayName":1443},"20","rooth8233","aleksandar@stajic.de","Aleksandar Stajić",[1445],{"lang":7,"title":208,"content":210,"contentJson":1446,"excerpt":1410},{"time":212,"blocks":1447,"version":1409},[1448,1451,1454,1457,1460,1463,1466,1469,1472,1475,1478,1481,1484,1487,1490,1493,1496,1499,1509,1512,1515,1518,1521,1524,1543,1546,1554,1557,1560,1563,1566,1569,1572,1575,1578,1581,1584,1587,1595,1598,1601,1604,1607,1610,1613,1624,1627,1630,1633,1636,1639,1642,1645,1648,1651,1654,1657,1660,1663,1666,1669,1672,1675,1678,1681,1684,1687,1690,1693,1696,1699,1702,1705,1708,1711,1714,1717,1720,1723,1726,1729,1732,1735,1738,1749,1752,1755,1758,1761,1764,1767,1770,1781,1784,1787,1790,1793,1796,1799,1814,1817,1820,1838,1841,1856,1859,1875,1878,1897,1900,1903,1906,1909,1912,1915,1918,1921,1924,1927,1930,1933,1936,1939,1942,1945,1948,1961,1964,1980,1983,1986,1989,1992,1995,1998,2003,2008,2013,2018,2023,2028,2033],{"id":215,"data":1449,"type":218,"tunes":1450},{"text":217},{},{"id":221,"data":1452,"type":226,"tunes":1453},{"body":223,"title":224,"variant":225},{},{"id":229,"data":1455,"type":226,"tunes":1456},{"body":231,"title":232,"variant":233},{},{"id":236,"data":1458,"type":226,"tunes":1459},{"body":238,"title":239,"variant":240},{},{"id":243,"data":1461,"type":248,"tunes":1462},{"title":245,"maxLevel":246,"minLevel":247},{},{"id":251,"data":1464,"type":42,"tunes":1465},{"text":253,"level":247},{},{"id":256,"data":1467,"type":218,"tunes":1468},{"text":258},{},{"id":261,"data":1470,"type":218,"tunes":1471},{"text":263},{},{"id":266,"data":1473,"type":218,"tunes":1474},{"text":268},{},{"id":271,"data":1476,"type":42,"tunes":1477},{"text":273,"level":247},{},{"id":276,"data":1479,"type":218,"tunes":1480},{"text":278},{},{"id":281,"data":1482,"type":218,"tunes":1483},{"text":283},{},{"id":286,"data":1485,"type":218,"tunes":1486},{"text":288},{},{"id":291,"data":1488,"type":42,"tunes":1489},{"text":293,"level":247},{},{"id":296,"data":1491,"type":218,"tunes":1492},{"text":298},{},{"id":301,"data":1494,"type":218,"tunes":1495},{"text":303},{},{"id":306,"data":1497,"type":218,"tunes":1498},{"text":308},{},{"id":311,"data":1500,"type":334,"tunes":1508},{"steps":1501,"title":332,"orientation":333},[1502,1503,1504,1505,1506,1507],{"label":315,"description":316},{"label":318,"description":319},{"label":321,"description":322},{"label":324,"description":325},{"label":327,"description":328},{"label":330,"description":331},{},{"id":337,"data":1510,"type":42,"tunes":1511},{"text":339,"level":247},{},{"id":342,"data":1513,"type":218,"tunes":1514},{"text":344},{},{"id":347,"data":1516,"type":218,"tunes":1517},{"text":349},{},{"id":352,"data":1519,"type":218,"tunes":1520},{"text":354},{},{"id":357,"data":1522,"type":42,"tunes":1523},{"text":359,"level":247},{},{"id":362,"data":1525,"type":399,"tunes":1542},{"rows":1526,"title":390,"layout":391,"columns":1539},[1527,1529,1531,1533,1535,1537],{"id":366,"label":367,"values":1528},[369,369],{"id":371,"label":372,"values":1530},[369,369],{"id":375,"label":376,"values":1532},[369,369],{"id":379,"label":380,"values":1534},[369,369],{"id":383,"label":384,"values":1536},[369,369],{"id":387,"label":388,"values":1538},[369,369],[1540,1541],{"id":394,"label":395},{"id":397,"label":398},{},{"id":402,"data":1544,"type":42,"tunes":1545},{"text":404,"level":247},{},{"id":407,"data":1547,"type":391,"tunes":1553},{"content":1548,"stretched":43,"withHeadings":14},[1549,1550,1551,1552],[411,412,413],[415,416,417],[419,420,421],[398,423,424],{},{"id":427,"data":1555,"type":218,"tunes":1556},{"text":429},{},{"id":432,"data":1558,"type":42,"tunes":1559},{"text":434,"level":247},{},{"id":437,"data":1561,"type":218,"tunes":1562},{"text":439},{},{"id":442,"data":1564,"type":218,"tunes":1565},{"text":444},{},{"id":447,"data":1567,"type":218,"tunes":1568},{"text":449},{},{"id":452,"data":1570,"type":42,"tunes":1571},{"text":454,"level":247},{},{"id":457,"data":1573,"type":218,"tunes":1574},{"text":459},{},{"id":462,"data":1576,"type":218,"tunes":1577},{"text":464},{},{"id":467,"data":1579,"type":218,"tunes":1580},{"text":469},{},{"id":472,"data":1582,"type":42,"tunes":1583},{"text":474,"level":247},{},{"id":477,"data":1585,"type":218,"tunes":1586},{"text":479},{},{"id":482,"data":1588,"type":391,"tunes":1594},{"content":1589,"stretched":43,"withHeadings":14},[1590,1591,1592,1593],[486,487],[489,490],[492,493],[495,496],{},{"id":499,"data":1596,"type":218,"tunes":1597},{"text":501},{},{"id":504,"data":1599,"type":42,"tunes":1600},{"text":506,"level":247},{},{"id":509,"data":1602,"type":218,"tunes":1603},{"text":511},{},{"id":514,"data":1605,"type":218,"tunes":1606},{"text":516},{},{"id":519,"data":1608,"type":226,"tunes":1609},{"body":521,"title":522,"variant":523},{},{"id":526,"data":1611,"type":42,"tunes":1612},{"text":528,"level":247},{},{"id":531,"data":1614,"type":391,"tunes":1623},{"content":1615,"stretched":43,"withHeadings":14},[1616,1617,1618,1619,1620,1621,1622],[535,536,537],[539,540,541],[543,544,545],[547,548,549],[551,552,553],[555,556,557],[559,560,561],{},{"id":564,"data":1625,"type":218,"tunes":1626},{"text":566},{},{"id":569,"data":1628,"type":42,"tunes":1629},{"text":571,"level":247},{},{"id":574,"data":1631,"type":218,"tunes":1632},{"text":576},{},{"id":579,"data":1634,"type":218,"tunes":1635},{"text":581},{},{"id":584,"data":1637,"type":218,"tunes":1638},{"text":586},{},{"id":589,"data":1640,"type":42,"tunes":1641},{"text":591,"level":247},{},{"id":594,"data":1643,"type":218,"tunes":1644},{"text":596},{},{"id":599,"data":1646,"type":218,"tunes":1647},{"text":601},{},{"id":604,"data":1649,"type":218,"tunes":1650},{"text":606},{},{"id":609,"data":1652,"type":42,"tunes":1653},{"text":611,"level":247},{},{"id":614,"data":1655,"type":218,"tunes":1656},{"text":616},{},{"id":619,"data":1658,"type":218,"tunes":1659},{"text":621},{},{"id":624,"data":1661,"type":218,"tunes":1662},{"text":626},{},{"id":629,"data":1664,"type":42,"tunes":1665},{"text":631,"level":247},{},{"id":634,"data":1667,"type":218,"tunes":1668},{"text":636},{},{"id":639,"data":1670,"type":218,"tunes":1671},{"text":641},{},{"id":644,"data":1673,"type":218,"tunes":1674},{"text":646},{},{"id":649,"data":1676,"type":42,"tunes":1677},{"text":651,"level":247},{},{"id":654,"data":1679,"type":218,"tunes":1680},{"text":656},{},{"id":659,"data":1682,"type":218,"tunes":1683},{"text":661},{},{"id":664,"data":1685,"type":218,"tunes":1686},{"text":666},{},{"id":669,"data":1688,"type":226,"tunes":1689},{"body":671,"title":672,"variant":233},{},{"id":675,"data":1691,"type":42,"tunes":1692},{"text":677,"level":247},{},{"id":680,"data":1694,"type":218,"tunes":1695},{"text":682},{},{"id":685,"data":1697,"type":218,"tunes":1698},{"text":687},{},{"id":690,"data":1700,"type":42,"tunes":1701},{"text":692,"level":247},{},{"id":695,"data":1703,"type":218,"tunes":1704},{"text":697},{},{"id":700,"data":1706,"type":218,"tunes":1707},{"text":702},{},{"id":705,"data":1709,"type":218,"tunes":1710},{"text":707},{},{"id":710,"data":1712,"type":42,"tunes":1713},{"text":712,"level":247},{},{"id":715,"data":1715,"type":218,"tunes":1716},{"text":717},{},{"id":720,"data":1718,"type":218,"tunes":1719},{"text":722},{},{"id":725,"data":1721,"type":218,"tunes":1722},{"text":727},{},{"id":730,"data":1724,"type":42,"tunes":1725},{"text":732,"level":247},{},{"id":735,"data":1727,"type":218,"tunes":1728},{"text":737},{},{"id":740,"data":1730,"type":218,"tunes":1731},{"text":742},{},{"id":745,"data":1733,"type":218,"tunes":1734},{"text":747},{},{"id":750,"data":1736,"type":42,"tunes":1737},{"text":752,"level":247},{},{"id":755,"data":1739,"type":391,"tunes":1748},{"content":1740,"stretched":43,"withHeadings":14},[1741,1742,1743,1744,1745,1746,1747],[759,760,761,762],[764,765,766,767],[764,765,769,770],[764,772,766,773],[764,772,769,770],[776,777,778,779],[781,782,783,784],{},{"id":787,"data":1750,"type":42,"tunes":1751},{"text":789,"level":247},{},{"id":792,"data":1753,"type":226,"tunes":1754},{"body":794,"title":795,"variant":240},{},{"id":798,"data":1756,"type":218,"tunes":1757},{"text":800},{},{"id":803,"data":1759,"type":218,"tunes":1760},{"text":805},{},{"id":808,"data":1762,"type":218,"tunes":1763},{"text":810},{},{"id":813,"data":1765,"type":218,"tunes":1766},{"text":815},{},{"id":818,"data":1768,"type":218,"tunes":1769},{"text":820},{},{"id":823,"data":1771,"type":391,"tunes":1780},{"content":1772,"stretched":43,"withHeadings":14},[1773,1774,1775,1776,1777,1778,1779],[827,828],[830,831],[833,834],[836,837],[839,840],[842,843],[845,846],{},{"id":849,"data":1782,"type":226,"tunes":1783},{"body":851,"title":852,"variant":233},{},{"id":855,"data":1785,"type":42,"tunes":1786},{"text":857,"level":247},{},{"id":860,"data":1788,"type":218,"tunes":1789},{"text":862},{},{"id":865,"data":1791,"type":218,"tunes":1792},{"text":867},{},{"id":870,"data":1794,"type":218,"tunes":1795},{"text":872},{},{"id":875,"data":1797,"type":42,"tunes":1798},{"text":877,"level":247},{},{"id":880,"data":1800,"type":391,"tunes":1813},{"content":1801,"stretched":43,"withHeadings":14},[1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812],[884,885],[887,888],[890,891],[893,894],[896,897],[899,900],[902,903],[905,906],[908,909],[911,912],[914,915],{},{"id":918,"data":1815,"type":218,"tunes":1816},{"text":920},{},{"id":923,"data":1818,"type":42,"tunes":1819},{"text":925,"level":247},{},{"id":928,"data":1821,"type":391,"tunes":1837},{"content":1822,"stretched":43,"withHeadings":14},[1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836],[932,933],[935,936],[938,939],[941,942],[944,945],[947,948],[950,951],[953,954],[956,957],[959,960],[962,963],[965,966],[968,969],[971,972],{},{"id":975,"data":1839,"type":42,"tunes":1840},{"text":977,"level":247},{},{"id":980,"data":1842,"type":391,"tunes":1855},{"content":1843,"stretched":43,"withHeadings":14},[1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854],[984,985],[987,988],[990,991],[993,994],[996,997],[999,1000],[1002,1003],[1005,1006],[1008,1009],[1011,1012],[1014,1015],{},{"id":1018,"data":1857,"type":42,"tunes":1858},{"text":1020,"level":247},{},{"id":1023,"data":1860,"type":334,"tunes":1874},{"steps":1861,"title":1062,"orientation":333},[1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873],{"label":1027,"description":1028},{"label":1030,"description":1031},{"label":1033,"description":1034},{"label":1036,"description":1037},{"label":1039,"description":1040},{"label":1042,"description":1043},{"label":1045,"description":1046},{"label":1048,"description":1049},{"label":1051,"description":1052},{"label":1054,"description":1055},{"label":1057,"description":1058},{"label":1060,"description":1061},{},{"id":1065,"data":1876,"type":42,"tunes":1877},{"text":1067,"level":247},{},{"id":1070,"data":1879,"type":391,"tunes":1896},{"content":1880,"stretched":43,"withHeadings":14},[1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895],[412,1074],[1076,1077],[1079,1080],[1082,1083],[1085,1086],[1088,1089],[1091,1092],[1094,1095],[1097,1098],[1100,1101],[1103,1104],[1106,1107],[1109,1110],[1112,1113],[1115,1116],{},{"id":1119,"data":1898,"type":42,"tunes":1899},{"text":1121,"level":247},{},{"id":1124,"data":1901,"type":218,"tunes":1902},{"text":1126},{},{"id":1129,"data":1904,"type":218,"tunes":1905},{"text":1131},{},{"id":1134,"data":1907,"type":218,"tunes":1908},{"text":1136},{},{"id":1139,"data":1910,"type":218,"tunes":1911},{"text":1141},{},{"id":1144,"data":1913,"type":218,"tunes":1914},{"text":1146},{},{"id":1149,"data":1916,"type":42,"tunes":1917},{"text":1151,"level":247},{},{"id":1154,"data":1919,"type":218,"tunes":1920},{"text":1156},{},{"id":1159,"data":1922,"type":218,"tunes":1923},{"text":1161},{},{"id":1164,"data":1925,"type":218,"tunes":1926},{"text":1166},{},{"id":1169,"data":1928,"type":42,"tunes":1929},{"text":1171,"level":247},{},{"id":1174,"data":1931,"type":218,"tunes":1932},{"text":1176},{},{"id":1179,"data":1934,"type":218,"tunes":1935},{"text":1181},{},{"id":1184,"data":1937,"type":1190,"tunes":1938},{"url":1186,"title":1187,"excerpt":1188,"ctaLabel":1189},{},{"id":1193,"data":1940,"type":218,"tunes":1941},{"text":1195},{},{"id":1198,"data":1943,"type":1190,"tunes":1944},{"url":1200,"title":1201,"excerpt":1202,"ctaLabel":1203},{},{"id":1206,"data":1946,"type":42,"tunes":1947},{"text":1208,"level":247},{},{"id":1211,"data":1949,"type":1211,"tunes":1960},{"items":1950,"title":1250},[1951,1952,1953,1954,1955,1956,1957,1958,1959],{"id":1215,"answer":1216,"question":1217},{"id":1219,"answer":1220,"question":1221},{"id":1223,"answer":1224,"question":1225},{"id":1227,"answer":1228,"question":1229},{"id":1231,"answer":1232,"question":1233},{"id":1235,"answer":1236,"question":1237},{"id":1239,"answer":1240,"question":1241},{"id":1243,"answer":1244,"question":1245},{"id":1247,"answer":1248,"question":1249},{},{"id":1253,"data":1962,"type":42,"tunes":1963},{"text":1255,"level":247},{},{"id":1258,"data":1965,"type":1258,"tunes":1979},{"title":1260,"entries":1966},[1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978],{"term":395,"anchor":394,"definition":1263},{"term":1265,"anchor":397,"definition":1266},{"term":398,"anchor":1268,"definition":1269},{"term":415,"anchor":1271,"definition":1272},{"term":1274,"anchor":1275,"definition":1276},{"term":1278,"anchor":1279,"definition":1280},{"term":1282,"anchor":1283,"definition":1284},{"term":1286,"anchor":1287,"definition":1288},{"term":1290,"anchor":1291,"definition":1292},{"term":1294,"anchor":1295,"definition":1296},{"term":1298,"anchor":1299,"definition":1300},{"term":1302,"anchor":1303,"definition":1304},{},{"id":1307,"data":1981,"type":42,"tunes":1982},{"text":1309,"level":247},{},{"id":1312,"data":1984,"type":218,"tunes":1985},{"text":1314},{},{"id":1317,"data":1987,"type":218,"tunes":1988},{"text":1319},{},{"id":1322,"data":1990,"type":218,"tunes":1991},{"text":1324},{},{"id":1327,"data":1993,"type":42,"tunes":1994},{"text":1329,"level":247},{},{"id":1332,"data":1996,"type":218,"tunes":1997},{"text":1334},{},{"id":1337,"data":1999,"type":1344,"tunes":2002},{"link":1339,"meta":2000},{"image":2001,"title":1342,"description":1343},{"url":369},{},{"id":1347,"data":2004,"type":1344,"tunes":2007},{"link":1349,"meta":2005},{"image":2006,"title":1352,"description":1353},{"url":369},{},{"id":1356,"data":2009,"type":1344,"tunes":2012},{"link":1358,"meta":2010},{"image":2011,"title":1361,"description":1362},{"url":369},{},{"id":1365,"data":2014,"type":1344,"tunes":2017},{"link":1367,"meta":2015},{"image":2016,"title":1370,"description":1371},{"url":369},{},{"id":1374,"data":2019,"type":1344,"tunes":2022},{"link":1376,"meta":2020},{"image":2021,"title":1379,"description":1380},{"url":369},{},{"id":1383,"data":2024,"type":1344,"tunes":2027},{"link":1385,"meta":2025},{"image":2026,"title":1388,"description":1389},{"url":369},{},{"id":1392,"data":2029,"type":1344,"tunes":2032},{"link":1394,"meta":2030},{"image":2031,"title":1397,"description":1398},{"url":369},{},{"id":1401,"data":2034,"type":1344,"tunes":2037},{"link":1403,"meta":2035},{"image":2036,"title":1406,"description":1407},{"url":369},{},"Post erfolgreich abgerufen",{"items":2040,"source":2125,"manualIds":2126,"manualMatchedIds":2127},[2041,2048,2055,2062,2069,2076,2083,2090,2097,2104,2111,2118],{"id":2042,"slug":2043,"title":2044,"excerpt":2045,"featuredImage":2046,"publishedAt":2047},"364","tipps-fuer-die-verbesserung-der-seo-suchmaschinenoptimierung","Mastering the SEO Workflow: Essential Optimization Strategies for Organic Growth","A structured SEO workflow is crucial for sustainable organic growth. Learn the ten foundational strategies, from keyword research and technical optimization to content quality and performance analysis.","\u002Fuploads\u002F2026\u002F03\u002Ftipps-fuer-die-verbesserung-der-seo-suchmaschinenoptimierung-1774866098131-hwkzrg.webp","2024-01-26T06:35:00.000Z",{"id":2049,"slug":2050,"title":2051,"excerpt":2052,"featuredImage":2053,"publishedAt":2054},"472","why-more-context-can-make-ai-answers-worse","Why More Context Can Make AI Answers Worse","A larger context window does not guarantee a better answer. This article explains how signal dilution, conflicting evidence, stale state, position sensitivity, and lossy compression can reduce AI reliability—and introduces a practical Context Pressure Test.","\u002Fuploads\u002F2026\u002F09\u002Fwhy-more-context-can-make-ai-answers-worse-1790351615793-2ntv2v.webp","2026-09-25T11:51:00.000Z",{"id":2056,"slug":2057,"title":2058,"excerpt":2059,"featuredImage":2060,"publishedAt":2061},"483","what-is-an-ai-solution-architect-system-boundaries-responsibilities-and-trade-offs","What Is an AI Solution Architect? System Boundaries, Responsibilities and Trade-offs","An AI Solution Architect turns business requirements into a production-ready AI system across data, models, tools, security, runtime, evaluation and operations.","\u002Fuploads\u002F2026\u002F10\u002Fwhat-is-an-ai-solution-architect-system-boundaries-responsibilities-and-trade-offs-1791476643267-1st5xz.webp","2026-10-08T12:23:00.000Z",{"id":2063,"slug":2064,"title":2065,"excerpt":2066,"featuredImage":2067,"publishedAt":2068},"466","the-gpu-is-not-the-product-future-proof-private-ai-architecture","The GPU Is Not the Product: Future-Proof Private AI Architecture","Private AI infrastructure should not be designed around one GPU or one model. A more resilient approach combines fast inference GPUs, memory-rich AI systems, physical-AI nodes and optional frontier cloud models behind a capability-aware routing layer.","\u002Fuploads\u002F2026\u002F09\u002Fthe-gpu-is-not-the-product-future-proof-private-ai-architecture-1790140878812-8hsl39.webp","2026-09-23T01:19:00.000Z",{"id":2070,"slug":2071,"title":2072,"excerpt":2073,"featuredImage":2074,"publishedAt":2075},"480","when-should-an-ai-stop-trusting-its-own-knowledge-the-retrieval-trigger","When Should an AI Stop Trusting Its Own Knowledge? — The Retrieval Trigger","An AI model does not need retrieval for every question. The important problem is knowing when its internal knowledge is no longer enough. The Retrieval Trigger is a practical decision boundary that determines when an AI system should stop relying solely on model knowledge and obtain external evidence before answering.","\u002Fuploads\u002F2026\u002F09\u002Fwhen-should-an-ai-stop-trusting-its-own-knowledge-the-retrieval-trigger-1790574991244-f4rpyg.webp","2026-09-28T01:49:00.000Z",{"id":2077,"slug":2078,"title":2079,"excerpt":2080,"featuredImage":2081,"publishedAt":2082},"486","source-of-truth-in-ai-systems-where-reliable-knowledge-actually-comes-from","Source of Truth in AI Systems: Where Reliable Knowledge Actually Comes From","A Source of Truth defines which source is authoritative for a specific fact or state. Learn how it differs from RAG, provenance, memory, context, vector databases and systems of record.","\u002Fuploads\u002F2026\u002F10\u002Fsource-of-truth-in-ai-systems-where-reliable-knowledge-actually-comes-from-1791479103235-6bq9em.webp","2026-10-08T13:02:00.000Z",{"id":2084,"slug":2085,"title":2086,"excerpt":2087,"featuredImage":2088,"publishedAt":2089},"479","where-does-an-llm-get-its-data-rag-data-sources-in-python","Where Does an LLM Get Its Data? RAG Data Sources in Python","An LLM does not magically know your files, databases or APIs. This practical continuation of the RAG series shows, with simple Python, how external data becomes retrievable evidence: from text files and SQL to full-text search, embeddings, context assembly and the final LLM call.","\u002Fuploads\u002F2026\u002F09\u002Fwhere-does-an-llm-get-its-data-rag-data-sources-in-python-1790517200521-nfsi5i.webp","2026-09-27T05:51:00.000Z",{"id":2091,"slug":2092,"title":2093,"excerpt":2094,"featuredImage":2095,"publishedAt":2096},"494","air-gapped-ai-how-ai-systems-work-without-internet-or-cloud-access","Air-Gapped AI: How AI Systems Work Without Internet or Cloud Access","Air-gapped AI runs models, RAG and AI applications inside an isolated security domain without internet or cloud dependencies. Learn how models, data, updates and tools operate offline.","\u002Fuploads\u002F2026\u002F10\u002Fair-gapped-ai-how-ai-systems-work-without-internet-or-cloud-access-1791487983978-e6xqf0.webp","2026-10-08T11:32:00.000Z",{"id":2098,"slug":2099,"title":2100,"excerpt":2101,"featuredImage":2102,"publishedAt":2103},"481","generative-ai-explained-models-retrieval-tools-and-applications-are-not-the-same-thing","Generative AI Explained: Models, Retrieval, Tools and Applications Are Not the Same Thing","Generative AI is more than a model. Learn how models, retrieval, tools, context, runtimes and applications fit together in production AI systems.","\u002Fuploads\u002F2026\u002F10\u002Fgenerative-ai-explained-models-retrieval-tools-and-applications-are-not-the-same-thing-1791475411822-pp0dvz.webp","2026-10-08T12:00:00.000Z",{"id":2105,"slug":2106,"title":2107,"excerpt":2108,"featuredImage":2109,"publishedAt":2110},"468","ai-agent-memory-is-not-rag-how-to-separate-memory-retrieval-state-and-context","AI Agent Memory Is Not RAG: How to Separate Memory, Retrieval, State and Context","Agent memory, RAG, state, and context are often used as if they were interchangeable. They are not. This practical architecture model separates the four layers, shows where each belongs, and explains what breaks when systems collapse them into one.","\u002Fuploads\u002F2026\u002F09\u002Fai-agent-memory-is-not-rag-how-to-separate-memory-retrieval-state-and-context-1790350560308-np0xy6.webp","2026-09-25T11:34:00.000Z",{"id":2112,"slug":2113,"title":2114,"excerpt":2115,"featuredImage":2116,"publishedAt":2117},"471","how-to-know-whether-an-ai-agent-actually-used-the-right-evidence","How to Know Whether an AI Agent Actually Used the Right Evidence","An AI agent can cite sources and still use the wrong evidence. This article introduces a practical method for checking claim support, source authority, applicability, provenance, and whether the evidence actually influenced the answer.","\u002Fuploads\u002F2026\u002F09\u002Fhow-to-know-whether-an-ai-agent-actually-used-the-right-evidence-1790351317188-o5z9ve.webp","2026-09-25T11:47:00.000Z",{"id":2119,"slug":2120,"title":2121,"excerpt":2122,"featuredImage":2123,"publishedAt":2124},"470","what-should-an-ai-agent-remember-forget-recompute-or-retrieve-again","What Should an AI Agent Remember, Forget, Recompute or Retrieve Again?","Long-running agents should not remember everything. This article provides a practical lifecycle model for deciding what belongs in durable memory, what should be retrieved again, what is safer to recompute, and what should expire or be superseded.","\u002Fuploads\u002F2026\u002F09\u002Fwhat-should-an-ai-agent-remember-forget-recompute-or-retrieve-again-1790351131087-iehz28.webp","2026-09-25T09:43:00.000Z","fallback",[],[]]