---
title: "Vendo for SaaS: Tenant Isolation and Approval Boundaries"
canonical: https://wavect.io/blog/vendo-saas-tenant-isolation/
language: en
description: "Plan a Vendo SaaS integration with two tenants, role changes, approvals and restart tests. Learn which production responsibilities remain yours."
image: "https://wavect.io/img/blog/headers/header_vendo-saas-tenant-isolation.png"
---

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

4 min read · 8 October 2026 Last reviewed October 8, 2026

[**Next**](/blog/enterprise-mcp-authorization-architecture/)

# Vendo for SaaS: Tenant Isolation and Approval Boundaries

TL;DR

Vendo can add user-built features to a SaaS product, but the host must still enforce identity, tenant access and action permissions. Start with one read-only feature, then prove approval and restart behavior with two tenants before exposing writes.

**Evidence:** Documentation reviewed on 8 October 2026. This is a researched implementation guide. The pilot below is proposed; we have not run these vendor evaluations or measured their performance.

## What must a SaaS team still own after adding Vendo?

Your backend remains responsible for deciding which records the signed-in user can read or change. Generated screens, a sandbox and an approval card do not replace authorization in your API. Start with a customer-specific dashboard whose tools already enforce tenant scope. Expand to actions only after that boundary passes independent checks.

The relevant product is Vendo at `vendo.run`, the customization layer maintained in [the official runvendo repository](https://github.com/runvendo/vendo). It adds agent-driven features and micro-apps to an existing product. Other companies named Vendo are unrelated to this guide.

## How should identity and tenant access work?

The [Vendo authentication documentation](https://docs.vendo.run/howto/auth) resolves the host's existing identity and recommends an immutable subject. Its no-auth example assigns every visitor the same demo user. That example is unsuitable for a multi-tenant production integration.

Use one trusted server-side session resolver for Vendo and host routes. Resolve organization membership from the backend, then check it in every tool that reads or writes business data. Never treat an organization identifier supplied by the model as proof of access. Users who belong to two organizations still need an explicit active-organization boundary.

## What should a two-tenant pilot prove?

Create synthetic organizations A and B. Give each an administrator and a read-only member. Both have an invoice with the same local number but different internal identifiers. Propose a generated “overdue invoices” view and a reminder action. The following cases are acceptance targets, not observed Vendo results.

| Attempt | Required outcome | Independent check |
| --- | --- | --- |
| A requests B's invoice ID | Denied without leaking invoice fields | Host API response and access log |
| A changes active organization | Only the newly authorized context is visible | Re-query records and reopen the saved app |
| Read-only member sends a reminder | Blocked unless the role explicitly permits it | Delivery ledger stays unchanged |
| Administrator loses the role after approval | Permission is checked again before execution | No external send after revocation |
| Two workers resume the same approved action | One logical side effect | Durable operation key and delivery ledger |
| Process restarts | Authorized state survives; expired grants do not revive | Store contents and replayed action |

Run the read tests directly against host tools as well as through generated UI. A UI that hides a button is not an access-control test.

## Does Vendo ask before every write?

No. The [approval guide](https://docs.vendo.run/howto/approvals) documents a default posture where reads and writes run, while destructive and ungraded calls ask. Define explicit policies for sensitive writes such as sending messages or changing billing data. A business-critical write can require approval even when its technical risk label is not destructive.

The same guide distinguishes in-app resumption from the MCP path: outside agents must call again on the same MCP session after approval. Test both entry points if your customers use both. Bind approval to the intended action and recheck permissions at execution; approval is not an authorization bypass.

## What must survive a restart?

The [persistence documentation](https://docs.vendo.run/production/persistence) describes Vendo Cloud storage for threads, apps, grants, approvals, audit and runs. Persistence is a capability, not proof that a host-side write is exactly once. Keep a durable business-operation ledger with tenant, actor, approved arguments, operation key and reconciled outcome.

On uncertain external outcomes, inspect the destination before retrying. If a reminder was delivered but the process died before saving the response, starting a new operation can send it twice. Test a crash between the external side effect and the local acknowledgement.

## Is passing vendo doctor enough for production?

No. The [production checklist](https://docs.vendo.run/production/deploying) explicitly says doctor reads source and environment without calling the deployed app. Use it to detect wiring problems, then test the live staging deployment for identity, streaming, verified webhooks, approvals and restart behavior. Cloud fills some infrastructure slots; the host still wires several security and request boundaries.

## When is Vendo a good fit?

Pilot it when customers need different views or bounded workflows over an API you can authorize reliably. A bespoke copilot may be simpler when there is one fixed task and no need for user-built apps. Assign maintenance ownership for tool schemas, saved features and incident recovery before expanding. Bring one feature and its permission matrix to [scope a SaaS agent integration](/contact/).

[Download the proposed pilot protocol (JSON). It contains acceptance cases and empty result fields, not measured vendor results.](/downloads/vendo-saas-tenant-isolation-pilot.json)

## Related implementation guidance

[Enterprise MCP Authorization Architecture: A Multi-Tenant Reference Design](/blog/enterprise-mcp-authorization-architecture/). [AgentMail for SaaS: Tenant Isolation and Duplicate-Send Recovery](/blog/agentmail-saas-duplicate-sends-recovery/).

## Sources checked

- [runvendo/vendo](https://github.com/runvendo/vendo)
- [Vendo: Auth](https://docs.vendo.run/howto/auth)
- [Vendo: Approvals](https://docs.vendo.run/howto/approvals)
- [Vendo: Persistence](https://docs.vendo.run/production/persistence)
- [Vendo: Deploying](https://docs.vendo.run/production/deploying)

**Independence and trademarks:** Wavect publishes this page and is itself a provider, so we have a commercial interest in it. We are not affiliated with, endorsed by or partnered with the other companies named here, and all third-party company names, brands and trademarks are the property of their respective owners. Statements about other providers are taken from publicly available sources, primarily their own published pages, as of the review date shown on this page, and may have changed since. Please verify them directly before you decide. This page was written to the best of our knowledge and with the intent to remain objective. If you believe anything here is inaccurate or unfair, write to us and we will correct it: [office@wavect.io](mailto:office@wavect.io)

Architecture and platforms

## Continue through this cluster

Framework, platform and system-design choices that affect delivery over the long term.

[Start with the cornerstone**Smart City Architecture Best Practices: MQTT, LoRaWAN, Kubernetes and Terraform**](/blog/smart-city-architecture-best-practices-2026/)

- [GitButler for Parallel AI Agents: Multiple Branches, One Build](/blog/gitbutler-parallel-ai-agents-one-workspace/)
- [AgentMail for SaaS: Tenant Isolation and Duplicate-Send Recovery](/blog/agentmail-saas-duplicate-sends-recovery/)
- [AI Coding and the Software Moat: Who Runs What You Build?](/blog/ai-coding-software-moat-operations/)
- [Shopify B2B Order Approvals: Native Features, Apps, or a Custom Buyer Portal?](/blog/shopify-b2b-order-approval-workflow/)
- [Shopify–ERP Returns and Refunds: When the Standard Connector Is Not Enough](/blog/shopify-erp-returns-refunds-integration/)

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

4 min read · 8 October 2026 Last reviewed October 8, 2026

[**Next**](/blog/enterprise-mcp-authorization-architecture/)

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/#organization",
      "@type": [
        "Organization",
        "ProfessionalService",
        "LocalBusiness"
      ],
      "employee": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "founder": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "legalRepresentative": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "name": "Wavect GmbH",
      "subjectOf": {
        "@id": "https://wavect.io/verified-claims.json#dataset",
        "@type": "Dataset",
        "creator": {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        "description": "A machine-readable registry of quantitative and qualitative claims published by Wavect, with review dates, localized page appearances and public third-party citations where available.",
        "inLanguage": "en",
        "isAccessibleForFree": true,
        "license": "https://creativecommons.org/licenses/by/4.0/",
        "name": "Wavect verified publication claims",
        "url": "https://wavect.io/verified-claims.json"
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/team/kevin-riedl/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Kevin Riedl",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796365",
        "https://www.linkedin.com/in/wsdt",
        "https://github.com/wsdt"
      ],
      "url": "https://wavect.io/team/kevin-riedl/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/team/christof-jori/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Christof Jori",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796367",
        "https://www.linkedin.com/in/jocr77/",
        "https://github.com/jo-chris"
      ],
      "url": "https://wavect.io/team/christof-jori/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/#website",
      "@type": "WebSite",
      "inLanguage": [
        "en",
        "de",
        "es",
        "zh"
      ],
      "name": "Wavect",
      "potentialAction": {
        "@type": "SearchAction",
        "query-input": "required name=search_term_string",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://wavect.io/search/?q={search_term_string}"
        }
      },
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/blog/vendo-saas-tenant-isolation/#webpage",
      "@type": "WebPage",
      "dateModified": "2026-10-08",
      "inLanguage": "en",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-10-08",
      "url": "https://wavect.io/blog/vendo-saas-tenant-isolation/"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "abstract": "Vendo can add user-built features to a SaaS product, but the host must still enforce identity, tenant access and action permissions. Start with one read-only feature, then prove approval and restart behavior with two tenants before exposing writes.",
  "articleBody": " Blog overview/Delivery and QA/Architecture and platforms Vendo for SaaS: Tenant Isolation and Approval Boundaries TL;DR Vendo can add user-built features to a SaaS product, but the host must still enforce identity, tenant access and action permissions. Start with one read-only feature, then prove approval and restart behavior with two tenants before exposing writes. Evidence: Documentation reviewed on 8 October 2026. This is a researched implementation guide. The pilot below is proposed; we have not run these vendor evaluations or measured their performance. What must a SaaS team still own after adding Vendo? Your backend remains responsible for deciding which records the signed-in user can read or change. Generated screens, a sandbox and an approval card do not replace authorization in your API. Start with a customer-specific dashboard whose tools already enforce tenant scope. Expand to actions only after that boundary passes independent checks. The relevant product is Vendo at vendo.run, the customization layer maintained in the official runvendo repository. It adds agent-driven features and micro-apps to an existing product. Other companies named Vendo are unrelated to this guide. How should identity and tenant access work? The Vendo authentication documentation resolves the host's existing identity and recommends an immutable subject. Its no-auth example assigns every visitor the same demo user. That example is unsuitable for a multi-tenant production integration. Use one trusted server-side session resolver for Vendo and host routes. Resolve organization membership from the backend, then check it in every tool that reads or writes business data. Never treat an organization identifier supplied by the model as proof of access. Users who belong to two organizations still need an explicit active-organization boundary. What should a two-tenant pilot prove? Create synthetic organizations A and B. Give each an administrator and a read-only member. Both have an invoice with the same local number but different internal identifiers. Propose a generated “overdue invoices” view and a reminder action. The following cases are acceptance targets, not observed Vendo results. AttemptRequired outcomeIndependent check A requests B's invoice IDDenied without leaking invoice fieldsHost API response and access logA changes active organizationOnly the newly authorized context is visibleRe-query records and reopen the saved appRead-only member sends a reminderBlocked unless the role explicitly permits itDelivery ledger stays unchangedAdministrator loses the role after approvalPermission is checked again before executionNo external send after revocationTwo workers resume the same approved actionOne logical side effectDurable operation key and delivery ledgerProcess restartsAuthorized state survives; expired grants do not reviveStore contents and replayed action Run the read tests directly against host tools as well as through generated UI. A UI that hides a button is not an access-control test. Does Vendo ask before every write? No. The approval guide documents a default posture where reads and writes run, while destructive and ungraded calls ask. Define explicit policies for sensitive writes such as sending messages or changing billing data. A business-critical write can require approval even when its technical risk label is not destructive. The same guide distinguishes in-app resumption from the MCP path: outside agents must call again on the same MCP session after approval. Test both entry points if your customers use both. Bind approval to the intended action and recheck permissions at execution; approval is not an authorization bypass. What must survive a restart? The persistence documentation describes Vendo Cloud storage for threads, apps, grants, approvals, audit and runs. Persistence is a capability, not proof that a host-side write is exactly once. Keep a durable business-operation ledger with tenant, actor, approved arguments, operation key and reconciled outcome. On uncertain external outcomes, inspect the destination before retrying. If a reminder was delivered but the process died before saving the response, starting a new operation can send it twice. Test a crash between the external side effect and the local acknowledgement. Is passing vendo doctor enough for production? No. The production checklist explicitly says doctor reads source and environment without calling the deployed app. Use it to detect wiring problems, then test the live staging deployment for identity, streaming, verified webhooks, approvals and restart behavior. Cloud fills some infrastructure slots; the host still wires several security and request boundaries. When is Vendo a good fit? Pilot it when customers need different views or bounded workflows over an API you can authorize reliably. A bespoke copilot may be simpler when there is one fixed task and no need for user-built apps. Assign maintenance ownership for tool schemas, saved",
  "articleSection": "Engineering",
  "author": {
    "@id": "https://wavect.io/team/kevin-riedl/#person",
    "@type": "Person",
    "name": "Kevin Riedl",
    "sameAs": [
      "https://www.wikidata.org/wiki/Q139796365",
      "https://www.linkedin.com/in/wsdt",
      "https://github.com/wsdt"
    ],
    "url": "https://wavect.io/team/kevin-riedl/"
  },
  "citation": [
    {
      "@type": "WebPage",
      "name": "the official runvendo repository",
      "url": "https://github.com/runvendo/vendo"
    },
    {
      "@type": "WebPage",
      "name": "Vendo authentication documentation",
      "url": "https://docs.vendo.run/howto/auth"
    },
    {
      "@type": "WebPage",
      "name": "approval guide",
      "url": "https://docs.vendo.run/howto/approvals"
    },
    {
      "@type": "WebPage",
      "name": "persistence documentation",
      "url": "https://docs.vendo.run/production/persistence"
    },
    {
      "@type": "WebPage",
      "name": "production checklist",
      "url": "https://docs.vendo.run/production/deploying"
    }
  ],
  "dateModified": "2026-10-08",
  "datePublished": "2026-10-08",
  "description": "Vendo can add user-built features to a SaaS product, but the host must still enforce identity, tenant access and action permissions. Start with one read-only feature, then prove approval and restart behavior with two tenants before exposing writes.",
  "headline": "Vendo for SaaS: Tenant Isolation and Approval Boundaries",
  "image": "https://wavect.io/img/blog/headers/header_vendo-saas-tenant-isolation.svg",
  "inLanguage": "en",
  "keywords": "Engineering, AI agents",
  "mainEntityOfPage": {
    "@id": "https://wavect.io/blog/vendo-saas-tenant-isolation/",
    "@type": "WebPage"
  },
  "publisher": {
    "@id": "https://wavect.io/#organization",
    "@type": [
      "Organization",
      "ProfessionalService",
      "LocalBusiness"
    ]
  },
  "url": "https://wavect.io/blog/vendo-saas-tenant-isolation/",
  "wordCount": 1151
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "item": "https://wavect.io/",
      "name": "Home",
      "position": 1
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/overview/",
      "name": "Blog overview",
      "position": 2
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/topics/delivery-qa/",
      "name": "Delivery and QA",
      "position": 3
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/clusters/architecture-platforms/",
      "name": "Architecture and platforms",
      "position": 4
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/vendo-saas-tenant-isolation/",
      "name": "Vendo for SaaS: Tenant Isolation and Approval Boundaries",
      "position": 5
    }
  ]
}
```
