When building Forge apps, sooner or later you’ll want to integrate with an external system — maybe for monitoring, data synchronization, or automation.
But the moment you call an external API using fetch(), your app loses the Runs on Atlassian badge.
This article shows how to design such an integration without any egress — meaning the Forge app never sends data outside Atlassian Cloud — and still communicates securely with an external backend.
The full demo project is available on GitHub:
Forge Health Monitor
The Architecture
The solution is based on two key capabilities that Atlassian Forge provides.
1. Safe navigation to external resources via router.navigate
Forge allows navigation to external pages using the @forge/bridge API:
import { router } from "@forge/bridge";
await router.navigate(registrationUrl);
When this happens, Forge automatically shows a security confirmation dialog, warning the user that they’re leaving the Atlassian environment.
Importantly, this does not require any permissions in your manifest.yml.
The key idea is that during this redirect, the app passes non-sensitive contextual data to the external backend, such as:
• cloudId — the unique tenant identifier (used to separate data by tenant on the external backend)
• accountId — the Atlassian account of the user (may be shared across multiple tenants)
• triggerUrl — a static web trigger endpoint unique to each tenant (unauthenticated by default, so custom authorization logic must be implemented)
• callbackUrl — the Forge page to return
This pattern can also be extended to support OAuth authorization flows (Google, Microsoft, or Keycloak).
2. Static Web Triggers for inbound communication
Static Web Triggers are the second key mechanism.
They allow external services to send HTTP requests into Forge — and doing so does not violate the Runs on Atlassian requirement, because the call direction is inbound, not outbound.
Web triggers don’t provide built-in authentication, so you must implement it yourself.
In this example, authentication is done using Ed25519-signed requests — it’s a minimal working approach, though it could be further improved.
What Forge Health Monitor Application Does
Forge Health Monitor is a monitoring solution that allows you to track the health status of external services directly from your Jira instance. Here's what it does:
Core Functionality:
- Monitors External Services - Continuously checks if your external APIs, websites, or services are running
- Real-time Status Display - Shows current health status (ALIVE/DOWN) for all monitored services
- User-friendly Interface - Simple Jira global page where you can view all your service statuses
- Automatic Updates - Refreshes status every 30 seconds without manual intervention
Here’s how it works conceptually:
How to Run the Example
-
Clone the repository
git clone https://github.com/vzakharchenko/Forge-Health-Monitor cd Forge-Health-Monitor
-
Install dependencies
npm install
-
Register the app in your Atlassian Developer Console
forge register
-
Start an ngrok tunnel on port 8080 — this will expose your custom backend:
ngrok http 8080 # Note the HTTPS URL (e.g., https://abc123.ngrok.app)
-
Set the ngrok URL as a Forge environment variable
forge variables set BACKEND_URL https://abc123.ngrok.app
-
Deploy the Forge app
forge deploy
-
Install it into your Jira instance
forge install
-
Start the custom backend
cd ./customBackend npm install npm run start
The app and backend are now running — open your Forge app in Jira and test the flow!
Exploring the App
- Open your Jira instance and launch the Forge app
- Click “Add Service”
- Confirm navigation by clicking “Continue” in the system dialog
- Enter any publicly available health check URL that returns HTTP 200 (no authentication required).
Only http and https URLs are accepted in this demo for simplicity.
- Click Continue, and you’ll return to the Forge app.
You’ll see the new service in the list — the backend will now periodically (every 5 minutes) check the service’s availability.
Result
With this setup, we successfully integrated an external service without violating Runs on Atlassian.
All outbound requests are performed by the external backend, while Forge remains completely isolated and only receives signed updates through web triggers.
Top comments (0)