All integrations

Recipes · fd1

fd1 · FluxDesk's first production integrator

Walk through fd1's actual 4-tier permission model + how Mode B (request-on-behalf + dispatch) is wired today.

What this recipe is

fd1 is FluxDesk's first production-grade integrator. This recipe walks through its actual 4-tier permission model + how Mode B (request-on-behalf + webhook-driven dispatch) is wired today. Use it as a copy-from reference for any orchestrator that owns access-provisioning duties outside FluxDesk.

fd1 talks to FluxDesk over MCP + the v1 HTTP surface, holds a single flux-tools-… service-account token, and runs alongside (not inside) the FluxDesk container — Charter Art 4 (system boundary).

fd1 4-tier permission map (production)

Tier 0 is granted automatically on first onboard; tiers 1-3 are opt-in via the team-support flow below.

TierCatalog slugCategoryGrantsBackend action
0inbound-fd1

default · auto

🔑 接入凭证 / Access Credentialsfd1 → employee inbox push channelauto-issued on first onboard
1fd1.codex-backend

opt-in · MCP

🤖 公司付费 AI 订阅 / Paid AI SubscriptionsCodex backend (公司 OpenAI 订阅)fd1 codex login <user>

OAuth device-auth on admin Mac

2fd1.claude-backend

opt-in · MCP

🤖 公司付费 AI 订阅 / Paid AI SubscriptionsClaude Code backend (公司 Anthropic 订阅)fd1 claude login <user>

OAuth device-auth

3bastion-terminal-access

reuses FluxDesk row

🖥 vibe coding 开发环境申请fluxdeskone SSH terminal accessfd1 employee ssh-grant <user>

⚠️ Status: MVP (manual dispatch)

Today the request → approve → provision loop is human-bridged. After an admin clicks ✓ 审批通过 in /team-support the team_support.approved webhook fires into the void — fd1's receiver isn't shipped yet. The admin then runs fd1 employee dispatch <req_id> to complete the cycle.

Webhook-driven automation is planned for v0.20.x, once fd1 deploys the webhook receiver to the fluxdeskone host behind a Cloudflare tunnel. Steps 2 → 3 below become automatic then; the rest of the model doesn't change.

1

Admin requests a grant on a user's behalf

One fd1 CLI call per tier. Internally this hits FluxDesk MCP create_team_support_request_on_behalf which records a pending request + pushes an inbox notification to the admin queue.

shell
# Step 1 · admin runs fd1 CLI on behalf of an employee.
# Under the hood this calls FluxDesk MCP create_team_support_request_on_behalf.
fd1 employee request-grant alice fd1.codex-backend \
  --reason "Codex Code 公司订阅 enrollment" \
  --use-case "review-only access for vibe-coding sessions"
shell
# Same call, raw HTTP (what the fd1 CLI actually does).
curl -X POST https://my.fluxdesk.net/mcp \
  -H "Authorization: Bearer flux-tools-EXAMPLE…" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "create_team_support_request_on_behalf",
      "arguments": {
        "subject_email": "[email protected]",
        "catalog_slug": "fd1.codex-backend",
        "reason": "Codex Code 公司订阅 enrollment",
        "use_case": "review-only access for vibe-coding sessions"
      }
    }
  }'
What the fd1 CLI runs under the hood — for porting to your own orchestrator.
2

Admin approves in the FluxDesk UI

Admin opens /team-support 待审批✓ 审批通过. FluxDesk sets request.status = "approved" and emits the team_support.approved outbound webhook (see outbound docs for HMAC verification). Today this webhook fires into the void — fd1's receiver isn't shipped yet.

3

Admin runs `fd1 employee dispatch` (manual bridge)

fd1 looks up the approved request, maps its catalog_slug to a backend command, and kicks off the matching action — for Codex/Claude this is an OAuth device-auth flow on the admin's Mac. On success, fd1 emits a fd1.<x>.enabled event back into the employee's inbox with usage instructions.

shell
# Step 3 · MANUAL bridge (current MVP).
# After admin clicks ✓ 审批通过 at /team-support, fd1 dispatch:
#   - looks up the approved request by id
#   - maps catalog_slug → backend command
#   - kicks off the OAuth device-auth flow on the admin's Mac
#   - on success, emits fd1.<x>.enabled back into FluxDesk inbox
fd1 employee dispatch <request_id>

# Examples per tier:
fd1 codex login alice         # tier 1 — Codex
fd1 claude login alice        # tier 2 — Claude
fd1 employee ssh-grant alice  # tier 3 — fluxdeskone SSH
4

fd1 emits the inbox-ready event

After the backend command succeeds, fd1 hits /api/v1/events with the employee's personal inbound token (claimed once via /api/v1/tokens/claim; same email → same token until rotated, so replay-safe).

shell
# After OAuth success, fd1 emits a fd1.<x>.enabled event back into
# FluxDesk so alice gets an inbox notification with usage instructions.
curl -X POST https://my.fluxdesk.net/api/v1/events \
  -H "Authorization: Bearer flux-in-pers-EXAMPLE…" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "fd1.codex.enabled",
    "title": "Codex Code 公司订阅已开通",
    "body": "你已加入公司 OpenAI Codex 订阅。终端运行 codex 即可。",
    "tone": "positive"
  }'

Revoke flow

Admin runs fd1 employee revoke → MCP revoke_catalog_approval → FluxDesk marks the approval revoked, logs the audit row, and emits team_support.withdrawn. Once the v0.20.x webhook receiver lands, fd1 tears down the source system automatically (e.g. fd1 codex logout). Today the admin runs the matching logout manually.

shell
# Off-board · admin runs fd1 revoke.
# Under the hood this calls FluxDesk MCP revoke_catalog_approval.
fd1 employee revoke alice fd1.codex-backend

# Current MVP: webhook receiver not yet shipped, so admin runs the
# matching backend logout manually after revoke records the audit row.
fd1 codex logout alice

Event namespace

fd1 emits these 11 event types back into FluxDesk inbox via /api/v1/events. Namespace pattern is fd1.<entity>.<action> past-tense.

  • fd1.account.onboarded

    new hire signal accepted

  • fd1.account.offboarded

    termination signal accepted

  • fd1.codex.enabled

    Codex login OK

  • fd1.codex.disabled
  • fd1.claude.enabled

    Claude Code login OK

  • fd1.claude.disabled
  • fd1.ssh.granted

    bastion key authorized

  • fd1.ssh.revoked
  • fd1.repo.created
  • fd1.repo.collaborator_added
  • fd1.repo.archived

fd1 as a reference implementation

fd1 is the canonical worked example for Mode B (admin orchestrator + MCP request-on-behalf). If you're wiring your own provisioner, copying fd1's shape is the fastest path: one service-account tools token, MCP for the write path, outbound webhook for fan-out, inbound events for the user-facing follow-up.

This recipe is maintained in collaboration with fd1. Updates land via PR — or via the FluxDesk team mirroring fd1's own docs/fd1-for-fluxdesk-team.md when fd1 publishes a new version. Catalog slugs and event types above are canonical: fd1 reviews this page when their backend changes.

Have a similar setup? We're happy to add your recipe here. [email protected]