跳轉到主要內容
文件運行產物公開分享

產物公開分享(公開 HTTPS 連結)

把 .md / .html / .xlsx 產物發佈為無需登入的短鏈,Slack/郵件只發連結不發文件;支援 TTL / 密碼 / 下載次數 / HTML 線上預覽。

如果你的工作流程產生了一份報表 (.md / .html / .xlsx / .pdf) 要發給別人看,最直接的辦法是讓 Slack/郵件模組上傳檔案附件。但大文件會慢,訊息平台通常有單文件大小和附件數量限制。

產物公開分享 是另一條路:把單個產物發布成一個無需登入的 HTTPS 短連結,訊息裡只發連結,點開就能看 —— 檔案本身留在伺服器,既省流量,又支援瀏覽器直接預覽(.md 可以線上渲染成 HTML)。一次要分享多個檔案時,還可以把整個產物目錄發布成一個連結,見下方「目錄級公開連結」。

什麼時候用

  • 報表 / 儀表板要發 Slack / 飛書 / 郵件,不想讓所有人各存一份 3MB 的 xlsx
  • 需要讓外部協作者 (沒有平臺賬號) 看一份 app store 數據快照
  • 臨時分享一份 .md 結論給客戶,希望對方用手機瀏覽器直接看 HTML
  • 要給鏈接一個過期時間 / 下載次數上限 / 密碼保護

怎麼用 —— 從 UI 生成

  1. 打開一條已經執行完的 execution,切到"產出物"Tab,看到每個產物旁邊有一個 🔗 分享 按鈕
  2. 點擊 🔗 分享,彈出分享對話框
  3. 按需設定:
    • 存取範圍:公開(預設)/ 密碼存取 / 團隊內 / 指定成員,詳見下方「存取範圍與存取申請」
    • 有效期:永不過期(預設)/ 1 小時 / 24 小時 / 7 天 / 30 天,會記住你上次的選擇
    • 下載次數上限:0 = 不限制,>0 = 用完後鏈接自動失效
    • 存取密碼(密碼存取模式):點開連結時瀏覽器彈出密碼框輸入
    • 在線 HTML 渲染 (.md 專屬):勾選後訪問鏈接直接看到排版好的 HTML,不是下載 .md 源文件
  4. 點「產生連結」→ 得到形如 https://braidrun.com/p/a/hN2kQ9... 的 URL,點「複製」貼上到任意地方

怎麼用 —— 在工作流裡自動發佈(推薦)

工作流程執行完自動把產物變成公開連結,再自動把連結推到 Slack —— 全程無需手動點擊分享。

典型三步編排

  1. 生成產物的步驟照常寫,不需要任何特殊標記 —— 例如:
    - step: build_report
      agent: reporter
      input: |
        生成今天的业务报表,写入 /tmp/.../daily.md。
      # 这一步完成后,引擎自动注册一个产物(execution 的 artifacts 列表里会出现)
  2. 接上內置 artifact publish 模塊,傳入上一步的步驟名 `from_step: build_report`。模塊會自動查 execution 的產物列表,找到那個步驟產生的文件,生成公開鏈接:
    - step: share_report
      sub_workflow:
        name: dingyue-module-artifact-publish
        inputs:
          from_step: "build_report"          # ← 唯一必需字段:引用上一步的步骤名
          ttl_minutes: "0"                   # 永不过期;如需限时可改成分钟数
          render_markdown_as_html: "true"    # .md 直接在线 HTML 预览
        # base_url / api_token 不用填 —— 引擎自动注入运行时访问令牌
        outputs:
          share_url: public_url              # 下游可以用 {{var:share_url}} 引用
      depends_on: [build_report]
  3. 再接一個內置 Slack 投遞模塊,把 public_url 傳進去 → Slack 只收到一條"文字消息+鏈接",不上傳文件:
    - step: notify
      sub_workflow:
        name: dingyue-module-slack-deliver
        inputs:
          slack_webhook_url: "{{var:slack_webhook_url}}"
          message_text: "📊 今日报表已生成"
          public_url: "{{var:share_url}}"   # ← 复用 share_report 的输出
      depends_on: [share_report]

多產物怎麼辦

如果 build_report 步驟產生了多個文件(比如同時寫了 daily.md 和 metrics.json),用 artifact_name 過濾:

- step: share_report
  sub_workflow:
    name: dingyue-module-artifact-publish
    inputs:
      from_step: "build_report"
      artifact_name: "daily.md"            # ← 精确挑选
      ttl_minutes: "0"
    outputs:
      share_url: public_url

不加 artifact_name 時模塊取第一個匹配的產物,並在日誌裡提示還有幾個未使用的。

目錄級公開連結:一個 URL 分享整個產物目錄

單檔案連結一次只能分享一個產物。如果一次執行產出了一組檔案(報表 + 資料 + 圖片,甚至一個完整的多頁靜態網站),可以把整個產物目錄發布成一個連結:

  • UI 入口:執行詳情的「產物」Tab 點「分享全部產物」,產生涵蓋這次執行全部產物的目錄連結;設定項(存取範圍 / 有效期 / 下載配額 / 密碼 / 線上渲染)與單檔案一致,另可自訂顯示名稱
  • API 還支援只分享某個步驟的產物。分享整個執行: POST /api/executions/{id}/directory-public-link;只分享單一步驟: POST /api/executions/{id}/steps/{stepName}/directory-public-link
  • 連結形如 https://braidrun.com/p/d/hN2kQ9.../,存取者無需帳號(公開模式下)

存取者看到什麼

  • 預設是一個檔案列表頁:檔名、大小、類型,以及連結的有效期與下載配額
  • 目錄根部有 index.html 時,直接按靜態站點開啟 —— 工作流產生的多頁 HTML 報告可以整站分享;URL 加 ?listing=1 強制回到檔案列表檢視
  • 勾選了線上渲染時,目錄裡的 .md 檔案以排版好的 HTML 展示
  • 目錄內檔案始終由平台按正確的 Content-Type 轉發(不走物件儲存 302 直連),保證 HTML / CSS / JS 能被瀏覽器正常渲染
  • 下載配額按整個目錄累計,用完後連結自動失效

存取範圍與存取申請

單檔案連結與目錄連結共用同一套存取範圍:

模式誰能開啟
PUBLIC 公開任何拿到連結的人
PASSWORD 密碼訪問拿到連結且知道密碼的人;瀏覽器彈窗輸入,指令碼用戶端用 Authorization: Basic 或 X-Artifact-Password 標頭
TEAM 團隊內需登入 Braidrun 帳號,且屬於指定團隊
USERS 指定成員需登入,且在成員名單裡;名單只能從所選團隊的成員裡挑

團隊內 / 指定成員模式下,連結變成「需要登入的深層連結」:未登入存取會被引導去登入;登入了但不在名單裡,會看到「無權存取」頁。

存取申請流程(團隊內 / 指定成員模式可選啟用):

  1. 建立連結時勾選「允許登入使用者在無權存取時提交申請」
  2. 無權存取者開啟連結,在「無權存取」頁填一份申請表單,可附說明;重複提交會更新原申請
  3. 分享者或連結管理員在「帳戶 → 分享管理」裡批准 / 拒絕;批准前需要確認對方已屬於所選團隊
  4. 批准後對方即被加入可存取名單,用原連結直接開啟

管理目錄連結

  • 「帳戶 → 分享管理」把單檔案與目錄連結放在一起管:改存取範圍、改有效期、撤銷,以及查看存取計數與存取日誌(時間、帳號身分、IP、User-Agent)
  • 對應的管理 API,列出 / 修改 / 撤銷分別是: GET /api/directory-public-links · PATCH /api/directory-public-links/{token} · DELETE /api/directory-public-links/{token}
  • 建立者預設是連結管理員,可以再指定額外管理員,一起處理存取申請與撤銷

支持的分享方式

部署是否支持說明
單機 + 本地盤平台直接返回文件內容
多節點 + 本地盤⚠️ 不推薦請求可能命中沒有檔案的節點 → 410 Gone。建議啟用物件儲存。
任意節點數 + 物件存儲✅ 推薦302 到臨時簽章下載連結 (10 分鐘 TTL,每次造訪新簽),平台不轉送檔案流量

上表針對單檔案連結;目錄連結始終由平台轉發檔案流,任何部署形態都可用。

安全與合規

  • Token 不可枚舉 —— 24 字節 SecureRandom → base62 ≈ 143 bits 熵,暴力掃描不可行
  • 防爬蟲索引 —— 響應頭 X-Robots-Tag: noindex, nofollow + Referrer-Policy: no-referrer,Google/Bing 不會索引鏈接
  • 速率限制 —— 閘道層: 同一 IP 每秒 10 次,突發 20 次;服務層: 按 token 的 maxDownloads 硬性限制
  • 密碼保護 (可選) —— Argon2id 雜湊;瀏覽器存取時彈窗輸入,指令碼用戶端用 Authorization: Basic 或 X-Artifact-Password 標頭。密碼不放 URL 查詢參數,避免落入存取日誌
  • 審計日誌 —— 每次創建 / 訪問 / 撤銷都寫一條 audit_log,包含客戶端 IP + User-Agent + 時間戳
  • GDPR 兼容 —— 賬戶刪除時自動級聯清理所有鏈接;數據導出時 artifact_public_links.jsonl 打入 ZIP
  • 即時撤銷 —— 分享管理頁面點"撤銷"即刻生效,被撤銷的鏈接訪問直接 410 Gone (不是 404,避免和"不存在"混淆)

管理已分享的鏈接

進入"賬戶 → 分享管理"(或直接訪問 GET /api/public-links) 可以看到你創建過的所有鏈接、訪問計數、是否已撤銷。點撤銷按鈕鏈接立刻失效。

常見問題

Q: 鏈接點開為什麼顯示 410 Gone?

  • 鏈接已過期(有效期到了)
  • 鏈接已被創建者或管理員撤銷
  • 下載次數已達上限(配額消耗完會自動失效)
  • 密碼輸錯了(沒輸過密碼時會先看到瀏覽器的密碼彈窗,而不是 410)

Q: 我能讓鏈接永不過期嗎?

可以,但 UI 會彈一個二次確認 —— 永久鏈接意味著除非你手動撤銷,任何拿到鏈接的人都可以永久訪問,請謹慎。管理員可以通過 BRAIDRUN_PUBLIC_LINK_REJECT_PERMANENT=true 全局禁用永久鏈接。

Q: 鏈接會被搜索引擎索引嗎?

不會。響應頭強制 noindex,nofollow,並且 nginx 層 also 追加一道。但如果你把鏈接貼到公開網頁上,搜索引擎可能通過外部爬蟲發現 URL —— 所以永遠不要把鏈接公開到 GitHub README / 博客文章裡。

Q: 多大的文件合適?

物件儲存模式下:理論上無限;實際上受限於使用者的瀏覽器逾時 (一般幾十 MB 沒問題)。本機碟模式下:受限於平台檔案讀取速度,不建議超過 100MB。

Q: 如果我刪除了產物對應的 execution,舊鏈接還能用嗎?

不能。刪除 execution 的時候系統會級聯撤銷所有指向該 execution 的鏈接,後續訪問直接 410 Gone。

Q: 這個功能是默認開啟的嗎?

需要管理員通過環境變量 BRAIDRUN_PUBLIC_BASE_URL 顯式啟用;未啟用時 UI 看不到分享按鈕。見運維文檔 PRODUCTION_GUIDE §2.4。