KDCube Architecture: Trust, Isolation, and Data Boundaries
KDCube is a self-hosted application runtime built from explicit boundaries: trusted apps, scoped data, guarded authority, and split execution for untrusted generated code.
Which subject is isolated from which resource, by which mechanism, under which deployment profile?
KDCube architecture begins outside the model call. An AI application receives requests from people and automations, loads application code, schedules work, reads durable state, emits events, calls providers, handles files, spends money, and may run code generated at runtime. Each action crosses a different trust boundary.
Collapsing those boundaries into one word creates two opposite errors:
- a system is called insecure because trusted backend code can access backend resources, even though that code is the installed product;
- a system is called secure because one component runs in a container, even though identities, storage addresses, tools, or credentials are not scoped.
KDCube makes the subjects and crossings explicit. This article maps the architecture from the platform operator down to one stored byte. It explains what KDCube scopes automatically, what an application author must still model, what the generated-code profiles actually protect, and which claims depend on the deployed topology.
One terminology note: current source, descriptors, and routes still use
bundle in literal names such as bundle_id, bundles.yaml,
@bundle_entrypoint, and /api/integrations/bundles/.... In product and
builder-facing prose, that deployable unit is an application or app.
00Architecture highlights
| Concept | The takeaway |
|---|---|
| Deployment scope | One running KDCube deployment binds one effective tenant/project; tenant-aware data organization lets a control plane operate many such environments. |
| Application trust | Operator-installed app backends are trusted deployment code, not sandboxed plugins. |
| Multi-user runtime | Users can share workers and backing services because authoritative identity travels in request context and scoped store contracts. |
| Storage isolation | Platform stores provide an outer platform scope; custom stores must define their owner and minimum scope explicitly. |
| Runtime fences | Context crosses as a portable, JSON-safe situation; trusted runtimes bootstrap services and validated outputs reduce back. |
| Generated code | Untrusted code executes in ISO split by default in the reference deployment; legacy combined Docker shares a container/mount trust zone. |
| External authority | Connection Hub resolves connected accounts and delegated KDCube grants on the trusted side at the concrete operation boundary. |
| Evidence | Accounting and telemetry cover participating, instrumented paths; they are not universal egress discovery or an immutable compliance audit. |
| Self-hosting | The operator controls topology, providers, integrations, and allowed egress; configured external calls can still move selected data outside the deployment. |
01KDCube architecture in one boundary map
The shortest accurate map starts outside the runtime, with the operator:
The diagram contains boundaries with different meanings:
| Boundary | What it separates | Primary mechanism |
|---|---|---|
| Deployment boundary | One tenant/project environment from another | Runtime binding plus schemas, namespaces, and storage prefixes; optionally dedicated infrastructure |
| User boundary | One authenticated user's objects and authority from another user's | Bound request context, scoped store queries, and operation guards |
| Application boundary | One app's owned storage and surfaces from another app's conventions | App id in SDK addresses, app-owned roots, descriptors, and provider routing |
| Authority boundary | A caller from an operation it has not been granted | Platform authentication, Connection Hub projection, and resource/operation grants |
| Runtime fence | One execution's serializable situation and outputs from its coordinator | Portable context, bootstrap, workspace, side files, and reduce |
| Generated-code boundary | Untrusted generated code from trusted runtime resources | Split supervisor/executor topology, narrow mounts, no executor secrets, and no executor network by default |
A tenant namespace is not a generated-code sandbox. A runtime fence around an async task is not an operating-system security boundary. An authenticated user is not automatically authorized for every operation. A trusted application is not made untrusted merely because it can call a database.
The architecture works because each mechanism answers one specific question.
02Five subjects must not be collapsed into "the user"
Real requests can carry more than one relevant identity:
| Subject | Meaning |
|---|---|
| Platform operator | Owns the deployment, chooses applications, infrastructure, policies, and secrets, and is inside the trusted computing base. |
| Application | Operator-approved backend code loaded into the deployment. It owns declared APIs, tools, jobs, UI, data models, and app-local storage. |
| Actor | The person or automation that presented the proof at the current ingress boundary. |
| Platform/storage user | The KDCube subject under which platform roles and user-owned data are evaluated. It can be linked or projected from the actor. |
| External delegate or provider account | An automation acting for a KDCube user, or an external account that the user allowed KDCube to use. |
| Generated program | Runtime-created code. It is input to the executor, not an application and not a platform authority. |
For a direct browser login, actor, platform user, storage user, and economics subject may be the same. They do not have to be.
Telegram actor
|
| authenticated channel identity
v
Connection Hub identity edge
|
+-> storage may remain actor-scoped
+-> platform roles may use linked platform subject
`-> economics may use the consented paying subject
Similarly, an external automation can hold a bounded KDCube credential without becoming the approving user. A connected Gmail account can be used by a trusted mail tool without turning a Gmail token into the user's KDCube session.
The current authority projection records these distinctions instead of silently replacing one id with another. Every protected boundary asks for the identity and grant it actually requires.
03Deployment scope: one environment, many users and apps
KDCube can operate a platform composed of many tenant/project environments. The current runtime binding is deliberately narrower:
one running deployment -> one effective tenant/project
one tenant/project -> many authenticated users
one tenant/project -> many operator-approved applications
This is deliberately friendly to a multi-environment control plane without pretending one processor is a hostile-tenant sandbox. Tenant and project remain first-class fields in descriptors, registry records, schemas, Redis namespaces, object prefixes, events, and accounting lineage. A control plane can therefore provision, discover, upgrade, and observe many tenant/project-scoped deployments while preserving each environment's identity.
The tenant/project pair is used by configuration, service discovery, queue routing, persistence, events, and accounting. Backing infrastructure can then be selected independently:
logical separation physical separation
------------------ -------------------
shared PostgreSQL, separate schemas dedicated PostgreSQL
shared Redis, separate namespaces dedicated Redis
shared bucket, separate key prefixes dedicated bucket
shared EFS, separate app roots dedicated filesystem/mount
Both topologies can implement the tenant/project contract. They defend against different threats.
- Namespaces prevent correctly written platform services from addressing the wrong deployment's data.
- Dedicated resources also reduce the blast radius of credential, configuration, or service-level failures.
- Separate cloud accounts and networks add an infrastructure-owner boundary.
KDCube does not claim that mutually hostile operators or arbitrary, unreviewed application backends can safely share one processor. If application code must be treated as hostile, it belongs in a separate deployment or a stronger external isolation boundary.
04Applications are trusted deployment code
An application is selected through a descriptor and source reference:
operator review
|
v
bundles.yaml + pinned source/ref
|
v
application loader
|
v
trusted backend code in the proc service
This is the same trust decision as installing a backend plugin or deploying a service image. An application may:
- implement APIs, tools, agents, jobs, and event handlers;
- register UI, website, REST, MCP, and named-service surfaces;
- use SDK storage, secrets, provider, accounting, and event services;
- execute custom trusted code with the process privileges granted to proc.
The SDK makes correct scoping straightforward, but a trusted application can still bypass those contracts by opening an ambient database connection, inventing raw Redis keys, reading arbitrary mounted paths, or making a direct provider call. The platform cannot reconstruct a security boundary after trusted code deliberately bypasses it.
That yields a clear division:
| KDCube supplies | The operator/application author still owns |
|---|---|
| Descriptor-driven app loading and routing | Reviewing source and pinning immutable refs |
| Runtime-bound tenant/project/app context | Not accepting tenant, user, or authority from model/user arguments when context already owns it |
| Scoped SDK storage and credential APIs | Using those APIs instead of ambient clients and paths |
| Surface guards and grant evaluators | Declaring the correct guard for every non-public operation |
| Accounting hooks for supported calls | Routing paid work through instrumented services |
| Generated-code isolation profiles | Keeping untrusted code out of the trusted app process |
This is not a weakness hidden in the architecture. It is the architecture's trust root: the platform operator chooses which product code runs.
05One request, end to end
A browser, Telegram channel, REST client, MCP client, scheduled job, or peer app can all start work. The ingress proof differs; the internal rule does not: bind identity and deployment scope before application code or model output can choose an object.
Not every object needs every segment. The owner of a store chooses the minimum scope that makes the object unambiguous:
app runtime state:
tenant + project + app
user settings:
tenant + project + app + user + typed key
conversation event lane:
tenant + project + user + conversation + agent
conversation artifact:
tenant + project + user + conversation + turn
connected provider credential:
tenant + project + user-scoped secret key
The model may propose a conversation id, object ref, path, or tool arguments. It does not supply the authoritative tenant/project/user segments. A trusted resolver combines the proposal with runtime-bound context and returns either a scoped object or no object.
06Runtime context crosses fences explicitly
Work does not stay inside one Python call stack. It can cross:
- an async task;
- a worker thread;
- a local subprocess;
- a Docker or Fargate supervisor;
- a peer application call;
- a Data Bus provider;
- a later scheduled or delegated execution.
KDCube carries a compact, JSON-safe portable context room across supported runtime boundaries. It contains ids, routing, authority provenance, accounting lineage, and descriptors needed to reconstruct trusted services. It is not a generic object serializer and it is not a credential bag.
No live Redis client, database connection, or provider client is the portable contract. A trusted child runtime can reconstruct approved services after bootstrap. In split execution, the executor receives a narrower environment again; provider credentials and user secrets resolve only in the trusted supervisor.
The matching reduce phase is as important as bootstrap. Child files and side records do not become host truth merely because they exist. The reducer:
- reads expected side files and result manifests;
- validates them against the coordinator's contract;
- deduplicates or applies idempotent records;
- promotes selected artifacts or workspace deltas;
- reports child failure independently from missing outputs.
A fence can be an async task, thread, subprocess, Docker runtime, or remote service. That means fence describes an explicit execution handoff. It does not, by itself, claim an operating-system security boundary. The selected runtime profile determines the strength.
That distinction is concrete. A local subprocess inherits the host process environment and network, so it provides process and crash containment for trusted development work, not secret or network isolation. Legacy combined Docker filters the child environment but keeps supervisor and executor inside one container and mount trust zone. The reference deployment explicitly selects ISO split for untrusted code: the generated program runs in a separate, networkless-by-default executor with a reduced mount and credential view.
07Storage isolation: the complete map
There is no single "KDCube database." Different data has different owners, lifetimes, and isolation keys.
| Storage surface | Typical data | Platform-provided outer scope | Additional scope the app may need |
|---|---|---|---|
| PostgreSQL platform stores | Conversations, metadata, durable subsystem records, accounting | Tenant/project schema | User, app, conversation, object owner, or operation-specific predicates |
| Redis platform services | Queues, lanes, streams, sessions, locks, caches, registries | Tenant/project namespace in each service contract | App, user, conversation, resource, or subsystem namespace |
| App filesystem root | App-owned mutable files, mirrors, indexes, generated UI assets | Tenant/project/app root | User or object subdirectories when data is user-owned |
BundleArtifactStorage |
App-owned durable artifacts | Tenant/project/app logical prefix | User/object prefix when artifacts are not app-global |
| Conversation storage | Attachments, generated files, timeline artifacts | Tenant/project/user/conversation/turn | Artifact-relative path and hosted metadata |
| App properties | Non-secret runtime configuration and overrides | Tenant/project/app | Typed subsystem keys |
| User settings/properties | Durable per-user or per-conversation choices | Tenant/project/app/user | Conversation, agent, capability, or typed key |
| User-scoped secrets | Connected external-account credentials | Tenant/project/user secret owner | Provider, connector app, account, and credential kind |
| Custom vector/graph/search store | App-defined domain indexes and records | Only what the chosen SDK/store adds | App-defined ownership and authorization predicates |
The outer scope prevents one class of collision. It does not imply every inner scope.
For example:
tenant/project/app filesystem root
separates the app from another tenant/project/app root. It does not automatically separate Alice's files from Bob's files inside that app root. The application must add a user/object directory or use a higher-level user-scoped API.
PostgreSQL: deployment schema first, object ownership second
Project tables live in a tenant/project schema such as:
kdcube_<tenant>_<project>
This allows a PostgreSQL instance to be physically shared while platform stores address the deployment's schema. It is the tenant/project boundary, not the complete authorization model.
Inside that schema, a platform store may additionally query by:
user_id
app_id
conversation_id
turn_id
resource_id
The query must use the bound runtime subject. It must not trust a client or model to replace the owner predicate.
unsafe custom query:
SELECT ... WHERE conversation_id = <model supplied>
scoped query:
SELECT ... WHERE user_id = <RuntimeCtx user>
AND conversation_id = <requested id>
An application that creates custom tables owns their authorization model. If records from several apps or users share one table, include and enforce the necessary owner fields. A tenant/project schema alone does not create row-level user isolation, and this article does not claim that every custom table uses PostgreSQL row-level security.
Redis: use a namespace, not a naming habit
KDCube platform services define tenant/project-aware contracts for queues, conversation lanes, streams, relays, sessions, locks, registries, and selected caches. Application code must preserve the same discipline.
The cache APIs make an important distinction:
KVCache
raw Redis key/value cache
no namespace
no tenant/project prefix
NamespacedKVCache
wraps KVCache
namespace prefix
tenant/project prefix by default
Passing a raw KVCache through runtime code is useful. Storing app data in it
without converting it to a NamespacedKVCache is not isolated.
A user-scoped app cache normally needs all relevant segments:
tenant/project + namespace(app/subsystem) + user/object key
TTL is retention, not authorization. A Redis key that expires in one hour is still the wrong key if another app or user can address it during that hour. Similarly, a shared Pub/Sub channel or stream must carry the intended tenant/project and provider scope in its contract.
App filesystem storage: a stable app root, not automatic per-user storage
Applications receive a runtime-resolved filesystem root:
<bundle-storage-root>/<tenant>/<project>/<safe(app-id)>
App code should use self.bundle_storage_root() inside its entrypoint, or the
low-level bundle_storage_dir(...) helper where no entrypoint instance exists.
It should not invent host paths, mount paths, or file:// roots in application
properties.
The platform owns stable root selection. The application owns everything below it:
<app-root>/
_search_index/ app-global, if intentionally shared
_workflow/ app-owned pipeline state
users/
<bound-user-id>/ app-created user boundary
exports/
The physical root may be local disk or shared storage such as EFS. If several proc workers can prepare the same app-owned output, the app must use the documented shared critical section and source signature. A lock protects concurrent mutation; it does not replace user authorization.
The resolved app root is an addressing contract for trusted applications. It is not necessarily a separate OS mount or ACL for every loaded app. Trusted code that deliberately traverses ambient mounts or bypasses the helper remains inside the operator's trust base. Applications that must be hostile to one another require separate deployment-level isolation.
App artifact storage: backend-neutral and app-scoped
BundleArtifactStorage is the backend-neutral API for app-owned artifacts. Its
logical layout is:
cb/tenants/{tenant}/projects/{project}/ai-bundle-storage/{app-id}/...
The deployment chooses local filesystem, S3, or another supported backend. App code receives the API rather than a physical storage URI.
This surface gives an app boundary. If the app stores user-owned objects, its
logical keys must add user/object scope or it must use a user-aware domain
store. BundleArtifactStorage is not interchangeable with conversation file
hosting. As with the filesystem helper, the app id in the logical prefix is a
trusted SDK contract, not a claim that mutually hostile in-process apps cannot
construct another address.
Conversation files: metadata and blobs share one lineage
Conversation storage combines:
- PostgreSQL metadata and indexing;
- object storage for attachments and generated artifacts;
- timeline records and logical refs used by the agent and UI.
The object layout includes the bound lineage:
cb/tenants/<tenant>/projects/<project>/attachments/
<user_id>/<conversation_id>/<turn_id>/<artifact-relative-path>
A trusted tool that produces a user-visible file uses the declared tool result
contract or host_files(...). The hosting service already knows
tenant/project/user/conversation/turn scope, registers metadata, and emits the
corresponding conversation event.
Generated code does not receive the historical storage root. A trusted resolver finds an allowed object under the bound user, materializes selected bytes into the current workspace, and later hosts only declared output.
Properties, user settings, and secrets are different stores
These categories must stay separate:
| Category | Suitable contents | Boundary |
|---|---|---|
| Tracked app descriptor | Source refs, non-secret config, declared surfaces, secret references | Deployment + app |
| App properties | Mutable non-secret app configuration and runtime overrides | Tenant + project + app |
| User settings/properties | User choices, including typed conversation/agent selections where applicable | Tenant + project + app + user |
| Deployment/app secrets | Provider keys and deployment credentials resolved by server-side secret lifecycle | Deployment/app secret reference |
| Connected-account credentials | OAuth tokens, app passwords, or other user-delegated provider credentials | Tenant + project + user + provider/account |
Production credentials do not belong in tracked descriptors, browser config, model context, or generated source. The split profile also keeps platform secret stores, supervisor descriptors, storage roots, and provider credentials out of the executor container.
Connection Hub keeps connected-account metadata and credential references under the KDCube user's scope. Raw provider credentials live in the configured user-scoped secret mechanism. A trusted integration tool resolves one only after matching:
current user
+ connector app
+ provider account
+ required claims
+ requested operation
This is a contract for platform-supported credential paths. It is not an absolute statement that trusted custom application code can never access a credential: trusted backend code executes inside the operator's trust base and must use the secret lifecycle correctly. It is also not a guarantee supplied by every execution profile. Local subprocesses inherit the host environment, and legacy combined Docker shares the supervisor's container/mount trust zone.
Custom vector, graph, and provider stores remain application models
Vector databases, graph stores, third-party SaaS indexes, and custom SQL services do not become user-isolated merely because KDCube called them.
The application must decide:
- whether the store is app-global, tenant/project-wide, or user-owned;
- which namespace or collection contains the records;
- which owner fields are written;
- which bound identity is used on every query;
- whether search results are re-authorized before materialization;
- how deletion, retention, and account unlinking propagate.
A useful rule is:
technology selects the storage engine
the domain contract selects the owner
the runtime context supplies the authoritative subject
08What is automatic, and what is not
This table is the practical contract for application builders:
| Surface | Automatic when using the platform API | Still explicit |
|---|---|---|
| Deployment startup | One effective tenant/project is bound | Choosing shared versus dedicated backing infrastructure |
| Platform PostgreSQL stores | Tenant/project schema and store-specific owner predicates | Ownership rules for custom tables and direct SQL |
| Platform Redis services | Service-owned tenant/project namespaces | Namespacing raw app caches, channels, streams, and locks |
| App filesystem helper | Tenant/project/app root | User/object layout below the root |
| App artifact API | Tenant/project/app logical prefix | User/object keys for user-owned artifacts |
| Conversation hosting | Tenant/project/user/conversation/turn lineage | Declaring which generated files are deliverables |
| User settings API | Tenant/project/app/user ownership | Typed key semantics such as conversation or agent selection |
| Connection Hub account resolver | Current user, provider/account, claims, health | Declaring the claims a tool needs and handling reconnect/consent |
| Managed REST/MCP guard | Server-side resource/operation grant evaluation | Declaring the correct resource, operation, and guard |
| Accounting SDK services | Records for instrumented calls | Avoiding direct uninstrumented provider calls when full attribution is required |
| Split executor | Narrow executor view, no secret store, no network by default | Tool design, mount policy, limits, and infrastructure hardening |
The phrase "automatic isolation" is therefore useful only when the surface and scope are named.
09Data in motion preserves scope, but each consumer still guards its work
KDCube has several communication mechanisms because they solve different problems:
| Mechanism | Purpose |
|---|---|
| Conversation Event Bus | Ordered events that can affect a conversation or schedule an app turn |
| Data Bus | Typed request/response or event exchange between app-owned provider surfaces |
| Live relay | Transient delivery to connected browser/client streams |
| Direct app operation | Synchronous application-to-application call under bound context |
The actor, tenant/project, routing, and correlation facts cross supported transitions explicitly. The portable context can reconstruct trusted services in a receiving runtime. That does not mean an event body grants authority.
caller context
|
+-> message identity and routing metadata
|
v
provider boundary
|
+-> verify namespace/resource/operation
+-> resolve current authority or connected account
`-> execute app-owned domain operation
The receiving provider remains responsible for its own operation guard and domain ownership checks. This prevents an internal transport from becoming an ambient bypass.
Operational event and accounting records are valuable evidence. They are not, by themselves, an immutable compliance audit. The operator owns retention, access control, export, monitoring, and any tamper-evident audit requirement.
10External authority flows in both directions
Connection Hub brokers two opposite relationships:
Delegated to KDCube
An application tool declares the provider/connector app and claims it needs, for example:
gmail.read
gmail.send
slack.search
slack.post
When the current user's account is absent, unhealthy, or lacks a required claim, the integration returns the standard consent/reconnect condition. A UI or MCP client can present the Connection Hub action to the user. After consent, the trusted tool resolves the credential and calls the provider. The model receives the result, not the token. Under the default ISO split profile, the generated executor likewise receives no provider credential; local and legacy combined profiles do not provide the same credential-isolation boundary.
Delegated by KDCube
An external automation receives a bounded bearer credential. The authoritative record remains server-side and maps resources to grants:
resource A -> [read]
resource B -> [read, write]
At the protected REST or MCP boundary, the managed guard loads the record and checks the matched resource and concrete operation. Grants are not evaluated as one global union; a write grant on resource B does not become write authority on resource A.
Under the standard managed-guard contract, a wildcard resource carrying the platform super-admin role is intended to cover all platform/application API resources when the operator intentionally enables administrative delegation. The endpoint must still use that guard; this does not manufacture external provider claims or bypass an unrelated custom authorization model. Non-admin credentials remain constrained by their configured resource-to-grants map.
The token is still a bearer credential. Expiry, revocation, secure storage, and transport protection remain necessary.
11REST and MCP are surfaces, not trust levels
An app can expose public, platform-authenticated, or managed/delegated REST and MCP operations.
client
|
v
REST or MCP transport
|
v
declared boundary guard
|
+-> authenticate or load delegated record
+-> match resource
+-> match operation/tool
+-> check roles/grants
`-> bind current subject
|
v
application operation
MCP standardizes discovery and tool calls. It does not decide:
- which user owns the data;
- which app may expose the operation;
- which external client can call it;
- which resource grants cover it;
- which account pays;
- whether the endpoint is public.
Those remain KDCube/application policy. Conversely, adding MCP support to one app does not turn the repository into one MCP plugin with ambient workstation access.
12Generated-code isolation: profiles are not equivalent
Generated code is a different trust subject from installed application code.
KDCube's default/reference production posture executes untrusted generated code
in ISO split. The reference descriptors set container_strategy: split
explicitly; operators should not rely on an omitted or unrecognized value to
establish that boundary. Other profiles exist for trusted development,
compatibility, or independently designed remote execution:
| Profile | Actual security meaning | Appropriate use |
|---|---|---|
| In-process/non-isolated | No security boundary | Trusted deterministic code only |
| Local subprocess | Process and crash containment; inherits the host process environment and network, so it is not a security sandbox | Development and trusted workloads |
| Docker combined | Legacy configurable profile. Supervisor and executor are separate processes but share one container trust zone and container-level mounts | Compatibility and controlled workloads, not the reference posture for untrusted generated code |
| Docker split | Separate supervisor and executor containers, narrow executor mounts, no platform secret store, and no executor network by default | Default/reference production profile for untrusted generated code |
| External/remote task | Boundary strength depends on remote task, IAM, network, snapshot, and return contracts | Large or independently scaled execution |
Combined Docker must not be described as if its shared-container mounts were "supervisor-only." They are in the same container trust zone. The logical supervisor/tool design still exists, but the topology does not provide the same secret, mount, and network separation as split mode.
The architecture rule is short: the split executor can compute, while external authority remains in trusted supervisor tools. Inputs are materialized through validated contracts and outputs are validated before they return to host storage.
And "no egress" must be scoped precisely. The split executor has no network by default. Trusted supervisor tools and application backends can still reach the services allowed by deployment networking and provider policy.
For the launch sequence, mount views, authenticated tool bridge, resource envelope, failure handling, and concrete configuration, read Isolated Code Execution: Computation Inside, Authority Through Tools. This article keeps only the profile distinctions needed to understand the larger KDCube architecture.
13Model-proposed references are requests, not authority
An agent can generate a plausible path, conversation id, artifact ref, or provider operation. Treat every such value as untrusted input.
model proposes:
conv:... / object id / external owner ref / path
|
v
trusted resolver binds:
tenant + project + current user + authority
|
+-------+-------+
| |
v v
allowed object no object /
materialized explicit denial
|
v
current execution workspace
For conversation history, changing the requested conversation can select another conversation owned by the same bound user. It cannot replace tenant, project, or user. External owner refs require a registered resolver and their own authorization contract.
This separation is more important than filtering strings. A perfectly well-formed identifier still grants no authority.
14Accounting and observability: useful evidence, bounded claims
KDCube carries accounting lineage such as tenant/project, user, app, conversation, turn, flow, provider, and model across supported calls. Integrated model, embedding, web-search, and participating custom-call paths can emit usage records and enforce configured economics.
The exact claim is:
instrumented platform call -> attributable usage/economics record
It is not:
every possible network call made by arbitrary trusted app code
-> automatically discovered and billed
A trusted application that directly calls a provider outside the accounting service can bypass platform attribution. An operator requiring complete cost capture must restrict that path and require instrumented provider services.
Likewise, logs, events, tool records, and accounting entries are operational evidence. Their completeness depends on the participating subsystem, and their retention and immutability depend on deployment configuration. KDCube does not claim a compliance certification or an automatically tamper-proof audit log.
15Threats, controls, and honest outcomes
| Scenario | Relevant boundary | Expected control or honest outcome |
|---|---|---|
| A model names another user's conversation | User/object boundary | Trusted lookup keeps the bound user predicate; the object is absent or denied |
| One deployment tries to address another tenant/project in a platform store | Deployment boundary | Schema/namespace/prefix derives from runtime binding, not model input |
| Custom app code uses raw SQL without an owner predicate | Trusted app boundary | Not automatically repaired; the application is defective and must be fixed |
| Custom app code uses raw Redis keys | Trusted app/cache boundary | No automatic isolation; use a namespaced cache and required user/object suffix |
| Generated code reads deployment descriptors or provider secrets | Generated-code boundary | Split executor does not receive those mounts or secret services |
| Generated code opens arbitrary Internet connections | Generated-code network boundary | Split executor has no network by default; use guarded supervisor tools |
| Generated code runs under combined Docker | Legacy shared-container profile | Process/tool supervision exists, but do not claim split-grade mount/secret separation |
| A delegated token calls an ungranted operation | Managed authority boundary | Guard checks server-side resource and operation grants and rejects |
| A connected provider token expires | Connected-account boundary | Tool returns credential-health/consent condition; user reconnects without token exposure to model |
| A public endpoint is crawled | Surface declaration | It is public by design; sensitive operations require an authenticated/managed guard |
| A trusted app makes an uninstrumented model call | Accounting boundary | Cost may not be captured; use the platform accounting/provider path |
| A platform operator or proc credential is compromised | Infrastructure trust root | Outside per-user/app logical isolation; rotate credentials and contain the deployment |
| Several workers build one EFS-backed app asset | Shared app storage concurrency | Use shared critical section and source signature; this is consistency, not authorization |
No single row proves the whole platform secure. It identifies the control that must exist for that scenario.
16Logical isolation and physical isolation are deployment choices
Most production systems combine both:
logical contracts
tenant/project schemas
Redis namespaces
object prefixes
app/user/object keys
request-bound authorization
physical controls
cloud account and IAM
VPC and security groups
dedicated databases or buckets where required
container/host isolation
secret manager policies
backup and retention boundaries
Use namespaced shared infrastructure when operational efficiency and the trusted-operator model make it appropriate. Use dedicated resources or deployments when:
- tenants are mutually hostile;
- regulatory policy requires physical or account-level separation;
- applications come from different untrusted operators;
- blast-radius reduction matters more than shared-service efficiency;
- one workload requires different IAM, egress, retention, or patch policy.
KDCube preserves the logical tenant/project contract in either topology. The operator selects the physical one.
Self-hosting controls topology; it does not imply zero egress
Self-hosting means the operator chooses where KDCube runs, where its stores live, and which providers and network paths are permitted. It does not mean data can never leave that infrastructure.
Configured model providers, embedding services, web search, mail, Slack, other connected accounts, and trusted custom application calls can receive the data needed for an allowed operation. The split executor's networkless default applies to the untrusted executor, not to trusted supervisor tools or application backends. Operators decide whether those trusted calls use public providers, private endpoints, egress gateways, allowlists, or no external provider at all.
ModSecurity with OWASP CRS can contribute to application-security controls by inspecting HTTP traffic and blocking classes of common attacks. Enabling it does not, by itself, establish PCI DSS compliance or produce a SOC 2 attestation.
17A production review needs six inputs
A repository scan that notices MCP or code execution but does not identify the deployment profile is incomplete. A useful review records:
Deployment topology Which tenant/project is bound? Which backing services are shared? What are the network, IAM, TLS, proxy, and secret-manager policies?
Trusted applications Which source refs are loaded? Are they reviewed and immutable? What process, filesystem, database, and network privileges does proc have?
User and authority configuration Which platform authority authenticates users? Which roles, identity edges, connected accounts, and delegated credentials exist?
Generated-code profile Is execution in-process, local subprocess, legacy combined Docker, production-reference split Docker, or an external task? What are the mounts, network, UID, capabilities, time, and storage limits?
Exposed surfaces Which UI, site, REST, MCP, event, and provider operations are public, platform-authenticated, or managed/delegated?
Data ownership contracts Which stores are platform-owned? Which custom app stores exist? How are tenant/project/app/user/object scope and deletion tested?
Without these inputs, "security audit passed" and "security audit failed" are both too coarse to be useful. A review should also record the source revision, deployment configuration, and scan time. Cached third-party assessments can describe an older repository or a different execution profile.
18Builder checklist: keep the boundary intact
Application trust
- Review application source and pin immutable refs.
- Treat backend apps as trusted deployment code, not generated-code sandboxes.
- Place mutually untrusted apps in separate deployments.
- Grant proc only the infrastructure privileges its installed apps need.
Identity and authorization
- Bind tenant, project, actor, user, authority, app, and lineage at ingress.
- Derive owner scope from runtime context, not model or client parameters.
- Declare every non-public REST/MCP/tool operation behind the correct guard.
- Re-evaluate grants at the concrete resource and operation boundary.
- Test revoked, expired, absent, and cross-resource credentials.
Storage
- Use tenant/project-aware platform stores.
- Use
NamespacedKVCache, not raw Redis keys, for isolated app state. - Use
bundle_storage_root()for app-local files. - Add user/object paths below an app root when data is not app-global.
- Use conversation hosting for user-visible turn artifacts.
- Keep custom table/vector/graph ownership explicit and query it from bound context.
Secrets and providers
- Keep production values out of tracked descriptors and browser config.
- Resolve deployment and user credentials only through trusted server-side services.
- Declare provider claims per tool and support consent/reconnect results.
- Never copy provider tokens into prompts, generated source, or executor files.
- Remember that trusted custom code is still responsible for not bypassing the secret lifecycle.
Generated code
- Keep ISO split as the configured default/reference profile for untrusted generated code.
- Treat combined Docker as a legacy configurable compatibility profile.
- Treat local subprocess execution as trusted development containment; it inherits the host environment and network.
- Keep executor mounts narrow and network disabled unless explicitly required.
- Expose external actions as narrow trusted tools.
- Validate inputs before materialization and outputs before hosting.
- Configure timeout, file-size, workspace-growth, and cancellation limits.
Evidence and economics
- Route paid calls through instrumented services when attribution is required.
- Test accounting context across tasks, subagents, and fenced runtimes.
- Define log/event/usage retention and access controls.
- Do not market operational telemetry as an immutable compliance audit.
19Verification matrix for a multi-user app
A production test plan should attempt the negative paths:
| Test | Expected result |
|---|---|
| User A requests User B's conversation id | No object or explicit denial |
| User A requests User B's hosted artifact ref | Resolution fails before materialization |
| Same app id runs in two tenant/project deployments using shared PostgreSQL | Each deployment addresses a separate schema |
| Same app id uses shared Redis | Keys/channels/streams retain tenant/project and app/subsystem namespace |
| Two users write under app filesystem storage | Their app-defined user subdirectories do not collide |
| A generated program probes descriptor/secret paths in split mode | Paths are absent from executor view |
| A generated program opens a network socket in split mode | Fails under default executor network policy |
| A generated program asks a mail tool without consent | Structured consent/reconnect result; no token appears in output |
Delegated credential has {A: read, B: write} and calls A.write |
Managed guard rejects |
| A credential is revoked after issuance | Next guarded call rejects from server-side state |
| A child runtime is killed before reduce | Failure remains explicit; missing side files are not treated as success |
| A custom provider call bypasses accounting | Test exposes missing record; app is routed through instrumented service |
Security tests should verify the effective deployed profile, not only source defaults.
20Precise claims and non-claims
Use these formulations:
| Imprecise phrase | Precise KDCube statement |
|---|---|
| "One runtime isolates mutually hostile tenants" | A platform can operate many tenant/project deployments; one running deployment is bound to one effective tenant/project and serves many users/apps. Shared stores preserve scope through platform contracts. |
| "All app code is sandboxed" | Operator-installed application code is trusted. Untrusted generated code executes in ISO split by default in the reference deployment; local and legacy combined profiles have weaker, documented boundaries. |
| "Docker isolates it" | Legacy combined and split Docker have different trust zones. Only split separates supervisor and executor containers and removes executor network by default. |
| "Credentials never leave the vault" | Platform-supported paths resolve credentials on the trusted side. The split executor does not receive them; local and legacy combined profiles do not provide the same isolation, and trusted custom code remains part of the trust base. |
| "Every call is accounted" | Integrated model, embedding, web-search, and participating custom-call paths emit configured usage/economics records. Direct or unintegrated custom calls can bypass them. |
| "KDCube has a complete audit trail" | Participating subsystems emit operational records; completeness, retention, immutability, and compliance controls are deployment responsibilities. |
| "No egress" | The split generated-code executor has no network by default. Trusted app and supervisor egress follows deployment network and tool policy. |
| "Self-hosted means data never leaves" | The operator controls topology and permitted egress. Configured providers, integrations, and trusted app calls may receive selected data for allowed operations. |
| "MCP gives access to KDCube" | An app may expose an MCP surface. Its declared guard and server-side grants decide access per resource and tool. |
The code can compute. External authority remains in trusted tools.
21The architecture, reduced to seven rules
That is the KDCube architecture. It does not depend on pretending every component is hostile or every component is safe. It names the trust decision, the owner, the crossing, and the enforcement mechanism.