Make your app embeddable
Last updated: 2 July 2026
Honeybase tasks can embed pages from your internal tools directly in the task's full view. Whether a page can be embedded is controlled by the embedded app, not by Honeybase: browsers enforce the app's own framing and cookie policies. If a page shows up blank ("refused to connect") or asks you to log in inside the frame, the app needs the two changes below. They are the same for every stack; jump to your framework or platform for the exact snippet.
The two universal requirements
1. Allow framing from Honeybase. Most apps
send an X-Frame-Options: DENY (or
SAMEORIGIN) header, which makes browsers silently
refuse to render the page in an iframe. Replace it with a Content-Security-Policy that
allows Honeybase explicitly:
Content-Security-Policy: frame-ancestors 'self' https://app.honeybase.ai
Remove any X-Frame-Options header for the pages you
want to embed (frame-ancestors supersedes it in
modern browsers, but older ones may still honor the stricter header). This keeps
clickjacking protection intact — only the origins you list can frame the app.
2. Send session cookies in an iframe. Even with
framing allowed, browsers only send your app's session cookie inside a cross-site
iframe when the cookie is marked
SameSite=None; Secure. With the common default
(SameSite=Lax) users appear logged out inside the
frame even though they are logged in a tab away. Your app must be served over HTTPS:
SameSite=None requires
Secure, and Honeybase only embeds
https:// URLs.
Framework examples
Django (and Django admin)
Django enables XFrameOptionsMiddleware by default
and uses SameSite=Lax cookies. In
settings.py:
# Stop sending X-Frame-Options: remove this middleware
# (or exempt specific views with @xframe_options_exempt)
MIDDLEWARE = [
# "django.middleware.clickjacking.XFrameOptionsMiddleware",
...
]
# Allow Honeybase as a frame ancestor (using django-csp)
CONTENT_SECURITY_POLICY = {
"DIRECTIVES": {
"frame-ancestors": ["'self'", "https://app.honeybase.ai"],
},
}
# Send session + CSRF cookies inside the iframe
SESSION_COOKIE_SAMESITE = "None"
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = "None"
CSRF_COOKIE_SECURE = True
Ruby on Rails
# config/application.rb — stop sending X-Frame-Options
config.action_dispatch.default_headers.delete("X-Frame-Options")
# config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |policy|
policy.frame_ancestors :self, "https://app.honeybase.ai"
end
# config/initializers/session_store.rb — iframe cookies
Rails.application.config.session_store :cookie_store,
key: "_myapp_session", same_site: :none, secure: true
Express / Node.js (helmet)
app.use(helmet({
frameguard: false, // stop sending X-Frame-Options
contentSecurityPolicy: {
directives: {
frameAncestors: ["'self'", "https://app.honeybase.ai"],
},
},
}));
app.use(session({
cookie: { sameSite: "none", secure: true },
// ...
}));
Spring Boot (Spring Security)
http.headers(headers -> headers
.frameOptions(frame -> frame.disable()) // stop X-Frame-Options
.contentSecurityPolicy(csp -> csp.policyDirectives(
"frame-ancestors 'self' https://app.honeybase.ai")));
# application.properties — iframe cookies
server.servlet.session.cookie.same-site=none
server.servlet.session.cookie.secure=true
ASP.NET Core
app.Use(async (context, next) =>
{
context.Response.Headers.Remove("X-Frame-Options");
context.Response.Headers.Append("Content-Security-Policy",
"frame-ancestors 'self' https://app.honeybase.ai");
await next();
});
builder.Services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
Laravel / PHP
// config/session.php — iframe cookies
'same_site' => 'none',
'secure' => true,
// Add the framing header in a middleware (and make sure your web
// server is not adding X-Frame-Options — see the proxy section)
$response->headers->set('Content-Security-Policy',
"frame-ancestors 'self' https://app.honeybase.ai");
Or fix it at the reverse proxy
If you would rather not touch the application (or the header is being added by the web server itself), you can strip and set the headers at the proxy for just the paths you want to embed. Nginx:
location /backoffice/ {
proxy_pass http://app_upstream;
proxy_hide_header X-Frame-Options;
add_header Content-Security-Policy
"frame-ancestors 'self' https://app.honeybase.ai" always;
}
Apache (mod_headers):
Header always unset X-Frame-Options
Header always set Content-Security-Policy \
"frame-ancestors 'self' https://app.honeybase.ai"
Cookie attributes still come from the application, so the
SameSite=None; Secure change usually has to happen
in the app config either way.
Hosted platforms
- Retool — standard Retool apps restrict framing and third-party cookies, so embedding requires Retool's own embedding support (Retool Embed, or public apps for content that does not need authentication). See Retool's documentation on embedding for your plan; once Retool serves the app with permissive framing, it works in Honeybase like any other page.
-
Grafana — set
[security] allow_embedding = trueandcookie_samesite = none(withcookie_secure = true) ingrafana.ini, or use publicly shared dashboards. - Metabase — enable embedding under Admin → Settings → Embedding. Public links and signed static embeds work without login; full interactive embedding is a paid Metabase feature.
- Other SaaS tools — search the vendor's docs for "embedding" or "iframe". If the tool offers no embedding option, its servers will keep refusing to be framed and the open-in-new-tab button in Honeybase is the fallback.
Safari and third-party cookies
Safari blocks third-party cookies entirely (Intelligent Tracking Prevention), and other browsers are gradually restricting them. Even with the settings above, users on Safari may need to log in inside the frame, use the Storage Access API if your app supports it, or fall back to the open in new tab button next to the embedded page's URL bar in Honeybase.
How Honeybase embeds your page
- Only https:// URLs are accepted, everywhere a page can be set (task forms and workflow nodes).
- The iframe is sandboxed without
allow-top-navigation, so an embedded page can never navigate your Honeybase tab. - Honeybase sends
Referrer-Policy: no-referrer, so your task URLs are not exposed to the embedded app. - Your session with the embedded app stays between your browser and that app — Honeybase never sees or proxies its cookies or credentials.