🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

多租户隔离工作台 GuoMonth/dsh-multi-tenant

DeepSeek Harness
GuoMonth6 天前有提交已提供中文文档扫描:含敏感能力

在 Kubernetes 上自托管的多用户 DeepSeek Harness。成员通过 OpenID…

43.7/100
综合分
22
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;engines.node 要求 ^24.0.0 || ^26.0.0,不满足 Node 22.19.0;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add GuoMonth/dsh-multi-tenant
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · other
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 6 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;engines.node 要求 ^24.0.0 || ^26.0.0,不满足 Node 22.19.0;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-multi-tenant-root(未发布到 npm,仅可源码安装)
✗Node 引擎要求 ^24.0.0 || ^26.0.0 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 04:32:58

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 49 处,展示前 49 条)
  • 读取本地文件
    charts/install.mjs:12
    export const sources = JSON.parse(readFileSync(resolve(files, 'sources.json'), 'utf8'));
  • 读取本地文件
    charts/install.mjs:20
    ]) if (sha(readFileSync(resolve(files, file))) !== expected) throw new Error(`Packaged asset checksum mismatch: ${file}`);
  • 读取本地文件
    charts/install.mjs:21
    const original = readFileSync(resolve(files, sources.core.original), 'utf8');
  • 读取本地文件
    charts/install.mjs:22
    const pinned = readFileSync(resolve(files, sources.core.pinned), 'utf8');
  • 执行外部命令来自配置/变量
    charts/install.mjs:28
    const result = spawnSync(command, args, { encoding: 'utf8', input, timeout: 360_000, maxBuffer: 8 * 1024 * 1024 });
  • 发起网络请求
    charts/install.mjs:119
    const response = await fetch(`${config.oidc.issuer.replace(/ $/, '')}/.well-known/openid-configuration`, { signal: AbortSignal.timeout(15000), redire
  • 读取本地文件
    integration/e2e/browser.cjs:4
    const users=JSON.parse(fs.readFileSync(process.env.E_PRIVATE+'/users.json'));
  • 写入本地文件
    integration/e2e/browser.cjs:42
    await context.storageState({path:process.env.E_PRIVATE+'/'+user.name+'-browser.json'});fs.chmodSync(process.env.E_PRIVATE+'/'+user.name+'-browser.json
  • 写入本地文件
    integration/e2e/browser.cjs:43
    result.users.push(record);fs.writeFileSync(process.env.E_EVIDENCE+'/browser.json',JSON.stringify(result,null,2));
  • 读取本地文件
    integration/e2e/lifecycle.cjs:4
    const records=JSON.parse(fs.readFileSync(evidence+'/browser.json')).users;
  • 发起网络请求
    integration/e2e/lifecycle.cjs:6
    const rpc=(page,method,args)=>page.evaluate(async({method,args})=>{const r=await fetch('/api/'+method,{method:'POST',headers:{'content-type':'applicat
  • 写入本地文件
    integration/e2e/lifecycle.cjs:12
    const save=()=>fs.writeFileSync(evidence+'/lifecycle.json',JSON.stringify(result,null,2));
  • 发起网络请求
    integration/e2e/model-tool.cjs:5
    const rpc=(p,method,args)=>p.evaluate(async({method,args})=>{const r=await fetch('/api/'+method,{method:'POST',headers:{'content-type':'application/js
  • 读取本地文件
    integration/e2e/performance.cjs:4
    const user=JSON.parse(fs.readFileSync(root+'/users.json'))[0];
  • 写入本地文件
    integration/e2e/performance.cjs:5
    (async()=>{const browser=await chromium.launch({headless:true,args:[`--host-resolver-rules=MAP *.dsh-mvp-rc2.test ${process.env.E_NODE_ADDRESS}, MAP d
  • 发起网络请求
    integration/e2e/performance.cjs:5
    (async()=>{const browser=await chromium.launch({headless:true,args:[`--host-resolver-rules=MAP *.dsh-mvp-rc2.test ${process.env.E_NODE_ADDRESS}, MAP d
  • 执行外部命令固定命令
    integration/e2e/prepare-install.mjs:6
    const k=(args,input)=>execFileSync('kubectl',['--kubeconfig',config,...args],{input,encoding:'utf8',stdio:['pipe','pipe','pipe']});
  • 读取本地文件
    integration/e2e/prepare-install.mjs:11
    apply([{apiVersion:'v1',kind:'Secret',metadata:{name:'reference-tls',namespace},type:'kubernetes.io/tls',data:{'tls.crt':readFileSync(root+'/tls.crt')
  • 读取本地文件
    integration/e2e/prepare-install.mjs:12
    const images=JSON.parse(readFileSync(evidence+'/images.json'));
  • 读取本地文件
    integration/e2e/prepare-install.mjs:13
    const users=JSON.parse(readFileSync(root+'/users.json'));
  • 写入本地文件
    integration/e2e/prepare-install.mjs:17
    writeFileSync(root+'/values.json',JSON.stringify(values,null,2)+'\n',{mode:0o600});
  • 写入本地文件
    integration/e2e/prepare-install.mjs:18
    const kube=JSON.parse(k(['config','view','--raw','--minify','-o','json']));kube.clusters[0].cluster.server=`https://${cluster}-control-plane:6443`;wri
  • 写入本地文件
    integration/e2e/prepare-install.mjs:20
    if(!existsSync(root+'/coredns-before.json'))writeFileSync(root+'/coredns-before.json',JSON.stringify(coredns),{mode:0o600});
  • 读取本地文件
    integration/e2e/prepare-install.mjs:20
    if(!existsSync(root+'/coredns-before.json'))writeFileSync(root+'/coredns-before.json',JSON.stringify(coredns),{mode:0o600});
  • 执行外部命令固定命令
    integration/e2e/prepare-install.mjs:23
    const node=JSON.parse(execFileSync('docker',['inspect',`${cluster}-control-plane`],{encoding:'utf8'}))[0].NetworkSettings.Networks.kind.IPAddress;
  • 写入本地文件
    integration/e2e/prepare-install.mjs:24
    writeFileSync(evidence+'/reference-network.json',JSON.stringify({namespace,nodeAddress:node,issuerService:ip,domain:values.domain,issuer:values.oidc.i
  • 读取本地文件
    integration/e2e/reference-infra.mjs:7
    const digests=JSON.parse(readFileSync(evidence+'/images.json'));
  • 读取本地文件
    integration/e2e/reference-infra.mjs:9
    const users=JSON.parse(readFileSync(privateRoot+'/users.json'));
  • 读取本地文件
    integration/e2e/reference-infra.mjs:10
    const clientSecret=readFileSync(privateRoot+'/client-secret','utf8');
  • 执行外部命令固定命令
    integration/e2e/reference-infra.mjs:11
    const apply=items=>execFileSync('kubectl',['--kubeconfig',process.env.KUBECONFIG,'apply','-f','-'],{input:JSON.stringify({apiVersion:'v1',kind:'List',
  • 读取本地文件
    integration/e2e/reference-infra.mjs:15
    {apiVersion:'v1',kind:'Secret',metadata:meta('reference-tls'),type:'kubernetes.io/tls',data:{'tls.crt':readFileSync(privateRoot+'/tls.crt').toString('
  • 读取本地文件
    integration/e2e/revocation.cjs:5
    const bob=JSON.parse(fs.readFileSync(evidence+'/browser.json')).users[1],session=JSON.parse(fs.readFileSync(evidence+'/lifecycle.json')).users[1].sess
  • 写入本地文件
    integration/e2e/revocation.cjs:9
    fs.writeFileSync(root+'/platform-config-before.json',JSON.stringify(original),{mode:0o600});
  • 写入本地文件
    integration/e2e/revocation.cjs:15
    fs.writeFileSync(evidence+'/revocation.json',JSON.stringify({membershipReload:true,establishedNativeWebsocketClosed:true,newNativeHttpRejected:true,re
  • 写入本地文件
    integration/e2e/revocation.cjs:17
    const result={membershipReload:true,establishedNativeWebsocketClosed:true,newNativeHttpRejected:true,restoredForUserE2E:true};fs.writeFileSync(evidenc
  • 读取本地文件
    integration/environment-contract/verify.mjs:8
    const pin=JSON.parse(readFileSync(new URL('vendor/environment-connector.json',root)));
  • 读取本地文件
    integration/environment-contract/verify.mjs:9
    const archive=readFileSync(new URL('vendor/'+pin.artifact,root));
  • 执行外部命令来自配置/变量
    integration/environment-contract/verify.mjs:13
    execFileSync(process.execPath,['--input-type=module','-e',"import {environmentTemplate,EnvironmentError,createAgentEnvironmentRuntime} from '@dsh/envi
  • 执行外部命令来自配置/变量
    integration/environment-contract/verify.mjs:14
    execFileSync(process.execPath,[require.resolve('typescript/bin/tsc'),'--noEmit','--strict','--skipLibCheck','--module','NodeNext','--moduleResolution'
  • 读取本地文件
    integration/installation/verify.test.mjs:12
    const values = JSON.parse(readFileSync(fixture, 'utf8'));
  • 执行外部命令固定命令
    integration/installation/verify.test.mjs:18
    const result = spawnSync('helm', ['lint', chart, '--values', fixturePath, '--strict'], {encoding:'utf8'});
  • 读取本地文件
    integration/installation/verify.test.mjs:24
    const role = readFileSync(resolve(chart, 'files', sources.runtimeRole.file), 'utf8');
  • 写入本地文件
    integration/installation/verify.test.mjs:78
    writeFileSync(file,JSON.stringify({...values,...changes}));
  • 执行外部命令固定命令
    integration/installation/verify.test.mjs:81
    const missing=spawnSync('helm',['template','dsh-platform',chart],{encoding:'utf8'});
  • 写入本地文件
    integration/installation/verify.test.mjs:85
    writeFileSync(valid,JSON.stringify({...values,namespacePrefix:'a'.repeat(24),resources:{requests:{cpu:'0.5',memory:'512Mi'},limits:{cpu:'2',memory:'2G
  • 删除本地文件递归
    integration/installation/verify.test.mjs:87
    } finally {rmSync(directory,{recursive:true,force:true});}
  • 执行外部命令来自配置/变量
    integration/installation/verify.test.mjs:90
    const result=spawnSync(process.execPath,[resolve(chart,'..','install.mjs'),'install','--values',fixturePath,'--namespace',namespace],{encoding:'utf8'}
  • 写入本地文件
    integration/installation/verify.test.mjs:99
    writeFileSync(file,JSON.stringify({...values,oidc:{...values.oidc,caSecretName:'issuer-ca',caSecretKey:'issuer.pem'}}));
  • 删除本地文件递归
    integration/installation/verify.test.mjs:106
    } finally {rmSync(directory,{recursive:true,force:true});}
扫描于 2026/11/3(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 租户身份管理
  • 会话隔离
  • 租户感知MCP

README

由 DeepSeek 最新模型翻译生成
DSH multi-tenant 在 Kubernetes 上自托管的多用户 DeepSeek Harness。成员通过 OpenID Connect(OIDC)登录,在各自的持久 AI 工作环境中使用 DSH 原生界面。 候选版(RC): Linux/amd64、单节点、平台单副本,面向可信组织成员,仅支持全新安装。RC 组合为平台 0.11.0-rc.1、runtime 0.5.0-rc.1、DSH 0.2.1-rc.3。不做兼容性承诺,部署时固定精确版本和制品。 安装 准备已有 Kubernetes 集群、支持网络策略的 CNI、动态存储、HTTPS 入口和 OIDC 身份提供方。安装机需要 Node 24+、Helm 3 和 kubectl。 npm install --global dsh-multi-tenant@0.11.0-rc.1 按安装指南准备配置,运行预检和安装。镜像使用同版本发布清单中的版本。让 AI 助手操作时,可提供 AI.md(英文)。 使用 打开平台地址并登录,选择 Enter / create,再选择 Inspect / resolve status。状态为 Ready 后,点击 Open environment,在 DSH 内配置模型和工具。 每用户一个持久卷,保存文件、对话、配置及工具凭据。正常启停和 Pod 重建会保留原卷。
展开完整文档(README 剩余 1 节)
DSH multi-tenant

在 Kubernetes 上自托管的多用户 DeepSeek Harness。成员通过 OpenID Connect(OIDC)登录,在各自的持久 AI 工作环境中使用 DSH 原生界面。

候选版(RC): Linux/amd64、单节点、平台单副本,面向可信组织成员,仅支持全新安装。RC 组合为平台 0.11.0-rc.1、runtime 0.5.0-rc.1、DSH 0.2.1-rc.3。不做兼容性承诺,部署时固定精确版本和制品。

安装

准备已有 Kubernetes 集群、支持网络策略的 CNI、动态存储、HTTPS 入口和 OIDC 身份提供方。安装机需要 Node 24+、Helm 3 和 kubectl。

npm install --global dsh-multi-tenant@0.11.0-rc.1

按安装指南准备配置,运行预检和安装。镜像使用同版本发布清单中的版本。让 AI 助手操作时,可提供 AI.md(英文)。

使用

打开平台地址并登录,选择 Enter / create,再选择 Inspect / resolve status。状态为 Ready 后,点击 Open environment,在 DSH 内配置模型和工具。

每用户一个持久卷,保存文件、对话、配置及工具凭据。正常启停和 Pod 重建会保留原卷。Stop 中断整个环境;登出或移除成员会撤销访问并保留数据。重启、删除和排障见运维指南。

文档

- 中文指南 · English guides
- 架构 · 参与开发
- runtime 仓库:维护运行镜像、资源身份与生命周期。平台已打包其 Connector,部署从本仓库开始。
- 发行版本与验证报告

MIT 许可证。
预览分享卡片长什么样 ↓GuoMonth/dsh-multi-tenant
分享 · DeepSeek Harness Hub
GuoMonth/dsh-multi-tenant

在 Kubernetes 上自托管的多用户 DeepSeek Harness。成员通过 OpenID…

回到顶部