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.
Architecture
Section titled “Architecture”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.
Authentication
Section titled “Authentication”Confluence (Atlassian) Side
Section titled “Confluence (Atlassian) Side”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:
| Scope | Purpose |
|---|---|
read:page:confluence / read:confluence-content.all | Read page content for sync |
write:page:confluence / write:confluence-content | Create/update pages from GitHub |
delete:page:confluence | Remove pages deleted in GitHub |
read:confluence-user | Identify actors to prevent sync loops |
read:space:confluence | Enumerate spaces for configuration |
storage:app | Persist configuration in Forge KVS |
GitHub Side
Section titled “GitHub Side”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).
Data Handling
Section titled “Data Handling”What Riffle Stores
Section titled “What Riffle Stores”- 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.
What Riffle Does NOT Store
Section titled “What Riffle Does NOT Store”- 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
Data Residency
Section titled “Data Residency”All stored data resides in the Forge KVS within the customer’s Atlassian data residency region. Riffle does not replicate data to external storage.
Access Control
Section titled “Access Control”- 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.
Secrets Management
Section titled “Secrets Management”| Secret | Storage | Rotation |
|---|---|---|
| GitHub App private key | Forge environment variable (base64-encoded) | Manual rotation via forge variables CLI |
| GitHub App ID / Webhook secret | Forge environment variables | Manual rotation |
| Forge API credentials | Managed by Atlassian | Automatic |
No secrets are committed to source control. Forge environment variables are encrypted at rest by Atlassian.
Network Egress
Section titled “Network Egress”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.
Logging and Monitoring
Section titled “Logging and Monitoring”- 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.
Vulnerability Response
Section titled “Vulnerability Response”Reporting
Section titled “Reporting”To report a security vulnerability, email security@trusthumankind.org. We aim to acknowledge reports within 48 hours.
Response Process
Section titled “Response Process”- Triage — Assess severity and impact within 48 hours of report
- Fix — Develop and test a patch
- Deploy — Push fix via Forge deployment pipeline
- Disclose — Notify reporter and, if applicable, affected customers
Dependency Management
Section titled “Dependency Management”- 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
Marketplace Compliance
Section titled “Marketplace Compliance”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