Skip to content

Security Policy

Riffle is a bidirectional Confluence ↔ GitHub documentation sync app built on Atlassian Forge, Atlassian’s hosted compute platform. This document describes how Riffle handles security across architecture, authentication, data, access control, secrets, network egress, logging, and vulnerability response.

Riffle runs entirely on Atlassian Forge infrastructure. There are no self-hosted servers, databases, or cloud resources managed by Coral Labs.

  • Compute: Forge serverless functions (Node.js 24, arm64, 256 MB memory limit)
  • Storage: Forge Key-Value Store (KVS) — encrypted at rest by Atlassian
  • Frontend: Forge UI Kit (@forge/react), rendered inside the Confluence iframe sandbox
  • Webhooks: Forge web triggers receive GitHub push events; Confluence events are delivered via Forge triggers

Because the entire runtime is Forge-hosted, Riffle inherits Atlassian’s SOC 2, ISO 27001, and data residency controls. See Atlassian’s Forge security documentation for details.

Riffle uses Forge OAuth 2.0 scopes — no user credentials are stored. The app operates under the principle of least privilege with the following scopes:

ScopePurpose
read:page:confluence / read:confluence-content.allRead page content for sync
write:page:confluence / write:confluence-contentCreate/update pages from GitHub
delete:page:confluenceRemove pages deleted in GitHub
read:confluence-userIdentify actors to prevent sync loops
read:space:confluenceEnumerate spaces for configuration
storage:appPersist configuration in Forge KVS

Riffle authenticates to GitHub as a GitHub App using RS256-signed JWTs and short-lived installation tokens (1-hour expiry). Private keys are stored as Forge environment variables (base64-encoded).

  • Forge KVS: Sync configuration (repo name, branch, space key, path mappings), cached GitHub installation tokens, and the app’s own Atlassian account ID. No page content is persisted in KVS.
  • In transit: Page content passes through Forge functions during sync operations (Confluence → GitHub or GitHub → Confluence). Content is held in memory only for the duration of the function invocation.
  • User credentials or passwords
  • Confluence page content at rest (beyond Confluence itself)
  • GitHub repository content at rest
  • Personal data beyond Atlassian account IDs used for loop detection

All stored data resides in the Forge KVS within the customer’s Atlassian data residency region. Riffle does not replicate data to external storage.

  • Space-level configuration: Riffle is configured per Confluence space by space admins via the Space Settings panel. Only users with space admin permissions can configure sync.
  • No global admin required: Riffle does not require Confluence site-admin privileges to operate.
  • Actor filtering: Riffle detects its own writes (via Atlassian account ID comparison) to prevent infinite sync loops. Changes made by the app are attributed to the app identity, not impersonated users.
SecretStorageRotation
GitHub App private keyForge environment variable (base64-encoded)Manual rotation via forge variables CLI
GitHub App ID / Webhook secretForge environment variablesManual rotation
Forge API credentialsManaged by AtlassianAutomatic

No secrets are committed to source control. Forge environment variables are encrypted at rest by Atlassian.

Riffle’s outbound network access is restricted by Forge’s external.fetch allowlist:

  • api.github.com — the only permitted external domain

All other outbound connections are blocked by the Forge runtime. Riffle cannot contact arbitrary external services.

  • Forge runtime logs: Function invocations, errors, and performance metrics are available via Atlassian’s Forge logging infrastructure (forge logs).
  • No external log shipping: Riffle does not send logs to external services.
  • Audit trail: Confluence maintains its own audit log of page changes. GitHub maintains commit history. Together, these provide a full audit trail of synced content.

To report a security vulnerability, email security@trusthumankind.org. We aim to acknowledge reports within 48 hours.

  1. Triage — Assess severity and impact within 48 hours of report
  2. Fix — Develop and test a patch
  3. Deploy — Push fix via Forge deployment pipeline
  4. Disclose — Notify reporter and, if applicable, affected customers
  • Dependencies are reviewed with each release
  • Forge’s Node.js runtime is maintained and patched by Atlassian
  • The converter pipeline (packages/converter) uses a minimal dependency set to reduce supply-chain risk

Riffle is distributed through the Atlassian Marketplace and complies with Atlassian’s Marketplace security requirements, including:

  • Forge-hosted (no self-managed infrastructure)
  • Scoped permissions (least privilege)
  • No storage of user credentials
  • Allowlisted external network access only