Skip to content

Search these docs from your AI tool

  • Antigravity
    {
      "mcpServers": {
        "edisyl-docs": {
          "serverUrl": "https://docs.edisyl.com/mcp"
        }
      }
    }
  • Claude CodeCLI
    claude mcp add edisyl-docs https://docs.edisyl.com/mcp --transport http --scope user
  • CodexCLI
    codex mcp add --url https://docs.edisyl.com/mcp edisyl-docs
  • Cursor
    {
      "mcpServers": {
        "edisyl-docs": {
          "type": "http",
          "url": "https://docs.edisyl.com/mcp"
        }
      }
    }
  • Gemini CLI
    gemini mcp add --transport http edisyl-docs https://docs.edisyl.com/mcp
  • Goose
    {
      "extensions": {
        "edisyl-docs": {
          "enabled": true,
          "name": "edisyl-docs",
          "type": "streamable_http",
          "uri": "https://docs.edisyl.com/mcp",
          "envs": {},
          "env_keys": [],
          "headers": {},
          "description": "",
          "timeout": 300,
          "bundled": null,
          "available_tools": []
        }
      }
    }
  • JetBrains AI Assistant
    {
      "mcpServers": {
        "edisyl-docs": {
          "type": "http",
          "url": "https://docs.edisyl.com/mcp"
        }
      }
    }

    Paste into Settings → Tools → AI Assistant → Model Context Protocol → Add → As JSON. Direct file writing isn’t supported — JetBrains stores this per-version as XML.

  • Junie (JetBrains)
    {
      "mcpServers": {
        "edisyl-docs": {
          "url": "https://docs.edisyl.com/mcp"
        }
      }
    }
  • OpenCode
    {
      "mcp": {
        "edisyl-docs": {
          "type": "remote",
          "url": "https://docs.edisyl.com/mcp"
        }
      }
    }
  • VS CodeCLI
    code --add-mcp '{"name":"edisyl-docs","type":"http","url":"https://docs.edisyl.com/mcp"}'
  • Windsurf
    {
      "mcpServers": {
        "edisyl-docs": {
          "serverUrl": "https://docs.edisyl.com/mcp"
        }
      }
    }

    Supports both stdio and native HTTP connections.

Authentication

The platform authenticates users through its own auth service — a GoTrue deployment (mono-auth) that this chart always runs alongside the applications, with its own database. There is no external auth project to point at and no switch to turn it on: edisyl.auth.enabled defaults to true, and the render refuses anything else while the API or the web application runs.

Users sign in with SAML through your identity provider, and nothing else. Email, phone and anonymous sign-in are pinned off, and no social provider is configured — Google sign-in was removed in chart 0.46.0. Turning SAML off would leave no way in at all, so the render refuses that too.

The identity provider your users sign in through — the deployment owner’s IdP — is declared in values, under deploymentIdp. The chart refuses to render without it. The configurator’s Single sign-on step asks for it and writes this block.

deploymentIdp:
# Exactly one of metadataUrl or metadataXml.
metadataUrl: "https://idp.example.com/app/saml/metadata"
# The email domains that sign in through this IdP.
domains: [example.com]

Exactly one metadata source. Set metadataUrl or metadataXml — the configurator’s “IdP metadata URL” or “IdP metadata XML” — never both and never neither:

  • metadataUrl must be HTTPS with a host. A URL lets the auth service pick up an IdP’s overlapping certificate rotation without a redeploy; a hard cutover still needs one. Whoever serves that URL can change the IdP’s signing certificates at any time, so use a URL only when it is the IdP vendor’s own.

  • metadataXml is the metadata document itself, for an IdP that publishes a file rather than a URL. Keep it under about 120 KB — past that the Job that registers it cannot start — and use a block scalar:

    deploymentIdp:
    metadataXml: |
    <?xml version="1.0" encoding="UTF-8"?>
    <md:EntityDescriptor ...>
    ...
    </md:EntityDescriptor>
    domains: [example.com]

The routed domains. domains (“Email domains routed to it”) is a non-empty list of bare email domains — example.com, with no @ or scheme. A user who types an address on one of them is sent to this IdP, and everyone it signs in on these domains joins the deployment owner’s organization. The list is exact: a domain removed here is released from the provider on the next deploy, so when you adopt an existing registration, list all of its domains. The addresses in bootstrap.adminEmails must be on one of them, or the owner row they create is one nobody can sign in as.

bootstrap.enabled must stay true. The Job that registers the IdP renders only with bootstrap on, so the render refuses deploymentIdp with it off.

Mock SAML, which signs in any address it is asked for, is refused unless both env and config.appEnv are local. It is for a throwaway local cluster only.

Create a SAML application in your IdP before the install, with these two endpoints on the auth service’s public host:

Entity ID and SP metadata https://auth.<your-domain>/auth/v1/sso/saml/metadata
ACS (reply) URL https://auth.<your-domain>/auth/v1/sso/saml/acs

An IdP that imports SP metadata can take both from the first URL. Make sure the assertion carries the user’s email address. Then take the IdP’s own metadata from the application: Okta and Entra ID publish a metadata URL for it; Google Workspace publishes XML only, so it goes in metadataXml.

The cluster has to reach a metadata URL: the registration Job fetches it from inside the cluster, so egress to the IdP’s host must be open.

The chart registers the IdP for you. A Job named edisyl-idp-reconcile-<hash> registers deploymentIdp with the auth service, updating an existing registration in place (matched by entity ID) so its provider id survives, and records that provider id in the database. The API trusts owner sessions only from the provider recorded there, so declaring the IdP in values is the whole setup — there is no id to copy back into values and no registration command to run.

The Job’s name carries a hash of its spec, so it runs again whenever the spec changes: a change to deploymentIdp, the API image, the chart version, or any value in edisyl-config. An unchanged release re-applies the finished Job as a no-op. To run it again without a change — after rebuilding the auth database, say — delete the Job and upgrade.

A failed registration does not fail helm install. It is a plain Job, not a hook; on a fresh install it retries until the migrations, the owner organization and the auth service exist. Wait for it to complete, and read the provider id from the last lines of its log:

Terminal window
kubectl -n edisyl wait --for=condition=complete job -l app=edisyl-idp-reconcile --timeout=15m
kubectl -n edisyl logs -l app=edisyl-idp-reconcile --tail=20

On upgrades, helm upgrade --wait --wait-for-jobs makes a failed registration fail the upgrade, and it is safe there because migrations run before the upgrade — see Upgrading. Under Argo CD a failed registration leaves the Application Degraded while the sync itself completes; delete the Job and self-heal recreates it.

The auth service does not use the application database. It gets its own — a login role, a database it owns, and the connection secret both the deployment and its prep hook read. The chart provisions all three from the bundled CloudNativePG cluster when edisyl.auth.database.create says so, which by default follows cnpg.enabled.

With your own PostgreSQL, you provision that database and role and point edisyl.auth.database.secretName at a Secret holding its connection URI — see Using your own infrastructure.

Credentials are split by who mounts them, deliberately — a browser-facing server has no business holding a credential that can register an identity provider.

Secret Holds Mounted on
edisyl-auth What the service signs with: GOTRUE_JWT_KEYS, GOTRUE_JWT_SECRET and GOTRUE_SAML_PRIVATE_KEY The auth pod alone
edisyl-auth-client AUTH_ANON_KEY — the consumer side, what the apps verify against The application pods
edisyl-auth-admin AUTH_ADMIN_TOKEN, the credential for the auth service’s admin API The API and the edisyl-idp-reconcile Job

No URL appears in any of them. Where the auth service lives is derived into the platform config from the hostname this chart publishes for it, so the address and the service cannot disagree.

GOTRUE_JWT_KEYS is the service’s key set, and the chart cannot generate it — Helm cannot produce an EC keypair. The API verifies every user token as ES256, against the key set the auth service publishes at /auth/v1/.well-known/jwks.json, with the issuer pinned to that same address.

A service configured with only a symmetric secret issues HS256 tokens with no issuer claim, and then every authenticated request fails with 401 Invalid or expired token — sign-in included. It reads as a credential problem; it is an algorithm one.

Secrets and signing keys has two ways to mint all of them, and explains why the key set needs both an EC entry and a verify-only HS256 one. They are yours alone — we never generate or hold signing material for a self-hosted deployment.

Sign-in is through the web application, served at edisyl.<config.domain> unless you set an explicit edisyl.edisyl.ingress.host — for example, to put it on the apex instead.

Start at the web application’s /login, never from the IdP. Type your email address first: the SSO button stays disabled until the field holds a domain, and that domain is what routes to your IdP. An IdP-initiated sign-in never completes a session, which looks like a failure when it is the wrong entry point.

The first account that matters is the one in bootstrap.adminEmails: the seed creates an owner row for that address, and it is what gates creating data sources and other owner-level objects.

If the address you sign in with does not match one in bootstrap.adminEmails, you get an owner row nobody can log in as, and your own account owns only its personal workspace. The seed job is idempotent — adding the address and re-running helm upgrade links the existing row rather than duplicating it.

Report incorrect code

Please provide a detailed description of the incorrect code.