Sign inSign up

kukisama/pimdemo

By kukisama

Updated about 1 month ago

Microsoft Entra PIM 演示:用你自己租户的真实数据(单容器)

Image
Security
API management
1

539

kukisama/pimdemo repository overview

PIM Demo — 用真实数据把 Microsoft Entra PIM 讲清楚

Release GHCR Docker Hub

一句话:一个纯前端应用,用你自己租户的真实数据,把 Microsoft Entra PIM(即时特权访问)的完整能力——Entra 角色、组、Azure 资源、访问包、审批、访问审查、告警、日志——汇聚成一个可点击、可演示、可自查的站点。

docker run -d -p 8080:8080 -v pim_data:/app/data \
  -e VITE_REDIRECT_URI=http://localhost:8080/ \
  -e VITE_GLOBAL_TENANT_ID=你的租户ID -e VITE_GLOBAL_CLIENT_ID=你的clientId \
  ghcr.io/kukisama/pimdemo:latest

它解决什么问题

企业要落地「零常设管理员 / 最小特权」,但 PIM 的能力散落在 Entra 与 Azure 门户的多个角落,概念又抽象(合格 vs 激活、JIT、审批、访问审查…):既不好向管理层 / 客户讲清价值,也不好快速核对自己租户的现状。本工具把这些能力收进一个界面,用真实数据一页页呈现。

谁会用它

  • 售前 / 顾问:给客户做 PIM 的 POC 演示,不用在门户里东点西点。
  • 企业 IT / 安全管理员:一屏看清「哪个组 / 账号握有哪些特权、激活要不要 MFA / 审批、有哪些治理告警」,快速自查。
  • 学习者:内置图文「学习中心」,边看边学 PIM 概念与操作。

特点

  • 真实数据,不是 mock:直接读写你的租户(读操作安全随便点,写操作有明确提示)。
  • 一站式:三种 PIM 提供程序 + 访问包 / 审批 / 访问审查 / 告警 / 日志,外加「组权限透视」一键看清一个组的全部权限归属。
  • 本地即可跑、无需公网:SPA + PKCE,无 client secret,令牌只在浏览器(详见下文)。
  • 双云:Azure Global 与世纪互联(21Vianet)。
  • 自带文档:应用内图文「学习中心」(登录后 /learn,含逐页截图的 POC 上手 SOP)。

一键开始

项目根目录使用 PowerShell 7 (pwsh) 执行:

./Start-PimDemo.ps1

它会自动:检查 Node → 装依赖 →(首次)交互登录并创建应用注册 → 启动 http://localhost:5173 并在默认浏览器打开。可选参数:-SkipAppReg(.env 已配好、跳过注册)、-Build(生产构建 / 打包)、-Docker(容器方式运行)、-NoBrowser(不自动开浏览器)。

首次若提示"无法加载脚本"(执行策略限制),改用: pwsh -ExecutionPolicy Bypass -File .\Start-PimDemo.ps1

先看下面的先决条件;再往下是脚本背后的手动步骤、"是否需要公网"与部署方式。

支持 Azure Global 与 Azure 中国世纪互联(21Vianet)双云。


交付形式

  • 前端:React + Vite 的 SPA,用 MSAL 授权码 + PKCE 登录,前端直连 Graph/ARM。
  • 后端:只有一个零依赖的极小 Node 服务 server/index.mjs(Node 内置 http + sqlite,无需 npm install),用途仅两条——托管静态文件 + 从 SQLite 提供运行时配置。不接触令牌、不存业务数据。
  • 两种跑法
    • 本地直跑(Vite dev server,localhost:5173)——演示 / 自用最快,见下。
    • 单容器部署(Docker)——想让别人通过一个网址访问时才需要;镜像已发布到公共仓库,无需 clone 代码、无需自己 build,见下。

先决条件

  • 一个 Entra 租户 + 至少一个 Entra ID P2 席位(PIM 是 P2 能力)分配给演示账号。
  • 一个能创建应用注册并授予管理员同意的账号(全局管理员 / 特权角色管理员 等)。
  • 演示账号已启用 MFA(PIM 激活要用;细节见学习中心「初始环境配置」)。
  • 本机:Node ≥ 22.13 + npm(server/index.mjs 用的 node:sqlite 从 22.13 起才无需实验开关);PowerShell 7 + Microsoft.Graph.Authentication 2.25.0(仅注册脚本需要)。

手动跑起来(Start-PimDemo.ps1 背后做了什么 · Global 云)

一键脚本已封装以下步骤;想手动一步步来、或想了解原理时看这里。

# 1) 安装依赖(在仓库根目录,monorepo)
npm install

# 2) 准备配置
Copy-Item .env.example .env

# 3) 一条脚本自举:交互登录 Graph → 幂等创建「PIM Demo SPA」应用注册
#    (SPA 重定向 URI = http://localhost:5173/)→ 附加所需 Graph/ARM 委托权限
#    → 按租户授予管理员同意 → 把 client/tenant id 写进 .env
./scripts/New-PimDemoAppRegistration.ps1 -Cloud Global -WriteEnv

# 4) 启动开发服务器
npm run dev -w apps/web

# 5) 浏览器打开 http://localhost:5173 → 登录 → 先看「预检」页是否全绿

21Vianet(中国区)因为全局注册的应用不会复制到 Azure 中国,需要先手工建一个「引导应用」再跑脚本 -Cloud China21V。完整步骤见学习中心「初始环境配置」或 docs/应用注册指南.md


需要公网吗?——不需要

本地跑 + 这台机器能上网,就够了。 不必发布到公网、不必买域名或证书、不必开放入站端口。原因:

  • 登录是浏览器跳转到 login.microsoftonline.com,Graph/ARM 调用是浏览器发出的 fetch——全部是出站请求。
  • 重定向地址默认 http://localhost:5173/,Entra 对 SPA 的 localhost(loopback)允许明文 http(这是官方对本机地址的例外,生产的非本机地址才强制 HTTPS)。
  • 后端只在本机监听,不需要被外部访问。

只有当你想让别人通过一个 HTTPS 网址访问时,才需要公网:那时用 Docker 部署 + 你自己的反向代理终结 TLS,并把该网址登记为 redirect URI。见 docs/部署指南.md


给别人用:容器部署(已发布公共镜像)

镜像已发布到两个公共仓库,不需要 clone 代码、不需要自己 build

docker pull ghcr.io/kukisama/pimdemo:latest   # GitHub Container Registry
docker pull kukisama/pimdemo:latest           # Docker Hub

支持 linux/amd64linux/arm64。按本项目发布约定,每次发布只产生两个 tag:版本号(如 0.4.0)与 latest。tag 不是 registry 强制不可变对象;要求可重复部署时请使用 Release 中记录的 digest。历史版本见 Releases

最小可用 docker-compose.yml(把三个值换成你自己的):

services:
  pimdemo:
    image: ghcr.io/kukisama/pimdemo:0.4.0     # 生产建议钉死版本,别用 latest
    environment:
      VITE_ENABLED_CLOUDS: "global"
      VITE_REDIRECT_URI: "https://pim.example.com/"   # 必须与应用注册逐字符一致
      VITE_GLOBAL_TENANT_ID: "租户 GUID,或 organizations 表示多租户"
      VITE_GLOBAL_CLIENT_ID: "你的应用注册 clientId"
    ports: ["8080:8080"]
    volumes: ["pim_data:/app/data"]              # SQLite 配置持久化,升级不丢
    restart: unless-stopped
volumes:
  pim_data:
docker compose up -d
curl http://localhost:8080/healthz     # -> ok

docker compose pull && docker compose up -d    # 升级

要点:单容器;配置运行时注入(改环境变量重启即生效,不用重建镜像);容器内不带反向代理,TLS 由你自己在前面终结;单 / 多租户与 21Vianet 均支持。

./Start-PimDemo.ps1 -Docker 只按仓库根 Compose 从源码构建并启动,不会自动创建应用注册或写 .env;请先配置 Compose 中的 Tenant ID、Client ID 与生产 redirect URI。

详见 部署指南(部署形态、反代、排错)与 容器发布与更新流程(镜像里装了什么、版本与升级回滚)。


配置项

全部是非机密公开值(SPA 用 PKCE,无 client secret),见 .env.example:启用的云、各云 tenant / client id、redirect uri、预览特性开关。容器部署时同名 VITE_* 通过 docker-compose.ymlenvironment: 注入,由后端播种进 SQLite。

配置解析顺序:运行时 window.__PIM_CONFIG__(容器 /config.js,非空优先)→ 构建时 .env。本地 dev 无 /config.js,自动回退 .env


文档 / 学习中心


安全说明

  • SPA 用 PKCE无 client secret;令牌只在浏览器 sessionStorage
  • 后端不接触令牌、不落业务数据;SQLite 只存公开配置
  • 所有 PIM 数据只在你当前浏览器内存里展示;预检快照等导出由你手动下载到本机,服务器不保存。

常用命令

npm run dev -w apps/web    # 开发服务器(localhost:5173)
npm run build             # 生产构建 -> apps/web/dist
npm test                  # 单元测试(vitest)
npm run typecheck         # 类型检查

Tag summary

Content type

Image

Digest

sha256:662ac16e9

Size

31 MB

Last updated

about 1 month ago

docker pull kukisama/pimdemo