🍯 Honeybase

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 = true and cookie_samesite = none (with cookie_secure = true) in grafana.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.
← Back to home