List icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Log icon
Schedule icon

Confluence Stale Documentation Audit Sentinel

List Confluence pages, alert Slack on documentation older than your retention threshold, and log the result for platform and docs teams.

Categories
Business

A Confluence space accumulates runbooks, onboarding guides, and incident postmortems that nobody revisits once the page stops being urgent. Confluence has no built-in schedule that flags a page nobody has touched in months, so outdated instructions sit at the top of search results looking exactly as current as the page updated yesterday. This blueprint reads each page's real last-edit timestamp and reports what has actually gone stale, not a guess.

This blueprint was created by Mohit Jeswani.

How it works

  1. list_pages (io.kestra.plugin.confluence.pages.List) fetches current and archived pages, optionally scoped to space_ids, each with its version metadata. Read-only; nothing in Confluence is changed. allowFailure: true covers an API or auth error without failing the flow outright.
  2. evaluate (io.kestra.plugin.core.output.OutputValues) compares each page's versionInfo.createdAt (the timestamp of its latest edit, not when the page was first created) against stale_after_days, with a jq filter.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing scanned is stale.
    • alert: posts the count and titles to Slack.
  4. summary logs the count and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example an expired API token.

What you get

  • A real last-edit timestamp per page, not an assumption that an old page title means old content, and not the other way around.
  • The exact stale page titles in the Slack alert, not just a count.
  • A read-only check with zero risk of editing or archiving a real page.

Who it's for

  • Platform, docs, and knowledge-management teams who own a Confluence space and have no process catching a runbook or onboarding guide nobody has touched in a year.
  • Teams evaluating the Confluence plugin who want a worked example of pages.List used as a standing retention audit, distinct from this repo's existing Confluence blueprint, which writes a weekly recap page rather than auditing page age.

Why orchestrate this with Kestra

Confluence shows a page's last-modified date one page at a time; it does not compare that date across a whole space against a retention policy you declare, or notify anyone. Kestra keeps stale_after_days as a flow input, turns the scan into a Slack page naming the actual stale titles, and keeps a full execution history of every run.

Prerequisites

  • A Confluence Cloud site with a user account and an Atlassian API token.
  • At least one page in the target space(s) old enough to confirm the filter logic against.
  • A Slack incoming webhook URL.

Confluence is a hosted Atlassian Cloud product with no official standalone Docker image, so list_pages cannot be exercised against a local container; validate against a real, low-traffic space or Atlassian's free Confluence tier first.

Secrets

  • CONFLUENCE_USERNAME: the Confluence account email used by list_pages. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_CONFLUENCE_USERNAME.
  • CONFLUENCE_API_TOKEN: the Atlassian API token for that account. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_CONFLUENCE_API_TOKEN.
  • SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Default Purpose
space_ids [] Spaces to scan; empty scans every space the account can see
limit 100 Max pages fetched per run (API max 250)
stale_after_days 180 Days since last edit past which a page is reported stale
max_stale_count 1 Stale-page count that triggers the Slack alert

Outputs

  • {{ outputs.list_pages.children }}: every scanned page (title, markdown, versionInfo, rawResponse).
  • {{ outputs.evaluate.values.stale_count }} / .stale_titles: how many pages are stale and their titles, semicolon-joined.
  • {{ outputs.evaluate.values.severity }}: OK, STALE_DOCS_FOUND, or CRITICAL.

Pitfalls

  • versionInfo.createdAt is the latest edit timestamp, not the page's original creation date; a page created five years ago but edited last week is correctly not stale.
  • limit bounds how many pages list_pages even considers per run (API max 250); a space larger than that needs cursor-based pagination this blueprint does not yet implement, so a very large space is only partially scanned per run.
  • The default status filter on pages.List covers current and archived pages; deleted and trashed pages are never scanned, which is correct for a retention audit since both are already effectively gone.

Quick start

  1. Add the CONFLUENCE_USERNAME, CONFLUENCE_API_TOKEN, and SLACK_WEBHOOK_URL secrets.
  2. Set confluence_server_url and, optionally, space_ids to your real site.
  3. Run the flow manually and confirm summary logs a count.
  4. Raise stale_after_days above every scanned page's age, or lower it below a known old page's age, to confirm both compliant and alert fire correctly.
  5. Enable the weekly trigger once stale_after_days matches your real retention policy.

How to extend

  • Add pagination with the cursor property to scan a space larger than 250 pages in one run.
  • Chain io.kestra.plugin.confluence.pages.Update on each stale page to prepend a "needs review" label to its title, gated behind an explicit confirm_tag input so tagging never runs by accident.
  • Group stale_titles by spaceId from rawResponse in a downstream task to route each space's stale pages to that space's own owning team.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.