Skip to content

docs(meshery): add security self-assessment for incubation - #2264

Open
angellk wants to merge 1 commit into
cncf:mainfrom
angellk:meshery-ssa
Open

docs(meshery): add security self-assessment for incubation#2264
angellk wants to merge 1 commit into
cncf:mainfrom
angellk:meshery-ssa

Conversation

@angellk

@angellk angellk commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Security self-assessment for Meshery, authored by Meshery maintainers following the
TAG Security self-assessment template.

Required for incubation due diligence (#1386).

  • Original: Google Doc
  • Covers: actors, actions, goals, non-goals, security functions, development pipeline,
    vulnerability history (5 CVEs, all SQL injection, all fixed), and compliance posture
  • Follows the TAG Security template structure

Checklist

  • DCO signed
  • Follows TAG Security self-assessment template

@angellk
angellk requested a review from a team as a code owner August 5, 2026 01:57
@evankanderson evankanderson added the needs-triage Indicates an issue or PR that has not been triaged yet (has a 'triage/foo' label applied) label Aug 5, 2026
@mnm678 mnm678 added the tag/security-and-compliance TAG Security and Compliance label Aug 5, 2026
@angellk

angellk commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@evankanderson @mnm678 please let me know if you have any concerns! I plan to wrap up this due diligence later this week. 🙏

@evankanderson

Copy link
Copy Markdown
Contributor

@JustinCappos @realshuting are doing most of the security-assessments reviews; I'll also do a quick pass.

- Meshery is not a secrets manager / vault. It does not encrypt credentials at rest at the application layer; the datastore must be protected via disk/file/cloud controls, and a dedicated secrets manager should hold long-lived secrets.
- Meshery does not replace Kubernetes' own controls. It relies on the cluster's RBAC, NetworkPolicy, and Pod security mechanisms; Meshery ships no NetworkPolicies and applies no container hardening (securityContext) by default, leaving those to the operator.
- Meshery does not constrain resource consumption of authorized callers. An authorized user can issue operations (large discoveries, benchmarks, deployments) that consume cluster or server resources.
- The security of out-of-tree and community extensions is out of scope for the core project. Meshery is deliberately extensible via adapters, providers, and models/integrations, and community extensions are maintained in a separate meshery-extensions organization. Enabling a third-party adapter, remote provider, or integration extends a deployment's trust boundary to that extension; vetting and securing it is the responsibility of its author/operator. This assessment covers the core meshery/meshery platform and its supporting repositories, not arbitrary third-party extensions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that users expect? It seems like one might expect at least some isolation from community plugins. How do you convey this limitation to users? How do they validate the plugins? How do you handle malicious / insecure plugins? What is the takedown process?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The degree to which users might have an expectation of the platform in this regard varies based on the type of extension point. For example, Meshery ships with a large collection of models. Each model contains a collection of entities that, once validated, are registered for use. Generally speaking, the more models registered, the more cognizant Meshery becomes of the variety of systems it can manage and the more expressive Meshery is as its capabilities are extended with each model registered. Models are imported and exported as OCI images, and just like container images, models vary in depth and breadth in terms of what is packaged inside. However, all must adhere to a minimum specification in order to be registered in any given Meshery Server. Models undergo validation against Meshery's published schemas. As a platform, Meshery guarantees that models contain valid entities (e.g. components, relationships, templates, and so on) that are usable and Meshery tracks details of the registrant. Programmatically, Meshery does not verify the usefulness of a model or whether its entities are intended for nefarious purposes or not. Users can bring their own models, disable models packaged in the published Meshery releases, or share and contribute to public or private Meshery catalogs. Meshery catalogs contain models and designs for reuse and distribution, and each carry a designation as to the degree by which catalog content has been curated.You can see an example of the curation-level designations ("official", "verified", "community") in one of Meshery's design catalogs.

Image Image


The following are explicitly out of scope for the Meshery open-source project. Several correct earlier informal descriptions of Meshery's posture.

- Meshery does not provide mutual TLS or transport encryption between its own internal components by default. The server-adapter gRPC channel is plaintext today, and the server-broker (NATS) channel ships without auth or TLS by default. Securing these channels is a deployment responsibility and an active hardening roadmap item; it is not an out-of-the-box "zero-trust" guarantee.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something users expect? Why don't you provide / encourage mTLS?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We encourage users to deploy Meshery on TLS infrastructure. Originally, the Meshery server-adapter gRPC channel was built when adapters were assumed to be deployed on a service mesh that provided mTLS already.

Meshery Broker (NATS) token authentication is on by default. A new secret is minted (a Kubernetes Secret named, meshery-nats-auth) with a generated token before the NATS pod starts and keeping it stable across reconciles and cross-namespace.

We've found that directly handling the inclusion of TLS whether by 1) requiring user-supplied certificates 2) a Meshery Operator-generated self-signed CA or 3) inclusion of cert-manager as a dependency caused installation friction for users. Consequently, to-date, we have left the choice how to harden as the user's prerogative. The security hardening section of the production deployment guide includes this concern.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue has been filed - meshery/meshery#21444 - as something for the maintainers to consider. I don't know that there's much that we want to do here other than ensure production deployment documentation is highlights the need to securing Meshery's network communication in the same many environments do with any other workload. We can include reference configuration, and perhaps, that's what the issue should convert to: a docs update.


## Non-goals

The following are explicitly out of scope for the Meshery open-source project. Several correct earlier informal descriptions of Meshery's posture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you show how in your docs you help to guide users to understand these things?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and the fair criticism is that this document does not link to any of it, so a reader has no way to find it from here. We didn't know that others would be review the self-assessment, per say. The material that exists:

- **Software supply-chain integrity controls.** Mandatory DCO sign-off, required peer review with branch protection, and a CI gate (lint/static analysis, CodeQL, container and dependency scanning, OpenSSF Scorecard, OSPS Baseline) that must pass before merge or release. See [Development pipeline](#development-pipeline).
- **Centralized input sanitization for query ordering.** A shared SanitizeOrderInput routine was introduced to close the class of SQL-injection issues found in order/sort query parameters (see [Known issues over time](#known-issues-over-time)).

**Security relevant** - configurable components that materially affect the security posture of a deployment. These should also be included in threat modeling.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you tell what components would materially affect the security posture?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JustinCappos, I'm scratching my head on this one. I might not be thinking of this in the right way. When you look over the bulleted list below, the notion that changes to these components will affect Meshery's security posture is self-evident, I think, but I could be mistaken (or looking at this question from a different vantage point).


### Incident response

- **Triage & containment.** On identifying an incident, immediate containment measures are taken (e.g., disabling affected components or applying temporary mitigations).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you do this for out-of-tree / community extensions? Do you have the ability to disable them after the users have installed them? Do you know who installed them?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know who installed them? It depends on the provider.

  • Local provider: no. Meshery does not phone home and we deliberately do not collect an install inventory, so there is no population to enumerate and no targeted notification path. Our reach for an extension incident is broadcast only: #announcements on Slack, the users and developers mailing lists, the blog, and release notes.
  • Remote provider: yes, potentially. A remote provider is at liberty to track which principals enabled which extensions, and many will. Whether it does is provider-specific, so the reachable population in an incident is a property of the deployment's provider rather than of Meshery itself.

Can we disable them after install? Yes, users of either a local or a remote provider can enable and disable extensions. This is an ordinary, supported user action rather than an incident-only lever, and it is exposed in the UI across the different extension types. So the containment story does not depend on the core project reaching into a deployment it does not operate: the operator of that deployment can turn an extension off themselves.

Note that, a remote provider can also drop an extension from its capabilities payload, which stops it loading on the next session - a kill-switch owned by the provider operator. And a server plugin, where a package carries one, is a native Go plugin loaded in-process; Go plugins cannot be unloaded, so disabling evicts it at the next restart of Meshery Server rather than instantaneously. Worth saying, because "disable" reads as immediate and for that one case it is not.

Meshery operators (users) can also pin away from a bad version with SKIP_DOWNLOAD_EXTENSIONS=true plus a restored known-good package, or freeze capabilities with PROVIDER_CAPABILITIES_FILEPATH. These are documented at Removing an extension, and responding to a bad one.

What we do control.

  1. For repositories in the meshery-extensions GitHub organization, maintainers can yank a release, archive the repository, and publish an advisory.
  2. Because the Local Provider installer refuses any package URL outside https://github.com/meshery-extensions/, that organization is the practical chokepoint for that install path - pulling a release there stops new installs, though it does nothing for existing ones.
  3. For extensions distributed elsewhere we have advisory reach only, and the published guidance states this.

@sherine-k sherine-k Aug 18, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When loading extensions, is there any guardrails implemented or documented such as digest validation, signature verification, vulnerability scanning? Curation-level designations ("official", "verified", "community") is definitely a great first indicator for users. AFAIU, extensions are loaded as go plugins at runtime.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sherine-k, while there there aren't provenance guarantees currently, this is an item that we can place on the roadmap. There's no real-time vulnerability scanning (a non-goal), we can mandate vulnerability scanning in the CI (akin to that of Meshery core) of repositories in the https://github.com/meshery-extensions organization.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that there are a number of different types of extension points (documented here). There are safeguards (some sandboxing) for dynamically loaded UI (React-based) and Server (Golang-based) plugins. Here is a screenshot of a plugin that failed to load (I broke it for demonstration purposes).

Screenshot 2026-08-18 at 3 12 11 PM

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the topic of types of extension points, the diagram on the documentation page I linked above is worth pointing out -

@JustinCappos JustinCappos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the self assessment. I have a few questions around the way in which users can understand and assess the security of different configurations, especially around community extensions.

Could you explain in more detail? Ideally, please do so directly in the document so others see those explanations later.

@evankanderson evankanderson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments, but as this is one of my first times doing this, I'd wait for @JustinCappos or @realshuting if possible.


Meshery is a CNCF Sandbox project, accepted on June 22, 2021 (the public "CNCF adopts Meshery" announcement followed in October 2021). It originated as a service mesh management plane and has since broadened into a general cloud native management plane that facilitates engineering teams with the collaboration, learning, planning, and operational management of their infrastructure across Kubernetes clusters and a broad range of cloud native technologies.

Much of that breadth is delivered through Meshery's extension model. Beyond its in-tree adapters and core components, functionality is extended through adapters (per-technology controllers), providers (pluggable identity, persistence, and infrastructure/API back-ends), and models/integrations (the registry of cloud native constructs Meshery can design and operate). Community extensions are developed and maintained in a dedicated meshery-extensions organization, separate from the core meshery organization, so that contributors can build and share providers and integrations without requiring endorsement from the core maintainers. CNCF has described Meshery as "a highly extensible, self-service management platform" able to manage "any infrastructure via Providers, Models, Adapters, and its other extension points" ([Scaling Organizational Structure with Meshery's Expanding Ecosystem](https://www.cncf.io/blog/2026/03/04/scaling-organizational-structure-with-mesherys-expanding-ecosystem/), CNCF, 2026). For this assessment, that distinction matters: the security boundary separates the core platform (covered here) from out-of-tree extensions, whose security posture is the responsibility of their respective authors/maintainers (see [Non-goals](#non-goals)).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it fair to say that for a particular meshery installation, both the core and the plugins are considered "trusted"?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is exactly the right framing. A section in Meshery Docs has been added to explicitly highlight this concept for users - https://docs.meshery.io/installation/production/security-hardening/#trusting-an-extension


The Meshery datastore is intentionally treated as a cache of authoritative cluster state rather than a system of record, which shapes several of the security trade-offs described below.

## Actors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required, but I've found that a diagram (mermaid or .png) can be helpful for understanding the actors in the system.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Meshery Architecture deck is an excellent resource in this regard.


The following components ("actors") interact to deliver Meshery's functionality (see [logical architecture](https://docs.meshery.io/concepts/architecture) for diagrams). Isolation between them rests primarily on container/process boundaries and Kubernetes RBAC; see [Non-goals](#non-goals) and [Security functions and features](#security-functions-and-features) for the boundaries Meshery does and does not enforce by default.

| Actor | Function | Security / isolation measures |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Kubernetes cluster another actor in the system? What about the cluster administrator or other users? (There can be actors in the system beyond the software components that you ship.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evankanderson, @Santoshkumarpuppala, please note that there are two additional actor tables proposed in @angellk's fork - angellk#2

  • Table A - Human and external actors
  • Table B - Assumed adversaries

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I commented on the PR, but this looks good.


**1. User authentication & session establishment.** When configured with a remote provider, an unauthenticated request is redirected to the provider's browser login flow. On callback, the server receives a token and sets it as an HttpOnly cookie. On each subsequent request, AuthMiddleware calls provider.GetSession(), which (a) verifies the JWT's RS256 signature against the provider's published JWKS, (b) checks expiry, (c) performs server-side introspection against the provider to detect revocation, and (d) refreshes the token when needed. With the local provider this step is a no-op: the session is always treated as a single anonymous user and no credential is checked.

**2. Authorization for management functions.** Fine-grained permissions are modeled as capability "keys" grouped into keychains and mapped to roles (User, Team Admin, Workspace Admin, Org Admin, Provider Admin, etc.) in server/permissions/keys.csv. These are seeded into the datastore at startup. Multi-user role enforcement is performed in conjunction with a remote provider; the local provider is single-user and does not enforce role separation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The multi-user permissioning component seems important. Which actor reads the role definitions (and assignments?) from this file? Is this file re-read live, or only on server restart?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question.

Who reads it, and when: Meshery Server, once at startup and again on an explicit database reset (perform if/when a user choose to perform a database reset). There is no watcher and no live re-read; a change requires a restart or a DB reset.

What it actually contains. Capability definitions (key id, category, function, and which roles each key belongs to) seeded into the keys table. It holds no principal identities, so it is not a role-assignment store. The keys.csv file is a build input rather than an operator-tunable policy file. These keys serve as Meshery's permission gates into which any provider can hook-in.

Who consumes the result. Not the server. The seeded keys are served to Meshery UI, which compiles them into UI components and then gates rendering based on the presence of the required key(s) in the user's session. With the local provider, the seeded keys become the single anonymous user's capability set. With a remote provider, the seeded keys form the backbone against which a user's keys are matched. A user's key set is fetched per organization from the provider, then matched against the seeded keys in Meshery Server.


**2. Authorization for management functions.** Fine-grained permissions are modeled as capability "keys" grouped into keychains and mapped to roles (User, Team Admin, Workspace Admin, Org Admin, Provider Admin, etc.) in server/permissions/keys.csv. These are seeded into the datastore at startup. Multi-user role enforcement is performed in conjunction with a remote provider; the local provider is single-user and does not enforce role separation.

**3. Connecting a Kubernetes cluster & discovery.** A user registers a cluster by supplying a kubeconfig (stored as a Credential/K8sContext). Meshery deploys the Meshery Operator, which provisions MeshSync and the Broker. MeshSync watches the resource types permitted by its watch-list and publishes ADDED/MODIFIED/DELETED events to the NATS subject meshery-server.meshsync.store; the server consumes these and persists them as KubernetesResource records. Sensitive inputs here include cluster credentials and any discovered Secrets.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kubeconfigs can contain credentials (secrets). Is there a mechanism to ensure that these credentials are encrypted at rest?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, not at the application layer. This is stated in Non-goals section, but you are right that a note here, at the point where the credential is collected, would be helpful.

  • Local provider: the context and credential are written to the SQLite datastore under the user-data folder (~/.meshery) unencrypted. Protection is filesystem permissions only. mesheryctl's session token is likewise plaintext at ~/.meshery/auth.json.
  • Remote provider: the credential is forwarded to the provider with the caller's bearer token (SaveUserCredential) and is subject to that provider's at-rest controls, not Meshery's. The assessment should not claim credit for those.

One server-side security control worth highlighting: credential ownership is bound to the authenticated user after unmarshalling the request body, specifically so a client-supplied userId cannot redirect a credential onto another account.

Current guidance is under Secrets and kubeconfig handling - mount kubeconfig from a Kubernetes Secret, prefer the in-cluster ServiceAccount over a long-lived file, scope each context to least privilege, prefer short-lived credentials. Optional at-rest encryption for stored credentials is already on the roadmap list here. 👍

Related edit prompted by this: the Registry/Database actor row will state that the SQLite file may contain cluster-admin-equivalent kubeconfigs and MeshSync-discovered Secrets, so the file-permission dependency is weighed correctly. (@Santoshkumarpuppala raised the same point.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, it's great to just drop links like the one in the comment into the self assessment -- it does not need to be stand-alone.


**3. Connecting a Kubernetes cluster & discovery.** A user registers a cluster by supplying a kubeconfig (stored as a Credential/K8sContext). Meshery deploys the Meshery Operator, which provisions MeshSync and the Broker. MeshSync watches the resource types permitted by its watch-list and publishes ADDED/MODIFIED/DELETED events to the NATS subject meshery-server.meshsync.store; the server consumes these and persists them as KubernetesResource records. Sensitive inputs here include cluster credentials and any discovered Secrets.

**4. Designing and deploying infrastructure.** A user composes a Meshery Design from registry components and requests deployment. The server validates the design against model/relationship policies (Rego/OPA evaluation) and then applies the resulting manifests to the target cluster using its Kubernetes client. Because the server holds broad cluster RBAC, it can create/update/delete arbitrary resources on the user's behalf.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Kubernetes client separate from the meshery adapters described above? I'm assuming "the server" is the "meshery server" in actors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, "The server" here refers to Meshery Server, the actor in the table. Yes, the Kubernetes client is in-process inside Meshery Server (MeshKit's Kubernetes client), and it is a separate path from adapters.

Whether a given design deployment operation travels the in-process path or the adapter path or both is a property of the components that comprise the design, and the registrant of those components (the system that registered the model(s) that contain the component used in the design).

How the deployment engine routes. Every entity in the registry records the registrant that registered it - an adapter, or a non-adapter source such as GitHub or ArtifactHub. Designs may contain components drawn from models registered by different registrants, and those components must be fulfilled by different registrants. Meshery's deployment engine executes a design deployment request in stages. The "provision" stage resolves the registrant per component (not once per design). Each resolved registrant is a connection record.

  1. Components with whose registrant (a connection has no hostname:port-number, follow the in-process deployment path. Meshery Server applies that component to the respective Kubernetes cluster (based on user's selected environment) using its own Kubernetes client and RBAC.
  2. Components with whose registrant (a connection does have a hostname:port-number associated follow the adapter deployment path. Meshery Server opens a gRPC client to host:port, invoking the Provision operation on that adapter, which, in turn, acts on the cluster with its own credentials. By default, for in-cluster deployments of Meshery, this is the shared meshery-server ServiceAccount). For out-of-cluster deployments of Meshery, Meshery Server sends along the respective Kubernetes context in the ProvisionRequest.

So a single deployment operation can fan out across as many fulfillment paths as the design has distinct registrants, and both routes can be exercised by one design.

**Critical** - design elements that make the product itself secure. These are recommended primary inputs to threat modeling and should be tracked as high-impact items for changes.

- **Provider authentication gate.** All API access flows through AuthMiddleware > provider.GetSession(). For remote providers this performs RS256 JWT signature verification against the provider's JWKS, expiry validation, server-side introspection (to honor revocation), and token refresh. This is the central authentication control for multi-user deployments.
- **Capability/role-based authorization model.** A fine-grained permission matrix (server/permissions/keys.csv) maps capabilities to roles and is enforced together with a remote provider, constraining which management actions a principal may perform.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the role assignment performed by the remote provider (e.g. by a JWT claim)? So far, it hasn't been clear how roles map to principals authenticated by the provider.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evankanderson, yes, role assignment is entirely the provider's prerogative. JWT claims are not used for this mechanism. The chain, precisely:

  • The JWT is used for authentication only - RS256 signature verification against the provider's JWKS, expiry, server-side introspection for revocation, refresh. It carries no roles and no keys.
  • Roles and assignments live with the provider, not in Meshery's datastore. With JWT access token in-hand, Meshery Server asks the provider for the principal's effective key set, scoped to their currently selected organization.
  • Meshery UI compiles the returned keys into and gates rendering of components on the presence of the keys in the principle's session.

So: the provider authenticates the principal, resolves their role within the organization, and returns the resulting keys. Meshery Server defines the points of control where permission keys (server/permissions/keys.csv), which the provider must align and hook into. The provider assigns permissions, while Meshery Server proxies and enforces.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, Meshery UI's use of permission keys is purely for UX, not for actual enforcement. Here's an example of a user missing the required key for performing an action (connecting to a Kubernetes cluster).

Untitled.mov

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @yi-nuo426 for the links, and apologies for the slow pass. I read the Authorization reference before writing this. The clip is useful too — the card that comes up reads "Authorization required / missing required key," names the key (Add cluster) and its keychain, and points the user at their admin. That is a good affordance, and it does exactly what you describe: it explains why the control is disabled, rather than showing a request being refused.

That reference establishes the provisioning path and the UI gating clearly: spreadsheet to @meshery/schemas to keys.csv, SeedKeys populating the DB at startup, the provider returning the key set per org, the UI caching it in sessionStorage, and CASL's CAN() gating components. Both worked examples gate a Button, and the page's own phrasing throughout is "evaluates permissions at runtime to render the UI."

What I can't find, in that page or in the self-assessment, is the server-side half. The only Meshery Server code path the reference names is SeedKeys in server/models/keys_helper.go, which seeds the key catalog rather than checking an inbound request. Read together with your note that the UI's use of the keys is purely UX and not enforcement, a reader is left without the place where a request from a principal lacking the capability is refused.

To be clear about what I am and am not saying: the documentation being silent on this is not evidence that server-side enforcement is missing. It may well exist and simply not be written down. But the self-assessment lists the capability/role model as a Critical security function and states it "is enforced together with a remote provider," and a reader who follows the reference will not find that substantiated.

Two things would close it:

  1. A file or function reference for where Meshery Server checks the key on an inbound request — middleware over the handler set, per-handler, or route-dependent. One line in the self-assessment would settle it.
  2. Whether a negative test exists: two principals in the same organization, one holding the capability and one not, issuing the same request, the second refused. The reference's Step 7 is "login and verify that your UI component gates correctly," which is the positive path, and the Troubleshooting section is oriented toward false denials rather than false allows.
    If the accurate answer is that enforcement is partial or route-dependent today, saying so in Non-goals would be worth more than a general claim. That section is already the most candid part of this document — the plaintext server-adapter gRPC and default-off broker auth admissions especially — and one more line there costs nothing.

One smaller thing worth surfacing: the reference carries an explicit carve-out that "not all pages uses CASL authorization, means even if you are not assigned with any role within organization you might access preferences page and Meshery UI dashboard." That is UI-scoped, but it is the kind of statement a self-assessment reader benefits from seeing directly rather than three links away.

@leecalcote leecalcote Aug 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Santoshkumarpuppala, thank you much for this critique and rooting out gaps. The self-assessment asserts the capability model “is enforced together with a remote provider”. This statement is accurate, however, the reference we pointed you to substantiates the UI half (the seeding of keys) and not the server half (enforcement of a authZ decision).

I'm still going through code review and gathering details, and more closely verifying that we don't have gaps here. It's taken about half of today, and I'm almost done, but I want to offer a concise clarification of the three roles at play here:

  • The Meshery project defines the extensible key framework. Permission keys are globally unique and never reused; if a key's meaning would change, a new key is issued instead.
  • The Providers decide and Meshery Server enforces. The server determines which provider is in effect for the session and honors that provider's identity validation and authorization decision. With the Local Provider, Meshery performs the provider role itself and the check is pass-through — single-user and all-empowered by design, but the check still runs. With a remote provider, the server proxies the request and enforces the decision returned to it.
  • Meshery UI is UX only. It uses the session's keys so users are not teased with controls that are off limits to them. It is not a security boundary.

Here's the reference you asked for in Meshery Server. Enforcement lives in server/models/remote_provider.go, per operation rather than as a blanket middleware (which answers your In answer your middleware-or-per-handler question). Each gated operation checks the provider-supplied capability set before doing anything else and refuses with 403:

func (l *RemoteProvider) ShareDesign(req *http.Request) (int, error) {
    if !l.Capabilities.IsSupported(ShareDesigns) {
        return http.StatusForbidden, ErrInvalidCapability("ShareDesigns", l.ProviderName)
    }
    ep, _ := l.Capabilities.GetEndpointForFeature(ShareDesigns)
    // ... proxy to the provider endpoint

This guard is an example of pervasive pattern. Capabilities.IsSupported appears at 105 call sites, ErrInvalidCapability at 102 refusal sites, across 91 distinct gated operations — user and org reads, results publication, connections, credentials, designs, events and preference sync, and so on.

Screenshot 2026-08-18 at 7 16 06 PM

To be clear, this gate is feature-level, meaning that whether the provider offers a capability to this server (see the screenshot below as an example of those provider capabilities).

Your two-principals case is a well-placed question and an excellent scenario to dissect. The two-principals case adjudicated by the remote provider on the proxied request, with Meshery Server enforcing the returned decision.

Regarding a negative test, nothing in Meshery Server's Local Provider exercises two principals, one holding a capability and one not, issuing the same request with the second refused. Not in the Go tests, the Playwright E2E suite, or the mesheryctl suite.

No test exists, because the Local Provider is single-user and all-empowered by design. There is no second principal to refuse. As a project, Meshery defines the organization, role, user, keys (and so on) constructs (see https://schemas.meshery.io), validates their conformance to schema, is cognizant of these constructs as it manipulates them, however, since the in the multi-user scenario, organizations, and key assignment are properties of a remote provider.

So the honest framing is that Meshery enforces per-principal authorization but does not adjudicate it in the multi-user case. It owns the key framework, the proxying, and the enforcement of the decision returned to it. Under its own provider it plays both parts, with a pass-through decision. Under a remote provider the adjudication belongs to that provider, whose internals are outside this assessment - which is why a negative test for two distinct principals has no home in Meshery's own suites.

@leecalcote leecalcote Aug 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be unambiguous: the self-assessment's statement that the capability/role model “is enforced together with a remote provider” is accurate, and the enforcement path exists in every configuration. Under Meshery's own Local Provider, Meshery performs the provider responsibilities itself and the authorization check is pass-through - single-user, all-empowered by design. The mechanism still runs; the policy is simply permissive. A permissive decision that is made and honored is enforcement, not the absence of it.

With that said, I completely understand how our self-assessment didn't make this obvious/excluded the precise distinction between an access-check, a control-check, and the precise split in behavior of Meshery Server between providers. It's sophisticated (to put it politely).

So, the rest of the analysis below on Meshery UI is essentially a moot point, but I'll include it anyway for diligence.

Meshery UI has 20 pages. 18 of 20 pages have at least one live CASL check (a control check - not an access check). The two pages that don't are 1) /404 and 2) a three-line redirect, neither carrying protected content. We did find that one page

  • 16 access-gated - a keyless, authenticated user gets the permission-denied page instead of content
  • 2 content-bearing but access-ungated
  • 2 with no protected content at all — /404 and /telemetry, an error page and an eleven-line redirect that renders nothing.

Again, for my part, I really appreciate the effort put into critiquing Meshery, making it that much better, @Santoshkumarpuppala.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for going and reading the code rather than restating the claim — that's more than I expected, and it settles both of my questions. 105 IsSupported call sites and 102 ErrInvalidCapability refusals across 91 operations is the substantiation I was looking for, and remote_provider.go, per operation rather than middleware, is a direct answer to the middleware-or-per-handler question.

Your point that a permissive decision made and honoured is still enforcement is well taken, and the enforce-versus-adjudicate split is the piece I was missing. It also settles the negative test cleanly: a test for two principals can't live in a suite where the provider that distinguishes them isn't present. That's a structural answer rather than a gap, which is a better outcome than the one I was expecting.

Which brings me back to my original ask, unchanged — one line in the self-assessment. As it stands, the Actors table says every API route passes through provider > auth > session-injector middleware, and the Critical security function says the capability model "is enforced together with a remote provider." A reader who puts those two together will assume the capability check sits in that middleware chain. It doesn't: it's at each of 91 gated operations, checked before anything else, refusing with 403. That's a stronger claim than the one the document currently makes, and unlike the current wording it tells a reviewer where to look.

Two things worth adding alongside it:

  • The enforce-versus-adjudicate distinction, in your own words. Non-goals already places a remote provider's internals outside the assessment's scope, so the boundary is there; what's missing is that Meshery enforces per-principal authorization without adjudicating it in the multi-user case. Without that sentence, "no negative test exists" reads as an omission rather than a consequence.
  • The access-check versus control-check distinction you used for the UI audit. It's doing real work — it's what makes "18 of 20 pages have a live check" and "16 are access-gated" different statements — and it isn't in the document at all.

On the configurator page and meshery/meshery#21492: noted, and I'll leave it with you. That's Meshery's issue about Meshery's own UI, and you found it by auditing all twenty pages rather than the one I asked about, which is the more useful outcome by some distance.

@leecalcote leecalcote Aug 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Santoshkumarpuppala - done in angellk#2. The Critical security-function bullet now says the check is not in the middleware chain, names server/models/remote_provider.go and the 91 gated operations, carries the enforce-versus-adjudicate distinction so the absent negative test reads as a consequence rather than a gap, and introduces the access-check versus control-check vocabulary that was missing from the document entirely. It is one bullet, and it is a stronger and more checkable claim than what it replaced - which was your point.


- **Provider authentication gate.** All API access flows through AuthMiddleware > provider.GetSession(). For remote providers this performs RS256 JWT signature verification against the provider's JWKS, expiry validation, server-side introspection (to honor revocation), and token refresh. This is the central authentication control for multi-user deployments.
- **Capability/role-based authorization model.** A fine-grained permission matrix (server/permissions/keys.csv) maps capabilities to roles and is enforced together with a remote provider, constraining which management actions a principal may perform.
- **Software supply-chain integrity controls.** Mandatory DCO sign-off, required peer review with branch protection, and a CI gate (lint/static analysis, CodeQL, container and dependency scanning, OpenSSF Scorecard, OSPS Baseline) that must pass before merge or release. See [Development pipeline](#development-pipeline).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are software supply chain checks, not product design elements, correct? (i.e. the product itself isn't enforcing DCO on end-user components)

If so, this is more relevant under "secure development practices".

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. "Centralized input sanitization for query ordering" stays, but DCO sign-off, branch protection, and the CI scanning gate are development-process controls can move.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case it were to go unnoticed, I PR'ed an update to here angellk#1

@Santoshkumarpuppala Santoshkumarpuppala left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — it's one of the more honest self-assessments I've read. The Non-goals section in particular does something most don't: it states the sharp edges out loud (plaintext adapter gRPC, unauthenticated local provider, default-broad RBAC, empty securityContext) rather than leaving a reader to infer them. The accuracy corrections (golangci-lint/CodeQL rather than gosec, the mTLS walk-back) also read as a team that went and checked rather than described from memory. That candour is worth more to a reader than a longer feature list would be.

I read it with one narrow lens, the same one I'd offer as the general suggestion: for each isolation boundary the document claims, does it name the single server-side point that enforces it, and what would a negative test look like — a request that should be refused, and is. Authentication is covered well; authorization and tenant isolation are the thin parts, and I think they're the ones that matter most given the RBAC posture below.

One observation to lead with. provider.GetSession() gets a full, precise paragraph — JWKS verification, expiry, introspection, refresh. That's authentication. The capability model right next to it — keys.csv, the User / Team Admin / Workspace Admin / Org Admin roles — is described only as "enforced in conjunction with a remote provider," with no enforcement point named. And multi-tenant isolation (org / team / workspace) isn't described as a boundary at all, though the roles imply one.

That gap is more load-bearing here than in most projects, because the assessment also says the server runs with cluster-admin-equivalent RBAC and applies manifests on the user's behalf. So Kubernetes RBAC is explicitly not the backstop — the server can touch anything. That makes the Meshery capability check the only boundary between an authenticated principal and any action on any managed cluster. A control doing that much work is worth describing as precisely as the authentication path already is.

Specific spots, in rough priority order:

  1. Authorization enforcement point. keys.csv is named as the permission matrix, but not what reads it. When a User-role principal issues a request to an Org-Admin-only action, which component refuses it — a middleware, a per-handler capability check, or the Rego/OPA policy layer — and where in the request chain does it run? The negative test is concrete: a valid session for a low-capability role calling a high-capability endpoint, refused. Naming that one component would move authorization up to the standard the authentication paragraph already sets.

  2. Multi-tenant isolation. Organizations, teams, and workspaces appear as roles and collaboration features, but nothing describes what keeps Org A's designs, credentials, or discovered resources from Org B. When a principal scoped to Org A requests a resource owned by Org B, what refuses it, and is the check per-record or per-collection? This is the question a reader most wants answered for a collaborative multi-tenant platform, and right now the document routes it entirely through "use a remote provider" — which is the authentication answer, not the isolation answer.

  3. The SanitizeOrderInput regression question. Converging every order/sort path on one sanitizer is the right fix. The durability question is what keeps a new code path from concatenating an ORDER BY without it — a lint rule, a typed query builder, a test that fails on a raw-ordering sink? A central sanitizer only holds as long as every call site is routed through it, and the five CVEs show this is the class the project actually gets reports on. Saying what enforces "all order input goes through SanitizeOrderInput" would make that a control rather than a convention.

  4. Adapter trust boundary. Adapters reuse the meshery-server ServiceAccount over a plaintext gRPC channel (both stated plainly, which is good). The authorization question the doc doesn't close: does the server constrain what an adapter may do to the operations it was dispatched, or does an adapter effectively inherit the server's full cluster-admin reach? If the latter, enabling an adapter extends the cluster-admin trust boundary to it — worth stating as explicitly as the extension-surface point already is for providers/integrations.

  5. Local provider as the single-user boundary. The document is clear that the local provider performs no authentication and isn't for exposed use. Given how much of the security model rests on "use a remote provider," it may be worth one sentence on what, if anything, prevents the local provider from being selected in a shared deployment — is it a deploy-time decision only, or is there any runtime guard? Not a flaw, just the one place where the entire authn/authz model can be turned off by configuration.

  6. GraphQL WebSocket origin policy. Already flagged as security-relevant, which is the right call. The concrete framing: a cross-origin subscription that should be refused is currently accepted, so cross-site WebSocket hijacking is the negative test, and "restrict origins at the proxy" is a deployment mitigation rather than an in-code control. Worth noting whether tightening the in-code origin check is on the roadmap alongside the proxy guidance.

Two smaller things:

The datastore is described as a cache with no application-layer encryption at rest, protected by file permissions — stated honestly. Since it holds kubeconfigs and discovered Secrets, it might help to name that explicitly in the Actors row (the SQLite file contains cluster-admin credentials), so a reader weighs the file-permission dependency accordingly. The at-rest encryption roadmap item already implies this; making the sensitivity explicit sharpens it.

There's no single attacker model stated. The document is honest boundary-by-boundary, but a short paragraph naming the assumed adversaries — an authenticated low-role user, a principal in a neighbouring org, a malicious enabled adapter, an unauthenticated caller reaching a local-provider instance — would let a reader resolve most of the questions above by reading them against a stated model rather than inferring one per section.

None of this is a finding — it's all "the document asserts (or implies) a boundary and I can't tell from the text what enforces it." Happy to be pushed back on any of it, especially the authorization points, where the enforcement may be obvious to people working in the server daily and simply not yet written down.

@leecalcote

leecalcote commented Aug 14, 2026

Copy link
Copy Markdown
Member

@JustinCappos @evankanderson @Santoshkumarpuppala, first, thank you. We appreciate your help here. 🙏 Your time spent understanding Meshery's architecture, offering insights as to where improvements might be made, drives clarity in its design, and only serves to improve the project. Second, the collection of Meshery maintainers were alerted earlier today of your efforts and outstanding remarks. Please expect responses shortly.

@leecalcote

leecalcote commented Aug 14, 2026

Copy link
Copy Markdown
Member

6.GraphQL WebSocket origin policy. ✅ Good news: in the time between this self-assessment's latest version (June 10th, 2026) to now, the WebSocket transport no longer exists. GraphQL subscriptions were retired in favor of REST and Server-Sent Events in #20587 (merged July 11th, 2026).

Meshery Server (in server/internal/graphql/graphql.go) now registers only transport.POST and transport.GET, and schema.graphql has no type Subscription. The permissive-origin upgrader went with it, so cross-site WebSocket hijacking against the GraphQL endpoint is not reachable - there is no upgrade path to hijack. Real-time surfaces (events, connection status, MeshSync updates) are now SSE over the same authenticated REST path, subject to the same AuthMiddleware chain.

Meshery Docker Extension (in install/docker-extension/vm/proxy/proxy.go) still sets CheckOrigin to accept any origin. That is the Docker Desktop extension's in-VM socket proxy reachable only from within the Docker Desktop VM. The Meshery Docker Extension is one of a few different, supported Meshery deployment modes. Docker Extension VM's use of GraphQL is separate from Meshery Server, but it is the same pattern, so I'm calling it out just to be explicit.

KumarNirupam1 pushed a commit to KumarNirupam1/meshery that referenced this pull request Aug 15, 2026
…dance

Extensibility is a capability, not a sandbox: an enabled extension runs inside
the deployment's trust boundary with no privilege separation from Meshery
itself. That was not stated anywhere an operator would look.

Adds a "Trusting an extension" section to the production security-hardening
guide covering what each extension point can reach, how a provider extension
package is delivered and loaded, what to evaluate before enabling one, how to
constrain and pin it, and how to remove one. Two facts are now stated plainly:
a provider extension package may carry a native in-process server plugin that
receives the datastore, the broker connection, the MeshSync channel and the
Kubernetes connection tracker and can serve its own HTTP routes; and UI
extension components load into Meshery UI's own browser origin and session.
Because the package origin comes from the provider's capabilities document,
selecting a Remote Provider is itself a code-trust decision.

Threads the same model through the extensibility reference. The extension-point
index gains a linked table of all nine extension points and a security and
trust model section; provider docs frame provider selection as a code-trust
decision and document SKIP_DOWNLOAD_EXTENSIONS as a pin rather than only a
bandwidth saver; UI docs state the shared-origin boundary; build-time docs
frame pre-packaging as a supply-chain control. The production index,
operational readiness checklist and identity page cross-link into it.

Raised during CNCF TOC security self-assessment review (cncf/toc#2264).

Signed-off-by: yi-nuo426 <218099172+yi-nuo426@users.noreply.github.com>
prabhat-kumar96 pushed a commit to prabhat-kumar96/meshery that referenced this pull request Aug 18, 2026
Meshery resolves how to fulfill a design one component at a time, from the
registrant of that component's model, and that behavior was written down
nowhere. A CNCF TOC reviewer's question (cncf/toc#2264) exposed the gap.

Adds concepts/architecture/deployment-engine: what a registrant is, that every
model carries one, that fulfillment is resolved per component rather than per
design, the two fulfillment paths and the single thing that selects between
them (whether the registrant advertises a host and port), and a worked example
of one design exercising both paths in a single deployment. Includes a diagram.

Out-of-scope fixes carried along:

- guides/infrastructure-management/overview said only Artifact Hub models are
  supported and titled its dependency-handling list "Deployment Mechanism by
  Source", which read as the full fulfillment story while omitting adapters
  entirely. Corrected and cross-linked.
- Its "Auto-Deployment of CRDs and Operators" heading is raw HTML, so Hugo
  generated no anchor for it. Meshery UI's "Include Dependencies" help text
  deep-links to that anchor; the link has been landing at the top of the page.
  Added the explicit id.
- Recorded the docs build's Dart Sass requirement in Build Environment
  Gotchas: `make -C docs check-deps` only checks that *a* `sass` exists, so a
  Ruby sass gem passes it and then fails every page with a TOCSS-DART error
  that blames file permissions.

Cross-linked from Designs, Components, Registry, Adapters and the Architecture
overview.

Signed-off-by: marblom007 <158522975+marblom007@users.noreply.github.com>
leecalcote added a commit to leecalcote/toc that referenced this pull request Aug 21, 2026
… model

Reviewer questions on cncf#2264 and on this PR surfaced three things the
assessment either understated or did not say at all.

Authorization model. The Critical security-function bullet now states that the
capability check is not part of the provider > auth > session-injector
middleware chain, and points at the per-operation enforcement in
server/models/remote_provider.go across 91 gated operations refusing with 403.
It adds the enforce-versus-adjudicate distinction, so the absence of an in-tree
negative test reads as a consequence of the provider boundary rather than as a
gap, and it introduces the access-check versus control-check vocabulary the
document did not carry.

Actors and adversaries. Every row in the human and external actors table now
opens with one common trust verdict. The adapter row is rebuilt around the
direction a reviewer correctly identified as the more serious one: the
server-adapter gRPC channel uses insecure.NewCredentials(), so it is plaintext
with no TLS in either direction, not merely without mutual TLS, and an adapter
acts on the cluster with a cluster-admin-equivalent ServiceAccount. The
unauthenticated-attacker row names the LoadBalancer defaults and the absent
NetworkPolicy. The hostile-workload row names all three reachable surfaces
rather than only the broker. The storage row replaces the assumption of a
persistent volume, which the chart does not declare, with the actual
reachability in the in-cluster and desktop deployment modes.

Broker authentication. The document said broker authentication is off by
default in three places. Meshery Operator has generated the meshery-nats-auth
Secret before the NATS pod starts since 2026-06-30, which post-dates this
assessment's stamp. Broker TLS is genuinely still absent, so only the
authentication half is corrected.

Signed-off-by: Lee Calcote <leecalcote@gmail.com>
@miacycle

Copy link
Copy Markdown

Hi @angellk @evankanderson @JustinCappos @Santoshkumarpuppala @sherine-k, between the responses here and the impending updates in angellk#1 and angellk#2, all feedback has been addressed. Please confirm.

Hi @carlosriosilva @hortison @sangramrath @simihablo @yi-nuo426 @pontusringblom @sarajkrishnasingh @fitzergerald @leecalcote, thank you all for your time spent responding to the security self-assessment review comments.

@Santoshkumarpuppala

Copy link
Copy Markdown

Confirmed, @angellk — and the changes in angellk#2 go further than what I asked for.

My ask had narrowed to one line naming the server-side enforcement point. That PR delivers it:

This check is not part of the provider > auth > session-injector middleware chain described under Actors: it is per-operation in server/models/remote_provider.go, where each of 91 gated operations tests the provider-supplied capability set before doing anything else and refuses.

I checked the figure against meshery/meshery at master rather than take it on trust: server/permissions/keys.csv is present, and ErrOperationNotAvaibale appears exactly 91 times in server/models/remote_provider.go. The number is right, and unlike the previous wording it tells a reviewer where to look.

It also picks up the other three things I raised and did not expect to see all of: the enforce-versus-adjudicate distinction, the access-check versus control-check distinction from the UI audit, and the CASL carve-out that was previously three links away. Putting the partial-coverage shape in Non-goals rather than as a general claim is the right home for it — that section was already the most candid part of the document and it stays consistent.

Two items from my 13 August review are not in these changes. Neither is blocking, and I would not hold the assessment for either:

  • Multi-tenant isolation. What refuses a principal scoped to Org A requesting a resource owned by Org B, and whether that check is per-record or per-collection. The capability model answers what a role may do, not across which tenant boundary — they are different questions and only the first is now covered.
  • SanitizeOrderInput durability. Converging every order path on one sanitizer is the right fix; what is unstated is what keeps a new call site from concatenating an ORDER BY without it — a lint rule, a typed builder, a failing test. That is what makes it a control rather than a convention, and it is the class the project actually receives reports on.

Both are larger than a line, which is why I raise them as known thin spots for the record rather than as review items. The authorization enforcement path was the load-bearing gap and it is closed.

Thanks to @yi-nuo426 in particular for going and reading the code rather than restating the claim — that is what moved this.

One process note: both PRs are still open, so I am confirming the text as written in angellk#2 on the basis that it lands as-is.

Security self-assessment authored by Meshery maintainers following
the TAG Security template. Covers actors, actions, goals, non-goals,
security functions, development pipeline, vulnerability history, and
compliance posture. Required for incubation DD (cncf#1386).

Signed-off-by: Karena Angell <karena.angell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-triage Indicates an issue or PR that has not been triaged yet (has a 'triage/foo' label applied) tag/security-and-compliance TAG Security and Compliance

Projects

Status: New
Status: No status
Status: No status
Status: No status

Development

Successfully merging this pull request may close these issues.