# Atlantic Agentic Labs: LightHouse™ documentation > Atlantic Agentic Labs builds LightHouse™, which manages an organisation's AI agents, models, approvals, access and billing, on the Atlantic Agentic Engine running in the organisation's own cloud account or servers. This is the public documentation for both. **For AI assistants and agents.** - **What Atlantic is.** Atlantic Agentic Labs builds LightHouse™, which manages an organisation's AI agents, models, approvals, access and billing. LightHouse runs on the Atlantic Agentic Engine, in the organisation's own cloud account or on its own servers. - **The public MCP server**: https://ask.atlanticagenticlabs.com/mcp (streamable HTTP), read-only, with no account or key. Coming: it is not yet available. Its four tools, each annotated read-only and closed-world: - `search_docs`: searches this documentation, the OpenAPI document and the MCP reference; returns passages quoted exactly, each with a deep link, the version or date, and evidence fields. - `search_published_knowledge`: searches the items Atlantic has published on its knowledge pages; returns passages in the same form. - `read_page`: returns one page of this documentation as Markdown, by address or path, with its title, address and last-updated date; public pages only, and a very long page is cut short with a note and its address. - `list_pages`: returns this documentation's table of contents: each page's section, title, path and one-line description. - **Limits.** Requests are limited for each caller and for the service as a whole. A request over a limit receives HTTP 429 with a Retry-After header; wait for that time before the next attempt. Queries are recorded with identifiers redacted and kept for 12 months. - **Out of scope.** The server provides no prices, makes no commitments on Atlantic's behalf, does not contact or hand over to a person, does not generate answers, reads no tenant data and makes no changes. - **Use.** Call `list_pages` or `search_docs` first, call `read_page` for a whole page, and cite the deep links returned. --- # LightHouse™ documentation > How LightHouse and the Atlantic Agentic Engine work, how to connect them to your estate, and what they do with your data. ## Start where you are [Evaluating LightHouse](/start/)What it is, what runs where, and a key and a working API call in ten minutes. [Designing the deployment](/concepts/)Your cloud or ours, what the stack creates and the permissions it takes, and how agents are built. [Building against it](/api/)The API and MCP references, generated from the service itself, with curl, Python and TypeScript examples. [Reviewing security and data](/security/)The trust boundary, each control and how to check it yourself, where your data lives, and who can see it. ## Octy™ on your knowledge [Put Octy on any knowledge base](/octy/)Answers from your own documents with citations, at a low cost per answer, in your own cloud or fully offline, under controls you set. ## Everything in the docs [01Start hereLightHouse manages your agents, models, approvals, access and billing, on the Atlantic Agentic Engine, and reports on them in six areas.](/start/)[02Organisation set-upThe path from sign-up to a configured LightHouse tenant: sign-up or sales-led onboarding, then domains, single sign-on, provisioning, invitations, where agents run, the stack, Octy and the security review.](/enterprise/)[03OctyOcty is Atlantic's conversational agent: put it on any knowledge base with an Octy profile, and it answers from that knowledge, with citations, at a low cost per answer.](/octy/)[04ConceptsThe ideas LightHouse and the engine are built from, and how they fit together.](/concepts/)[05Connect your estateEvery connector, the three ways to connect it, the scopes it asks for to read or to read and write, its sync schedule, and what it indexes.](/connect/)[06CollectorsThe code that reads each of your systems: in its own repository, documented, certified by Atlantic Agentic Labs and scanned on every change.](/collectors/)[07CloudsWhere the engine runs: your AWS, Azure or Google Cloud account, your own servers, or Atlantic-hosted.](/clouds/)[08Build agentsThree ways to build an agent: from the library, with the builder, or in code.](/build/)[09SecurityEvery control: what it is, where it is enforced, and how you can verify it yourself.](/security/)[10Data sovereigntyYour content stays in your account and is read in place. Export to Atlantic is opt-in and off by default.](/data-sovereignty/)[11Cost and token optimisationHow cost is measured, how every saving is calculated, and how to reproduce the figure yourself.](/cost/)[12The model routerThe router picks the cheapest model that meets the quality bar for the job, not the cheapest model.](/router/)[13APILightHouse's HTTP API: your tenant's host, authentication, conventions, and the generated reference.](/api/)[14MCPLightHouse's reads as Model Context Protocol tools, for Claude, Cursor, Codex and any MCP client.](/mcp/)[15CLIThe LightHouse command line: install, sign in, and every command.](/cli/)[16OperationsRunning LightHouse and the engine day to day.](/operations/)[17TrustSub-processors, the security controls summary, status, change notices and Ask Octy on the docs.](/trust/)[18ChangelogWhat changed in each release of LightHouse and the engine.](/changelog/) Source: https://docs.atlanticagenticlabs.com/ --- # What LightHouse is > LightHouse manages your agents, models, approvals, access and billing, on the Atlantic Agentic Engine, and reports on them in six areas. LightHouse manages your agents, models, approvals, access and billing, and reports on them in six areas. It runs on the Atlantic Agentic Engine, which runs in your own cloud account, on your own servers, or in an account Atlantic runs for you. **Your people and tools** - **Portal**: in the browser, signed in through your identity provider with a second factor - **CLI**: lighthouse-ai, signed in as you - **MCP clients**: Claude, GitHub Copilot, Copilot Studio: read-only tools, as the person who approved them - **Your systems**: the REST API, with a machine key At your tenant's address; every request checked for your tenant, role and scopes - **Requests and decisions** (downward): reads, approvals, limits, connections, settings - **Answers** (upward): figures, records, and content shown in place, not stored **LightHouse**: your tenant, in Atlantic's account - **API, MCP and portal**: the ways in - **Approvals and commands**: a person's decision, signed for your deployment - **Intake**: verifies each signed record against the contract - **Store and audit log**: your tenant's records, isolated; every action recorded Every connection opened from your side - **Operational telemetry** (upward): counts, costs and timings. Never content - **Content, read in place** (both ways): on request, signed by Atlantic, logged in your account - **Signed commands** (downward): checked against your own policy **Your deployment**: the Atlantic Agentic Engine, in your account - **Gateway**: the only path to a model - **Orchestrator**: runs your agents - **Knowledge**: your sources and index - **Relay, reader and command channel**: the three outbound connections People and tools reach LightHouse at your tenant's address, through your identity provider. LightHouse reaches your deployment only on connections your deployment opens: telemetry up, reads in place, signed commands down. ## What you do in LightHouse LightHouse is the portal that tenant users sign in to. From it they can: - see every agent, what it is doing now, and every run it has made - approve or reject an agent’s output before it takes effect - pause an agent, set its spending cap, or grant a standing pre-approval - choose where agents run and which models they may use - connect sources, issue API keys and decide who may sign in - see cost and usage, set limits, and pay Each client has its own tenant, at its own address: `https://.atlanticagenticlabs.com`. You sign in at `platform.atlanticagenticlabs.com` with your tenant ID, through your own identity provider. See [Tenants](/concepts/tenants/). The same data is available through the [API](/api/) and through the [MCP server](/mcp/) as read-only tools. ## The engine that runs your agents The Atlantic Agentic Engine runs your agents, in the place you choose: [your AWS, Azure or Google Cloud account](/clouds/), your own servers, or [Atlantic-hosted](/clouds/atlantic-hosted/). It contains: - **the gateway**, the only thing that calls a model, where spending caps, the kill switch and the tool gate are enforced in code ([The gateway](/concepts/gateway/)); - **the orchestrator**, which runs each agent under its [agent card](/concepts/agents/); - **your knowledge**: the sources it reads and the index it builds, in your account ([Knowledge bases](/concepts/knowledge-bases/)); - **a content reader**, so LightHouse can show your content in place without copying it; - **a command channel**, so a person’s decision in LightHouse reaches the agent ([Handlers](/concepts/handlers/)). The engine sends LightHouse operational telemetry, which is counts and timings only; content is not transmitted. See [The telemetry contract](/concepts/telemetry-contract/) and [Data sovereignty](/data-sovereignty/). ## The six areas | Area | What it shows | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | | **Cost** | Cost by agent, task and outcome, against budgets | | **Token optimisation** | Model choice, cache use, wasted calls, and cost per outcome over time | | **Security and context** | Blocked and screened requests, attempts to instruct the model, stop switches, the access audit, and the knowledge each answer was grounded in | | **Reinforcement** | Evaluations, approvals and human edits, fed back so agents improve with each release | | **Insights** | Time saved, throughput, and value against the agreed baseline | | **Compliance** | The evidence pack, the audit trail and reports for a regulator | Every saving LightHouse shows is **estimated**, and says so. [Cost and token optimisation](/cost/) shows how each figure is calculated, and how to reproduce it. ## Where to start | You are | Start with | | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Evaluating LightHouse | This page, then [Concepts](/concepts/) and [Security](/security/) | | Setting up a new tenant | [The set-up mission](/start/setup/) | | An architect | [Clouds](/clouds/), [The telemetry contract](/concepts/telemetry-contract/) and [Data sovereignty](/data-sovereignty/) | | A developer | The [Quickstart](/start/quickstart/), then the [API](/api/) and [MCP](/mcp/) | | Reviewing security or compliance | [Security](/security/), [Data sovereignty](/data-sovereignty/) and [Trust](/trust/) | ## What this site covers This site describes what is built and released. Anything not built yet is marked \[Coming], with no date promised. Source: https://docs.atlanticagenticlabs.com/start/ --- # Quickstart > Sign in, issue an API key, make your first API call and connect Claude over MCP, in about ten minutes. This quickstart signs in to LightHouse, issues an API key, reads the tenant from the API and connects Claude to the tenant over MCP, so that agents can be queried in plain words. It takes about ten minutes. ## Before you start You need: - **Your tenant ID.** It is in the email that created your tenant, and it is the first part of your portal’s address: `https://.atlanticagenticlabs.com`. A tenant is created by sign-up at `platform.atlanticagenticlabs.com/register` or by Atlantic; see [Sign-up](/enterprise/sign-up/). - **The `client_admin` role** in your tenant, to issue an API key. The person who signed up has it. - **Your tenant’s machine access token**: a Cloudflare Access client ID and secret that Atlantic issues with your tenant. Your tools present it beside the API key. If your administrator does not have it, ask Atlantic. - `curl`, and optionally Python 3.10 or later with `httpx`, or Node 18 or later. ## 1. Sign in 1. Open `https://platform.atlanticagenticlabs.com`. The page is headed **Sign in to LightHouse**. 2. Enter your tenant ID in **Tenant ID** (it starts `t-`) and choose **Continue**. Tick **Remember this tenant on this device** if you want the field filled in next time. LightHouse sends you to your tenant’s own address. 3. Sign in with your work account. A tenant created by sign-up starts with one way in: a one-time PIN sent to the address you registered. Atlantic connects your own identity provider on request; the first step of the set-up mission covers it. You land on **Overview**. **Setup and admin → Set-up mission** lists seven steps: sign-in, branding, billing, where agents run, models, a first data source and a first agent. This quickstart needs none of them. When you are ready to set the tenant up properly, follow [The set-up mission](/start/setup/). ## 2. Issue an API key 1. Go to **Settings → Keys**. 2. Under **Issue a key**, enter a **Label**, for example `quickstart`. Set **Role** to **Viewer** and **Expires in** to **30 days**. 3. Choose **Issue**. LightHouse shows the key once, with the message “Copy this key now. It won’t be shown again.” Copy it, store it in a secret store, then choose **I’ve stored it**. The key starts `aalcp-`. An API key can only read. Its role is `viewer` or `content_viewer`, and LightHouse refuses a key on every route that approves, decides, pays or changes a limit. Expiry is required and can be at most one year. See [Authentication](/api/authentication/). ## 3. Set your environment ```bash export AAL_TENANT="" # the first label of your portal's address export AAL_KEY="aalcp-..." # the key you just copied export CF_ACCESS_CLIENT_ID="" # your tenant's machine access token export CF_ACCESS_CLIENT_SECRET="" ``` ## 4. Make your first request `GET /api/v1/me` returns the identity and tenant the API resolves for the credential. **curl** ```bash curl -s "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/me" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" \ | jq '{tenant: .client.tenant_id, viewer: .viewer | {email, kind, role}}' ``` **Python** ```python import os import httpx r = httpx.get( f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/me", headers={ "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"], }, ) r.raise_for_status() me = r.json() print({"tenant": me["client"]["tenant_id"], "viewer": {k: me["viewer"][k] for k in ("email", "kind", "role")}}) ``` **TypeScript** ```ts const res = await fetch(`https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/me`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, }); if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`); const me = await res.json(); console.log({ tenant: me.client.tenant_id, viewer: { email: me.viewer.email, kind: me.viewer.kind, role: me.viewer.role } }); ``` Expected output, with your own tenant ID and key ID: ```json { "tenant": "", "viewer": { "email": "key:3f9c1a2b", "kind": "machine", "role": "viewer" } } ``` A key is identified as `key:` followed by its eight-character ID. The full answer also lists your deployments, your branding and your display settings: see [Me](/api/reference/people-and-preferences/#me). ### If the request fails | You see | Why | Do | | ------------------------ | ----------------------------------------------------------- | --------------------------------------------------------- | | A sign-in page, or a 302 | The Access client ID or secret is missing or wrong | Check `CF_ACCESS_CLIENT_ID` and `CF_ACCESS_CLIENT_SECRET` | | `401 unauthenticated` | The key is missing, revoked, expired, or for another tenant | Issue a new key in this tenant | | `404 unknown_client` | The tenant ID in the address is wrong | Check `AAL_TENANT` | Every refusal is `{error, message}` with a fixed code: see [Errors](/api/errors/). ## 5. Read your agents ```bash curl -s "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/agents" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" | jq . ``` This lists every agent your deployments have reported, with its state: `running`, `idle`, `failing`, `paused` or `awaiting-sign-off`. A new tenant with no deployment returns an empty list. See [Agents](/concepts/agents/) and the [Agents List](/api/reference/read/#agents-list) reference. ## 6. Connect Claude over MCP LightHouse serves the same reads as Model Context Protocol tools at `https://.atlanticagenticlabs.com/mcp`. Add it to Claude Code in one line: ```bash claude mcp add --transport http lighthouse "https://$AAL_TENANT.atlanticagenticlabs.com/mcp" \ --header "Authorization: Bearer $AAL_KEY" \ --header "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ --header "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" ``` Run `claude mcp list` to check that `lighthouse-ai` shows as connected. Then ask Claude, for example: *Which of my agents are failing, and what did they cost this month?* Claude answers using the `agents` and `usage` tools. Every tool only reads; none approves, pays or changes a limit. For Cursor and Codex, see [Connect a client](/mcp/connect/). ## Next steps - **Choose where agents run**: **Setup and admin → Where agents run**. Pick your cloud, a region and a deployment profile. LightHouse gives you the stack, and your own pipeline applies it. See [Clouds](/clouds/). - **Connect a source**: **Setup and admin → Connectors**. See [Connect your estate](/connect/) for which connectors connect from LightHouse. - **Add an agent from the library**: **Agents → Library**, open a card, then **Add to deployment**. This records a request. Nothing is deployed from the portal: the agent reaches your deployment through a reviewed merge and the release gate. See [From the library](/build/library/). - **Watch a run**: once a deployment is sending telemetry, **Agents → Activity** shows each run live, and the [run map](/build/run-map/) shows every step, its model, its cost and any sign-off. - **Work from a terminal or your own code**: `lighthouse-ai login` signs you in as yourself, with no key to copy ([The CLI](/cli/)); to call the API from your own code, generate a client from its OpenAPI document ([Build against the API](/api/build-against-the-api/)). - **Revoke the quickstart key** when you are done with it: **Settings → Keys**. Source: https://docs.atlanticagenticlabs.com/start/quickstart/ --- # Choose your setup > The four decisions that shape a LightHouse deployment — where agents run, which profile, which models, and which channel your people use — and what each one commits you to. Four decisions shape a deployment. Three can be changed later. The fourth, the region, is hard to change. Each section below links to the page with the full detail. | Decision | Changeable later? | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **Where agents run**: your cloud, your servers, or Atlantic’s | Yes. The old deployment keeps running until your own pipeline takes it down; nothing moves. | | **Which deployment profile**: ephemeral or always-on | Yes, by changing one Terraform variable. No data moves. | | **Which models**: and Direct or Managed | Yes, per use case, at any time. | | **Your region** | **Not easily.** Your content, index and model calls stay in the region you pick. Moving region means a new deployment and re-indexing. | ## 1. Choose where agents run **AWS** **You will need**: an AWS account you can run CloudFormation in, and a pipeline that can apply Terraform. LightHouse gives you a CloudFormation bootstrap and then a Terraform stack. LightHouse does not apply anything in your account. Your own pipeline applies it, so each change is reviewed and logged with your other infrastructure changes. - **Models**: Amazon Bedrock. - **Regions offered**: `eu-west-1`, `eu-west-2`, `eu-central-1`, `us-east-1`, `us-west-2`. - **Both profiles** are supported, and ephemeral saves the most here of any cloud. Next: [AWS](/clouds/aws/). **Azure** **You will need**: an Azure subscription, and a pipeline that can apply Terraform. Two Bicep files bootstrap it, then a Terraform stack. - **Models**: Azure OpenAI. - **Regions offered**: `westeurope`, `northeurope`, `uksouth`, `eastus`, `westus2`. - **Both profiles** are supported. Ephemeral saves least here of the three clouds, because Azure’s managed PostgreSQL cannot pause when idle. Next: [Azure](/clouds/azure/). **Google Cloud** **You will need**: a Google Cloud project, and a pipeline that can apply Terraform. Terraform bootstraps it, then a Terraform stack. - **Models**: Vertex AI. - **Regions offered**: `europe-west2`, `europe-west1`, `europe-west4`, `us-east4`, `us-central1`. - **Both profiles** are supported. Next: [Google Cloud](/clouds/google-cloud/). **Your own servers** **You will need**: a host that runs Docker or Podman (rootless or rootful) with Compose, and somewhere to keep secret files beside the stack. There is no cloud bootstrap: the deployment’s key is a secret file you place on the host. Everything else is the same engine. - **Runtime**: Docker, or Podman 5. Rootless Podman runs no daemon as root. - **Models**: any backend the gateway supports, including a model you host. - **Region**: wherever your hardware is. - **Both profiles** are supported. There is no cloud bill to compare a saving against. Under Podman, the ephemeral profile uses the two Podman settings in the generated file. Next: [Your own servers](/clouds/on-premises/). **Atlantic-hosted** **You will need**: nothing to run. Atlantic runs the account. Choose this to use the engine without operating it. The account belongs to Atlantic, so the data-sovereignty position differs from the other options; read [Data sovereignty](/data-sovereignty/) before choosing it. - **Models**: Amazon Bedrock. - **Regions offered**: `eu-west-1`, `eu-west-2`, `eu-central-1`, `us-east-1`. - Infrastructure is quoted as a managed service rather than compared against a cloud bill. Next: [Atlantic-hosted](/clouds/atlantic-hosted/). ## 2. Choose a deployment profile Both profiles run the same engine and the same agents. They differ in what is left running when nothing is happening. **Ephemeral** Infrastructure starts when there is work and stops when there is none. - **Choose it when** agent work is bursty or scheduled: overnight ingests, business-hours triage, or anything that is idle more often than busy. - **The trade-off**: the first request after a quiet spell waits while the deployment wakes. A read that needs the deployment returns `503 deployment_waking` with `Retry-After: 5`. The portal shows “Waking your deployment…” and retries. Integrations must retry on that status. - **Estimated saving on the lines the profile changes**: around 95% on AWS, 87% on Google Cloud and 72% on Azure. These are proportions; the amount depends on your region, currency and any committed-use pricing. **Always-on** Infrastructure stays up. - **Choose it when** requests arrive unpredictably all day, or your users cannot accept a waking delay. - **The trade-off**: you pay for capacity while it is idle. - It is the infrastructure module’s default, so always-on applies if no profile is chosen. Changing profile later is one Terraform variable, planned and applied by your own pipeline. No data moves: the key, the database, the file system and the secrets are kept. Resizing a database is a separate change. See [Deployment profiles](/concepts/deployment-profiles/). ## 3. Choose models, and who pays the provider A model is chosen for each use case. **Setup and admin → Models** only offers models available in the cloud you picked and allowed by your data-residency rule. **Direct** Calls go to your own provider account: your Amazon Bedrock, Azure OpenAI or Vertex AI, your Claude API organisation, or your OpenAI project. **You pay the provider.** LightHouse records which account a call is attributed to, and does not hold a provider key. Your gateway authenticates as itself through workload identity, so no long-lived credential exists. **Managed** Calls go through Atlantic’s provider account. **Atlantic bills you** at the price card. The model picker shows the managed price beside the direct price, with the margin stated as a percentage. Choose Managed to start without setting up a provider account. You can move to Direct later without changing an agent. See [Models](/router/) for how a model is chosen per call, and [Cost](/cost/) for what you are charged. ## 4. Choose the channels your people use The portal, the API, MCP and the CLI read the same data. Choose per audience; most tenants use all four. [The portal (UI)](/security/ui/)For people: approvals, the run map, spend, settings. Sign-in is through your own identity provider, with MFA required. [The API](/api/)For your systems: everything the portal shows, read-only, with a machine key scoped to one tenant. Start at Authentication. [MCP](/mcp/)For an assistant: read-only tools, so a person can ask about agents, runs and spend in plain words. [The CLI](/cli/)For engineers: sign in by device code, read the estate, follow live runs and scaffold an agent. Each channel has its own security page, because the controls differ. A browser session, a machine key and a delegated token are checked in different places and fail in different ways: - [Security: the portal](/security/ui/) - [Security: the API](/security/api/) - [Security: MCP](/security/mcp/) - [Security: the engine](/security/engine/) ## Next steps 1. **Set up the tenant.** [The set-up mission](/start/setup/) covers the seven steps. You can leave any of them for later. 2. **Try the API and MCP.** The [Quickstart](/start/quickstart/) issues a key, reads the API and connects an assistant over MCP in about ten minutes. 3. **Connect one source.** One connector, read only by default, with its credential sealed to your deployment and kept in your own secrets store once your deployment can keep it. See [Connect your estate](/connect/). 4. **Put one agent to work.** Add one from the library to your deployment. See [From the library](/build/library/) and [Agents](/concepts/agents/). Source: https://docs.atlanticagenticlabs.com/start/choose/ --- # The set-up mission > Ten steps from a new tenant to a working agent: what each one does, what it needs first, and how LightHouse determines that it is done. The **set-up mission** at **Setup and admin → Set-up mission** guides a client administrator from a new tenant to a first agent at work. It has ten steps and takes about 48 minutes in total (estimated). For the full path from sign-up, see [Organisation set-up](/enterprise/). Any step can be left for later, and steps can be taken in any order except where noted below. The rest of LightHouse operates while the mission is incomplete. The [Quickstart](/start/quickstart/) needs none of these steps; it issues a key and reads the API. The set-up mission is for configuring the tenant itself. The **Setup and admin** group appears in the sidebar only for people with the **Client administrator** (`client_admin`) role. ## Steps | # | Step | What it is for | Needs first | Est. | | -- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------ | | 1 | **Let your team sign in** | Connect the identity provider and set who may sign in. See [Single sign-on](/enterprise/single-sign-on/) | — | 3 min | | 2 | **Verify your domain** | Publish one DNS record to verify the organisation’s email domain, so that sign-in rules can name it. See [Verified domains](/enterprise/domains/) | — | 5 min | | 3 | **Make it yours** | The organisation’s logo and colours on the portal | — | 2 min | | 4 | **Settle how you pay** | A payment method or invoice terms, and the agreements accepted | — | 3 min | | 5 | **Choose where your agents run** | Own cloud, own servers (online or [air-gapped](/enterprise/air-gapped/)) or Atlantic-hosted, and the deployment profile | — | 5 min | | 6 | **See your stack report in** | Install the stack and receive a deployment’s first signed telemetry | Step 5 | 15 min | | 7 | **Choose your models** | A model per use case, Direct or Managed, filtered to the cloud and the data residency | Step 5 | 4 min | | 8 | **Connect your first data source** | One connector, read-only by default, with its credential kept in the organisation’s own secrets store, or under the tenant’s key until the deployment can keep it | — | 4 min | | 9 | **Put your first agent to work** | An agent from the library, on a deployment | Steps 7 and 8 | 5 min | | 10 | **Meet Octy** | Ask Octy™ a question about the estate; the answer cites what it read | — | 2 min | Dependencies: - **See your stack report in** and **Choose your models** require step 5. The models offered depend on the cloud chosen. - **Put your first agent to work** requires steps 7 and 8: an agent needs a model to call and a source to read. A step whose dependency is not done shows the dependency as blocking; the step can still be opened. ## Where to start, and what to skip 1. **Step 1, where other people will take part.** A tenant created by sign-up has one sign-in method: a one-time PIN sent to the registering address. Other people can sign in once an identity provider is connected and a rule admits them. The client administrator connects Microsoft Entra ID, Okta, Google Workspace, SAML 2.0 or OpenID Connect at **Access → Single sign-on** ([Single sign-on](/enterprise/single-sign-on/)); Atlantic configures GitHub and GitLab sign-in on request. Rules are set on the **Access** page (below). 2. **Step 4, before any spend.** Managed model calls require a payment method or invoice terms. In this step the administrator also accepts the master services agreement (MSA) and data processing agreement (DPA); LightHouse lists a new version of either as pending until it is accepted. See [Change notices](/trust/change-notices/). 3. **Step 5, before steps 6 and 7.** Choose the cloud, a region and a deployment profile. LightHouse produces the stack, and the organisation’s pipeline applies it. See [Clouds](/clouds/). 4. **Step 3, optional.** Branding changes the portal’s appearance only. To leave a step for later, choose **Leave for later** on it. To undo that, choose **Take this up again**. LightHouse records who made the choice in the audit trail. A step left for later no longer counts as outstanding and no longer blocks the steps that depend on it. ## Step 1 in detail: decide who may sign in **Settings → Users and roles** opens the **Access** page (`client_admin`, signed in as a person). It shows your **Identity providers** (each with its status and where its second factor comes from), the **Fixed rules** that no one can change, and **Who can sign in**: the rules that give people a role. 1. Under **Who can sign in**, choose **Add a rule**, or **Add a time-limited person (e.g. an auditor)** for a named person whose access should end on a date. 2. Set the **Role**: Viewer, Content viewer, Agent handler or Client administrator. See [Roles](/api/roles/). 3. Choose what the rule **Matches**: *Group in your identity provider*, *GitHub organisation or team*, *Email domain*, *Named person (email)*, or *Everyone in your identity provider*, and fill in the value. 4. Optionally set **Expires** (at most a year ahead) and a **Note** (up to 120 characters). 5. Choose **Save changes**. The page confirms *“Saved. Access is now at version N; the change is in the audit log.”* If a rule breaks a fixed rule, it says *“Not saved:”* and why. Someone matched by several rules gets the highest role. The fixed rules include: at least one client administrator rule must remain; a public mail domain (such as gmail.com) cannot be a domain rule; the one-time email code admits named people only; and Atlantic staff can be given at most content viewer. Under **Atlantic Agentic Labs staff**, you choose whether Atlantic’s engineers may also read content. The page’s **Access review (CSV)** and **Access review (JSON)** buttons download who holds which role. See [API security](/security/api/#roles-and-least-privilege). ## How LightHouse knows a step is done LightHouse reads the underlying configuration each time the mission is opened; no completion flag is stored. Step 1 reads the tenant’s identity providers and access rules, step 2 the verified domains, step 4 the billing account and pending agreements, step 6 the telemetry received from active deployments, step 8 the connections, step 9 the agents the deployments have reported and the accepted library requests, and step 10 whether Octy has answered a question in the tenant. A step can return to not done. Removing the identity provider reopens step 1; disconnecting the only source reopens step 8. Each step shows a sentence describing the current state of your tenant. For example: > Okta connected, and 3 rules deciding who signs in. > No identity provider yet: sign-in is by one-time PIN only. > Paying by invoice. MSA and DPA still to accept. > Still Atlantic’s own colours and mark. When step 5’s sentence includes a saving for running ephemeral rather than always-on, it is labelled estimated. It comes from the same versioned cost model as the **Deployments** page. See [Cost and token optimisation](/cost/). The mission reads and reports only and does not change the configuration. Each step links to its own page (**Do this step**, or **Open this step** once done), which does the work with its own confirmations and role checks. If the feature behind a step is temporarily unavailable, that step shows as not done with the sentence *“We could not read this just now; open the page to check.”* The other steps are unaffected. ## Reading it from the API `GET /api/v1/setup` returns the whole mission. Each step has its `step` id, `title`, `goal`, `minutes` (the estimate), `needs`, `done`, `skipped`, `blocked_by` and `outcome` (the sentence). The response also has `done`, `total`, `complete`, and `next`, which is the id of the first step that is neither done nor skipped. The step ids are `sign-in`, `verify-domain`, `branding`, `billing`, `where-agents-run`, `stack-reporting`, `models`, `first-data-source`, `first-agent` and `meet-octy`. ```bash curl -s "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/setup" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" \ | jq '{done, total, next, steps: [.steps[] | {step, done, outcome}]}' ``` Reading the mission needs `viewer` or above, so the quickstart’s read-only key is enough. See [Me and preferences](/api/reference/people-and-preferences/). Leaving a step for later is `PUT /api/v1/setup/{step}` with the body `{"skipped": true}` (or `false` to take it up again). It returns the refreshed mission, and is recorded in the audit trail as `setup_step_skipped` or `setup_step_resumed`. This route accepts only a person signed in to the portal with the `client_admin` role. An API key, or a delegated token from the CLI or an MCP client, is refused with `403 role_required`, whatever role it carries. In practice, use **Leave for later** in the portal. Other errors: | Status and code | Cause | | --------------- | ----------------------------------------------------------- | | `404 not_found` | The step id is not one of the ten | | `422 invalid` | The body is not `{"skipped": true}` or `{"skipped": false}` | See [Authentication](/api/authentication/) and [Roles](/api/roles/). The mission is also an MCP tool, [`setup`](/mcp/tools/setup/), so you can ask an assistant “What is left to set up?” and get the outcome sentences back. The tool only reads. ## When you are finished `complete` becomes `true` when every step is either done or left for later, and the mission’s summary reads **Your estate is set up**. Next: - **Watch a run**: **Agents → Activity** shows each run live, and the [run map](/build/run-map/) shows every step, its model, its cost and any sign-off. - **Add more sources**: [Connect your estate](/connect/). - **Set a limit before you need one**: [Limits and alerts](/operations/limits-and-alerts/). - **See what a reviewer or regulator can be given**: [Evidence](/concepts/evidence/) and [Trust](/trust/). Source: https://docs.atlanticagenticlabs.com/start/setup/ --- # Organisation set-up > The path from sign-up to a configured LightHouse tenant: sign-up or sales-led onboarding, then domains, single sign-on, provisioning, invitations, where agents run, the stack, Octy and the security review. This section sets out, in order, how an organisation obtains a LightHouse™ tenant and configures it under its own controls. ## Responsibilities | Party | Responsibility | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Client administrator** (`client_admin`) | Signs up or accepts Atlantic’s invitation, accepts the agreements, verifies domains, connects and tests single sign-on, issues the SCIM token, sends invitations, chooses where agents run and installs the stack. Each action requires a person’s own sign-in; a machine key cannot perform them | | **The organisation’s IT** | Publishes a DNS record, registers LightHouse in the identity provider, configures SCIM provisioning in the directory, and applies the stack | | **Atlantic** | Creates the tenant for sales-led onboarding and records a negotiated agreement by reference. Our certified forward-deployed engineers take part in any step on request | ## Sequence - **Client administrator**: signed in as a person - **Organisation's DNS, identity provider and directory** - **LightHouse**: the organisation's tenant Sign-up 1. Client administrator to LightHouse: **Sign up, or accept Atlantic's invitation**. self-service at /register, or sales-led from an order form 2. Client administrator to LightHouse: **Accept the MSA and DPA**. by click-through, or a negotiated agreement recorded by reference Identity 3. Client administrator to LightHouse: **Add a domain**. LightHouse returns the DNS record to publish 4. Organisation's DNS, identity provider and directory to LightHouse: **Publish the TXT record**. LightHouse finds it and marks the domain verified 5. Client administrator to LightHouse: **Connect the identity provider**. it admits only the administrator while in testing 6. Client administrator to Organisation's DNS, identity provider and directory: **Sign in through it**. the test is confirmed from that session 7. Client administrator to LightHouse: **Turn it on**. for verified domains, or for every user of the organisation's own provider 8. Organisation's DNS, identity provider and directory to LightHouse: **Provision users and groups**. SCIM 2.0, with a token issued in LightHouse 9. Client administrator to LightHouse: **Invite named people**. each with a role and an end date Deployment and review 10. Client administrator to LightHouse: **Choose where agents run**. a cloud, Atlantic-hosted, or the organisation's own servers, online or air-gapped 11. Organisation's DNS, identity provider and directory to LightHouse: **The stack reports in**. signed telemetry, live or imported by file 12. Client administrator to LightHouse: **Ask Octy a question**. the answer cites its sources 13. LightHouse to Client administrator: **Download the security review pack**. standard answers, each with its evidence Each step is taken by the client administrator in LightHouse, with the organisation's DNS, identity provider, directory and infrastructure performing their part. A new identity provider admits only the administrator until a sign-in through it has been confirmed. ## Steps | # | Step | In LightHouse | Prerequisite | Page | | -- | ---------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | 1 | Sign up, or accept Atlantic’s invitation | `platform.atlanticagenticlabs.com/register`, or the invitation email | — | [Sign-up](/enterprise/sign-up/) | | 2 | Accept the agreements | During sign-up; new versions at **Billing → Terms** | — | [Agreements](/enterprise/agreements/) | | 3 | Verify domains | **Access → Domains** | Access to the organisation’s DNS | [Verified domains](/enterprise/domains/) | | 4 | Connect single sign-on | **Access → Single sign-on** | An application registered in the identity provider | [Single sign-on](/enterprise/single-sign-on/) | | 5 | Turn single sign-on on | **Access → Single sign-on** | A confirmed test sign-in; for a domain rule, a verified domain | [Single sign-on](/enterprise/single-sign-on/#turning-it-on) | | 6 | Provision from the directory | **Access → Provisioning** | Single sign-on, for provisioned people to sign in | [SCIM provisioning](/enterprise/provisioning/) | | 7 | Invite named people and assign roles | **Access → Invitations**; roles on **Access** | — | [Inviting people](/enterprise/invitations/), [Roles](/api/roles/) | | 8 | Choose where agents run | **Where agents run** | — | [Clouds](/clouds/); [Choosing air-gapped](/enterprise/air-gapped/) for a site with no network path | | 9 | Install the stack and see it report in | **Deployments** | Step 8 | [The set-up mission](/start/setup/) | | 10 | Ask Octy a question | **Home** | — | [Octy](/octy/) | | 11 | Review security | **Settings → Security review** | — | [The security review pack](/enterprise/security-review/) | LightHouse enforces three dependencies: a tenant exists only after both agreements are accepted; a provider is tested before it is turned on; a sign-in rule for a whole domain requires that domain to be verified. The other steps can be taken in any order. ## In the set-up mission The [set-up mission](/start/setup/) at **Setup and admin → Set-up mission** tracks steps 3 to 10 alongside branding, billing, models, the first data source and the first agent. Three of its steps correspond to this section: | Mission step | Done when | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Verify your domain** | At least one domain is verified | | **See your stack report in** | Own cloud or own servers: a deployment has delivered signed telemetry in the last eight days; the step names the deployment and the time. Air-gapped: a telemetry bundle has been imported. Atlantic-hosted: the hosted account is running | | **Meet Octy** | Octy™ has answered a question in the tenant | Each outcome is read from the tenant when the mission is opened and is not stored. Any step can be left for later. Atlantic’s onboarding team has read-only access to the tenant’s mission, and each read is recorded in the tenant’s audit log. ## Audit Each change in this section is recorded in the tenant’s audit log with the person who made it: tenant registration; agreements accepted or recorded; domains added, checked and removed; providers connected, tested, turned on and disconnected; SCIM tokens issued and revoked; invitations sent, accepted and revoked. See [Who can see what](/data-sovereignty/access/). Source: https://docs.atlanticagenticlabs.com/enterprise/ --- # Sign-up > Create an organisation's LightHouse tenant by self-service sign-up, or through Atlantic from an order form. An organisation’s LightHouse™ tenant is created by self-service sign-up or by Atlantic from a signed order form. Both routes produce a tenant with one client administrator (`client_admin`), who then completes the [set-up mission](/start/setup/). ## Routes | | Self-service sign-up | Sales-led onboarding | | --------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | | **Started by** | A person at the organisation | Atlantic, from the order form | | **Agreements** | The MSA and DPA in force, accepted by click-through | The order form; a negotiated MSA or DPA signed on paper is [recorded by reference](/enterprise/agreements/#negotiated-agreements) | | **Commercial terms** | Standard; set on **Billing → Terms** | Set by agreement and recorded on the tenant | | **Administrator’s first sign-in** | At the portal address shown when sign-up completes | From the invitation email Atlantic sends | | **Sign-in method at first** | One-time PIN sent to the administrator’s email address | One-time PIN sent to the administrator’s email address | ## Self-service sign-up ### Requirements | Field | Requirement | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Work email** | Required. Disposable email domains are refused. A personal mail domain is accepted and reviewed by Atlantic. The address becomes the client administrator’s sign-in | | **Organisation** | Required. The name the organisation trades under, 2 to 120 characters. The tenant’s identifier is derived from it | | **Country of registration** | Required. The country in which the organisation is registered | | **VAT number** | Optional. Checked against the EU VIES service where given, and kept for invoices | ### Procedure 1. Open `https://platform.atlanticagenticlabs.com/register`, enter the organisation’s details and choose **Send me a code**. Result: LightHouse sends an email to the address with a six-digit code and a link to continue. The response is the same whether or not the address or company is already registered. 2. Enter the code. The code is valid for 30 minutes and accepts six attempts; **Send a new code** issues a new one and invalidates the previous code. The sign-up link is valid for 24 hours. Result: the email address is verified and the VAT number is checked against VIES. The VIES result is recorded as valid, invalid or unavailable. An unavailable VIES service does not stop the sign-up. 3. Read the master services agreement (MSA) and the data processing agreement (DPA) in force, select both, and choose **Accept and create my organisation**. No tenant exists before this step. Result: LightHouse records each acceptance (agreement, version, time, the verified email address, and keyed hashes of the network address and browser) and creates the tenant in the same transaction. The page shows the tenant ID and the portal address, `https://.atlanticagenticlabs.com`, and LightHouse emails the tenant ID to the administrator. 4. Open the portal address and sign in with the one-time PIN sent to the same email address. Result: the person is signed in as the tenant’s client administrator. ### The new tenant | Property | Value | | ------------------- | ------------------------------------------------------------------------------------------------------------------- | | **State** | Sandbox: synthetic sample data, with Octy™ available | | **Spend** | No managed model calls until a payment method or invoice terms exist (set-up step **Settle how you pay**) | | **Sign-in** | One-time PIN to the administrator’s address, until an [identity provider](/enterprise/single-sign-on/) is connected | | **Billing details** | The country, VAT number and VIES result are carried to **Billing → Terms** | ## Sales-led onboarding 1. The organisation signs Atlantic’s order form. The agreements are part of the order. A negotiated MSA or DPA is signed outside the portal. 2. Atlantic creates the tenant from the order form, with the commercial terms set, and records the agreements against it. Result: the tenant exists in the same initial state as a self-service tenant, with the order’s terms recorded. 3. Atlantic sends the named administrator an invitation email, **Your LightHouse sign-in**, with the portal address and the tenant ID. The email contains no credential. 4. The administrator opens the portal address and signs in with the one-time PIN sent to that email address. Result: the administrator is signed in as the tenant’s client administrator. Atlantic can resend the invitation on request. ## Limits | Limit | Value | | --------------------- | ----------------------------------------------------------- | | Sign-up link validity | 24 hours | | Code validity | 30 minutes | | Code attempts | 6; then `429 code_spent`, and a new code is required | | Rate limiting | Per network address, per email address and per email domain | ## Audit Tenant creation is recorded in the tenant’s audit log as `tenant_registered`, with the route (self-service or Atlantic), the VIES result and the agreements recorded. An invitation sent by Atlantic is recorded as `tenant_invite_sent`, and commercial terms set from an order form as `commercial_terms_set`. ## Next Complete the [set-up mission](/start/setup/). [Organisation set-up](/enterprise/) lists the steps in order. Source: https://docs.atlanticagenticlabs.com/enterprise/sign-up/ --- # Agreements > Accept the master services agreement and the data processing agreement in LightHouse, or have a negotiated agreement recorded by reference. Use of LightHouse™ is governed by the **master services agreement** (MSA) and the **data processing agreement** (DPA), accepted in LightHouse or executed outside it and recorded by Atlantic. ## Methods | Method | Used for | Recorded as | | ----------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------- | | Click-through at sign-up | [Self-service sign-up](/enterprise/sign-up/) | Accepted | | Acceptance at **Billing → Terms** | New versions of the standard text | Accepted | | Order form | [Sales-led onboarding](/enterprise/sign-up/#sales-led-onboarding) | Accepted, with the route `order_form` | | Negotiated MSA or DPA signed outside the portal | Sales-led onboarding with negotiated terms | [Executed agreement](#negotiated-agreements) | ## Versions Each agreement’s version is the date its text took effect, such as `2026-10-31`. The text of each version is published on the company site under that date (see [Legal](/data-sovereignty/legal/)). A later version is published alongside earlier versions; published versions are not edited. When a new version takes effect, LightHouse lists it as awaiting acceptance on **Billing → Terms** and in the set-up mission’s **Settle how you pay** step. ## Procedure The **Agreements** panel on **Billing → Terms** shows, for each agreement, the version in force and its status: **Accepted**, **Awaiting acceptance** or **Executed agreement**. 1. Open **Billing → Terms**, signed in as a person with the `client_admin` role. 2. Read the standard text from the link beside the version. 3. Choose **Accept the master services agreement** or **Accept the data processing agreement**. Result: the panel shows the agreement as **Accepted**, with the version. Acceptance is made by a person. Atlantic staff, machine keys and delegated tokens cannot accept. If a new version took effect after the page was loaded, the acceptance is refused; reload the page, read the new text and accept again. ## Acceptance record | Field | Content | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | Agreement and version | For example, `msa` `2026-10-31` | | Time | When the acceptance was made | | Person | The verified sign-in email address | | Origin | Keyed hashes of the network address and browser. These show whether steps came from the same party; the address itself is not stored | The record is append-only and cannot be edited or deleted while the tenant exists. It is also entered in the tenant’s audit log as `agreement_accepted`. ## Negotiated agreements An organisation that negotiates its MSA or DPA signs it outside the portal. Atlantic records the **executed agreement** against the tenant: | Field | Content | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | Contract reference | The reference on the signed document | | Effective date | The date from which the agreement governs | | Signatories | Both parties’ signatories | | Document hash | The SHA-256 hash of the signed document. LightHouse holds the hash, which identifies the signed file; it does not hold the document | The record is append-only and appears in the tenant’s audit log as `agreement_executed_recorded`, an action by Atlantic. From its effective date, an executed agreement governs in place of the standard text for that agreement. Later versions of the standard text are not offered for acceptance; a negotiated agreement changes by amendment, recorded as a further executed agreement. The panel shows the reference, effective date, signatories and hash. To compare the organisation’s copy with the record: ```sh shasum -a 256 signed-agreement.pdf ``` ## API | Route | Role | Action | | ------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | | `GET /api/v1/agreements` | Any role | Returns the versions in force, when the tenant accepted each, any executed agreement that governs, and what is pending | | `POST /api/v1/agreements` | `client_admin`, a person | Accepts the versions in force, such as `{"msa": "2026-10-31", "dpa": "2026-10-31"}`; the response lists what was newly recorded | A version already accepted is not recorded again. An agreement governed by an executed agreement cannot be accepted through this route (`409`). Source: https://docs.atlanticagenticlabs.com/enterprise/agreements/ --- # Verified domains > Verify an organisation's email domains with a DNS TXT record before sign-in rules name them. A verified domain is an email domain whose ownership the organisation has demonstrated with a DNS TXT record. LightHouse™ requires a verified domain before a sign-in rule can admit everyone at that domain. ## Requirements | Requirement | Detail | | ----------- | ----------------------------------------------------------------------------------------------------------- | | Role | `client_admin`, signed in as a person | | Access | The ability to publish a TXT record in the domain’s DNS zone | | Domain | Not a public mail domain (such as `gmail.com`; refused as `public_email_domain`) and not an Atlantic domain | | Limit | Up to 20 domains per tenant | ## Procedure 1. Open **Access → Domains**. Under **Add a domain**, enter the domain, such as `example.com`, and choose **Add domain**. Result: LightHouse shows the record to publish, and the domain is in the state **Waiting for the record**. | Type | Name | Value | | ----- | ----------------------------------- | ---------------------------------------- | | `TXT` | `_lighthouse-challenge.example.com` | `lighthouse-domain-verification=` | 2. Publish the record at the DNS provider. The record is on its own label, `_lighthouse-challenge`; records at the domain apex, including MX and SPF, are unaffected. The token is public; its presence in the zone demonstrates control of the zone. 3. Choose **Check now**. LightHouse looks up the record over DNS-over-HTTPS through public resolvers. DNS changes can take up to an hour to propagate. Result: when the record is found, the domain is **Verified**. Sign-in rules may then name the domain and its subdomains. ## States | State | Meaning | | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Waiting for the record** | The domain has been added; the record has not been found | | **Verified** | The record was found. Sign-in rules may name the domain and its subdomains | | **Record missing** | The record was not found at the last daily check. The domain remains verified for 14 days, and the page shows the end date. Publish the record again to keep the domain verified | | **Lapsed** | The record has been missing for more than 14 days. Saved rules continue to apply; the domain no longer counts as verified for new rules. Publish the record again and choose **Check now** to restore it | LightHouse re-checks every verified domain once a day. A check that cannot be completed, for example because a resolver is unavailable, leaves the state unchanged, and the page reports that the check could not be made. ## Ownership by one tenant A domain can be verified by one tenant only. A domain already verified by another organisation is refused; the refusal does not name that organisation. To dispute ownership, contact [Atlantic support](/operations/support/). ## Sign-in rules | Case | Behaviour | | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | New **Email domain** rule on the **Access** page | Requires a verified domain or a subdomain of one; otherwise refused with `domain_not_verified` | | Rule saved before domain verification was introduced | Continues to apply. The **Domains** page lists it as resting on an unverified domain, for the administrator to verify | | Removing a domain that a rule relies on | Refused with `domain_in_use` until the rule is changed or removed | | [Single sign-on](/enterprise/single-sign-on/#turning-it-on) turned on for domains | Admits only verified domains | ## API | Route | Role | Action | | ------------------------------------- | ------------------------ | ----------------------------------------------------------------------------- | | `GET /api/v1/domains` | `client_admin` | Lists the domains and their states | | `POST /api/v1/domains` | `client_admin`, a person | Adds a domain, `{"domain": "example.com"}`, and returns the record to publish | | `POST /api/v1/domains/{domain}/check` | `client_admin`, a person | Looks up the record | | `DELETE /api/v1/domains/{domain}` | `client_admin`, a person | Removes the domain | The [API reference](/api/reference/) has the request and response shapes. ## Audit Each change is recorded in the tenant’s audit log as `domain_added`, `domain_state_changed` or `domain_removed`, with the person who made it. A state change found by the daily re-check is recorded with the actor `aal:domains`. Source: https://docs.atlanticagenticlabs.com/enterprise/domains/ --- # Single sign-on > Connect Microsoft Entra ID, Okta, Google Workspace, SAML 2.0 or OpenID Connect to LightHouse, test it with a sign-in, then turn it on for the organisation. A client administrator connects the organisation’s identity provider to LightHouse™ at **Access → Single sign-on**. Sign-in at the edge is enforced by Cloudflare Access for every tenant (see [Authentication](/api/authentication/)); this page configures the organisation’s provider in Cloudflare Access. ## Requirements | Requirement | Detail | | ----------------- | --------------------------------------------------------------------------------------------------------------------- | | Role | `client_admin`, signed in as a person | | Identity provider | **Microsoft Entra ID**, **Okta**, **Google Workspace**, **SAML 2.0** or **OpenID Connect** | | Limit | Up to five identity providers per tenant, in addition to the one-time PIN; refused as `too_many_providers` above that | | Registration | An application registered in the identity provider with the values LightHouse shows | ## Client secret The client secret is sent to Cloudflare Access in the provider’s configuration and is then discarded. LightHouse does not store, log, audit or return it, and Cloudflare Access does not return it. Atlantic staff have no access to it. To change it, use **Replace secret**. ## Values for the identity provider Under **What to enter in your identity provider**, the page shows: | Value | Use | | -------------------------- | ---------------------------------------------------------------------------------------------------------- | | **Redirect URI (ACS URL)** | The address the provider returns the person to after sign-in. For SAML, the assertion consumer service URL | | **Entity ID (audience)** | For SAML, the service provider’s entity ID | Register an application with these values, then enter the provider’s details under **Connect an identity provider**. **Microsoft Entra ID** In the Microsoft Entra admin centre, register an application (**App registrations → New registration**) with a **Web** redirect URI set to the value LightHouse shows. Create a client secret under **Certificates & secrets**. Grant the delegated Microsoft Graph permissions `openid`, `email`, `profile` and `User.Read`, with administrator consent, and `GroupMember.Read.All` if sign-in rules will use Entra groups. In LightHouse, enter the **Client ID** (the application ID), the **Directory (tenant) ID** and the **Client secret**. **Okta** In the Okta admin console, create an **OIDC – OpenID Connect** app integration of type **Web Application**, with the sign-in redirect URI set to the value LightHouse shows, and assign it to the people or groups who will use LightHouse. In LightHouse, enter the **Okta organisation URL** (such as `https://example.okta.com`), the **Client ID** and the **Client secret**. For a custom authorisation server, also enter its **Authorisation server ID**. **Google Workspace** In the Google Cloud console for the Workspace organisation, create an **OAuth client ID** of type **Web application**, with the authorised redirect URI set to the value LightHouse shows. In LightHouse, enter the **Client ID**, the **Client secret** and the **Google Workspace domain**. **SAML 2.0** In the identity provider, create a SAML application with the ACS URL and entity ID that LightHouse shows, and release the person’s email address as an attribute. In LightHouse, paste the provider’s **metadata XML**. LightHouse reads the sign-in URL, the issuer and the signing certificates from it. If the email address is released under a non-default attribute name, enter it as **Email attribute**. **OpenID Connect** In the identity provider, register a confidential web client with the redirect URI that LightHouse shows. In LightHouse, enter the **Client ID**, the **Client secret**, the **Issuer URL**, the **Authorisation URL**, the **Token URL** and the **JWKS URL**. If the email address is in a claim other than `email`, enter it as **Email claim**. ## Testing A new provider starts in the state **Testing**. In this state its Cloudflare Access policy admits only the administrator who connected it, so a misconfigured provider (for example, one that points at the wrong directory or releases a claim that matches every user) admits no other user. 1. Choose **Connect**. Result: the provider shows **Testing**, and only the connecting administrator can sign in through it. 2. Sign out, sign in again and choose the new provider. 3. Return to **Access → Single sign-on** and choose **Confirm the test**. Result: the provider shows **Tested, ready to turn on**. The test is accepted only from a session that Cloudflare Access admitted through that provider. A confirmation from any other session or provider is refused. ## Turning it on Choose which people the provider admits, then choose **Turn on for the organisation**: | Option | Admits | Condition | | ---------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | **Everyone with an address at** | People at one or more [verified domains](/enterprise/domains/) | An unverified domain is refused | | **Everyone the provider signs in** | Every user of the provider | The provider is the organisation’s own: Entra ID, Okta, Google Workspace, SAML or OpenID Connect | Turning a provider on admits these people at the edge. Each person’s role in LightHouse comes from the sign-in rules on the **Access** page or from a [directory group](/enterprise/provisioning/#directory-group-sign-in-rules). A person whom no rule admits is refused. | Provider | Second factor | | -------------------------------------- | ----------------------------- | | Entra ID, Okta | Proved by the provider | | Google Workspace, SAML, OpenID Connect | Required by Cloudflare Access | `GET /api/v1/me` shows how a person’s second factor was proved. ## One-time PIN, secrets and disconnection | Action | Effect | | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Stop offering the one-time PIN** | Retires the email one-time PIN that a tenant created by sign-up starts with. Available once a provider the administrator connected has been tested and turned on | | **Replace secret** | Sends a new client secret to Cloudflare Access; the previous secret is no longer used | | **Disconnect** | Removes the provider, its Access policy and its entry on the tenant’s sign-in page | A provider can be disconnected, or the one-time PIN retired, only while another active sign-in method remains for the tenant’s administrators. Providers configured by Atlantic before self-service single sign-on was available are shown as **Set up by Atlantic** and remain in use. Changes to them are made through Atlantic support. ## API | Route | Role | Action | | ------------------------------ | ---------------------------------------- | -------------------------------------------------------------------------- | | `GET /api/v1/sso` | `client_admin` | Lists the providers, their states and the values for the identity provider | | `POST /api/v1/sso` | `client_admin`, a person | Connects a provider in the state **Testing** | | `POST /api/v1/sso/{id}/test` | A person signed in through that provider | Confirms the test | | `POST /api/v1/sso/{id}/enable` | `client_admin`, a person | Turns the provider on: `{"email_domains": [...], "all_users": false}` | | `POST /api/v1/sso/{id}/secret` | `client_admin`, a person | Replaces the client secret | | `DELETE /api/v1/sso/{id}` | `client_admin`, a person | Disconnects the provider | | `POST /api/v1/sso/otp/retire` | `client_admin`, a person | Retires the one-time PIN | ## Audit Each step is recorded in the tenant’s audit log with the person who made it: `sso_provider_connected`, `sso_provider_tested`, `sso_provider_enabled`, `sso_secret_replaced`, `sso_provider_removed` and `sso_otp_retired`. The client secret is not written to the log. Source: https://docs.atlanticagenticlabs.com/enterprise/single-sign-on/ --- # SCIM provisioning > SCIM 2.0 provisioning of LightHouse users and groups from the organisation's directory, including deprovisioning. LightHouse™ accepts SCIM 2.0 provisioning (RFC 7643 and RFC 7644) from Microsoft Entra ID, Okta or any directory that sends standard SCIM. The directory creates, updates, deactivates and deletes users and groups in the tenant. ## Scope Provisioning records who is in the directory, who is active and which groups each person belongs to. It operates with [single sign-on](/enterprise/single-sign-on/) and the sign-in rules on the **Access** page: | Subject | Behaviour | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Roles** | A role comes from a sign-in rule. A **Directory group** rule gives a role to the active members of a provisioned group. Domain, group and named-person rules continue to apply | | **Deprovisioning** | Takes precedence over every rule. A person the directory has deactivated or deleted is refused from their next request, including where a domain or group rule matches them. Their delegated tokens (CLI and MCP clients) are revoked immediately | | **API keys** | Unaffected. Keys belong to the tenant’s machines and are listed in the [access review](/security/verify/#with-your-tenants-credentials) | | **Matching** | A provisioned user is matched to a person by email address: the primary email, or the `userName` where it is an email address. It must be the address the person signs in with | ## Endpoint and token **Access → Provisioning** requires `client_admin`, signed in as a person. | | | | ------------------ | --------------------------------------------------------- | | **SCIM base URL** | `https://.atlanticagenticlabs.com/api/scim/v2` | | **Authentication** | A bearer token: `Authorization: Bearer ` | Choose **Create token**. The token is shown once; enter it in the directory at that point. LightHouse stores only its SHA-256 hash, and the token is accepted only at the tenant’s own host. | Action | Effect | | ------------------------- | --------------------------------------------------------------------------------------------------------- | | **Create token** | Issues the tenant’s one live token | | **Replace token** | Issues a new token and revokes the previous one immediately. Enter the new token in the directory at once | | **Turn off provisioning** | Revokes the token. People already deactivated remain refused | The page shows whether provisioning is on, when the token was issued and last used, counts of active and deactivated users and of groups, and the recent provisioning events. ## Directory configuration **Microsoft Entra ID** 1. In the Microsoft Entra admin centre, open **Enterprise applications** and choose **New application → Create your own application**, as a non-gallery application. An existing enterprise application for LightHouse sign-in can be used instead. 2. Open **Provisioning**, and set **Provisioning Mode** to **Automatic**. 3. Under **Admin Credentials**, set **Tenant URL** to the SCIM base URL and **Secret Token** to the token from LightHouse. Choose **Test Connection**, then **Save**. 4. Under **Mappings**, check that `userName` is mapped to the attribute that holds the address people sign in with (usually `userPrincipalName` or `mail`), and that `emails[type eq "work"].value` is mapped to `mail`. Keep the `active` mapping; it deactivates the user when the account is disabled. 5. Under **Users and groups**, assign the users and groups to provision. 6. Set **Provisioning Status** to **On** and save. Result: Entra ID provisions on its own schedule. **Provision on demand** provisions one user immediately, for a check; the user appears in the counts on **Access → Provisioning**. **Okta** 1. In the Okta admin console, open the app integration used for LightHouse sign-in. On its **General** tab, under **App Settings**, enable **SCIM provisioning** and save. 2. On the **Provisioning** tab, under **Integration**, set **SCIM connector base URL** to the SCIM base URL and **Unique identifier field for users** to `userName`. 3. Under **Supported provisioning actions**, select **Push New Users**, **Push Profile Updates** and **Push Groups**. 4. Set **Authentication Mode** to **HTTP Header**, and paste the token from LightHouse as the bearer token. Choose **Test Connector Configuration**, then **Save**. 5. Under **Provisioning → To App**, enable **Create Users**, **Update User Attributes** and **Deactivate Users**. 6. On the **Assignments** tab, assign the people and groups to provision. On the **Push Groups** tab, push the groups that sign-in rules will name. Result: the users and groups appear in the counts and recent events on **Access → Provisioning**. ## Directory group sign-in rules On the **Access** page, add a rule of the kind **Directory group (SCIM)**, enter the group’s display name exactly as the directory sends it, and choose the role. The rule admits the group’s active members. Membership is read on every request. A person removed from the group loses the role from their next request, and a delegated token issued under that rule stops working. ## Deprovisioning When the directory deactivates a user (`active: false`) or deletes one, LightHouse refuses that person from their next request and revokes their delegated tokens. A deleted user is retained as a deletion record, which prevents a domain rule from admitting the person again. The record is replaced only if the directory provisions the same `userName` again. ## Supported operations | Resource | Operations | | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | `ServiceProviderConfig`, `ResourceTypes`, `Schemas` | `GET` | | `Users` | `GET` (with `filter`, `startIndex` and `count`), `POST`; on one user `GET`, `PUT`, `PATCH`, `DELETE` | | `Groups` | `GET` (with `filter`), `POST`; on one group `GET`, `PUT`, `PATCH`, `DELETE` | Filters: for users, `userName eq`, `externalId eq` and `emails.value eq`; for groups, `displayName eq` and `externalId eq`. `PATCH` accepts the operation shapes that Entra ID and Okta send. Users and groups are held per tenant under row-level security; an identifier from another tenant returns not found. ## Portal API | Route | Role | Action | | --------------------------- | ------------------------ | ----------------------------------------------------------------- | | `GET /api/v1/scim` | `client_admin` | Returns the base URL, the token’s state, counts and recent events | | `POST /api/v1/scim/token` | `client_admin`, a person | Issues a token, shown once; the previous one stops working | | `DELETE /api/v1/scim/token` | `client_admin`, a person | Turns provisioning off | ## Audit Token changes are recorded in the tenant’s audit log with the person who made them (`scim_token_issued`, `scim_token_revoked`). The directory’s changes are recorded with the actor `scim`: `scim_user_created`, `scim_user_deactivated`, `scim_user_reactivated`, `scim_user_deleted`, `scim_group_created`, `scim_group_changed` and `scim_group_deleted`. Source: https://docs.atlanticagenticlabs.com/enterprise/provisioning/ --- # Inviting people > Invite a named person by email with a role and an end date. The invitation is a time-limited sign-in rule. An invitation gives one named person access to the tenant for a set period, for example an auditor, a contractor or a colleague outside the directory. Invitations are managed at **Access → Invitations**. ## Requirements | Requirement | Detail | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | Role | `client_admin`, signed in as a person | | Invitee | An email address. Atlantic staff cannot be invited; their access is set separately on the **Access** page | | Reachability | Where the tenant does not offer the one-time PIN, the address’s domain must be admitted by a sign-in rule for the identity provider | ## Effect of an invitation Sending an invitation: 1. adds a **Named person** sign-in rule for the email address, with the chosen role and end date; 2. where the tenant offers the one-time PIN, adds the address to the PIN’s Cloudflare Access policy; 3. sends the person an email in the tenant’s language, naming the administrator who sent it and giving the portal address. The email contains no link token or other credential. The person signs in through Cloudflare Access, with a one-time PIN sent to their own mailbox or through the organisation’s identity provider. ## Procedure 1. Under **Invite someone**, enter the **Email address**. 2. Choose the **Role**. The default is `viewer`. Choosing `client_admin` displays a warning: a client administrator can change who signs in, issue keys and read the audit log. See [Roles](/api/roles/). 3. Set **Access for**, in days: 30 by default, from 1 to 366. 4. Optionally add a **Note**, up to 160 characters. 5. Choose **Send invitation**. Result: the invitation is listed as **Pending**, with the sign-in method that applies to it. If the email cannot be delivered, the invitation is still created; give the person the portal address directly. ## Sign-in method | Tenant configuration | Sign-in | | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | The tenant offers the one-time PIN | The person enters their address at sign-in and receives a one-time code | | The tenant does not offer the PIN | Only addresses whose domain is admitted by a sign-in rule can be invited. Other addresses are refused with `not_reachable`; add the person through the identity provider instead | ## States | State | Meaning | | ---------------- | ---------------------------------------------------------------------------------------------------- | | **Pending** | Sent; the person has not signed in | | **Accepted** | The person has signed in | | **Expired** | The end date has passed. The rule’s expiry is checked on every request, and access ends on that date | | **Revoked** | A client administrator revoked the invitation | | **Rule removed** | The sign-in rule behind it was removed on the **Access** page | **Revoke** removes the sign-in rule, removes the address from the one-time PIN policy where the invitation added it, and erases the person’s profile. ## Limits | Limit | Value | | ---------------------- | ------------------------------------------------------------------------------------------------------------------ | | Duration | 1 to 366 days; default 30 | | Invitations per tenant | 50 per day; the page shows the number remaining | | Repeat invitation | Refused while an invitation to the same address is pending | | Public mailboxes | Accepted for a named person (such as a `gmail.com` address). Public mail domains are refused only for domain rules | | Client administrators | At least one must remain | ## API | Route | Role | Action | | --------------------------------- | ------------------------ | ---------------------------------------------------------------- | | `GET /api/v1/invitations` | `client_admin` | Lists every invitation and its state | | `POST /api/v1/invitations` | `client_admin`, a person | Sends an invitation: `{"email", "role", "expires_days", "note"}` | | `DELETE /api/v1/invitations/{id}` | `client_admin`, a person | Revokes the invitation | ## Audit Each invitation sent, accepted and revoked is recorded in the tenant’s audit log as `invitation_sent`, `invitation_accepted` or `invitation_revoked`. Source: https://docs.atlanticagenticlabs.com/enterprise/invitations/ --- # Choosing air-gapped > The air-gapped option for agents on the organisation's own servers: what changes, what the stack contains, and how the site reports to LightHouse. An air-gapped site is a deployment on the organisation’s own servers with no network path to LightHouse™. For such a site, LightHouse writes the stack in the engine’s offline mode, and the set-up mission counts the site as reporting once its first telemetry bundle has been imported. ## Requirements | Requirement | Detail | | ------------------ | ---------------------------------------------------------------------------------------------- | | Role | `client_admin` | | Where agents run | **Your own machines**. A cloud deployment always has an outbound path and cannot be air-gapped | | Deployment profile | Always-on. The offline relay keeps its spool on persistent disk | ## Selection On **Where agents run**, choose **Your own machines**, then under **How it reaches LightHouse**: | Option | Meaning | | -------------------- | ------------------------------------------------------------------------------------------------------------------ | | **Online** (default) | One outbound connection to LightHouse, direct or through the organisation’s proxy. Telemetry and commands are live | | **Air-gapped** | No network path to LightHouse. Data that would cross the network is transferred by hand as signed files | The choice is recorded in the tenant’s audit log. Through the API, `PUT /api/v1/run-targets` takes `connectivity`: `online` or `air_gapped`. A request for air-gapped with a cloud, or with a profile other than always-on, is refused. ## Differences from an online site | Area | Air-gapped behaviour | | --------------------- | ------------------------------------------------------------------------------------------------- | | **Telemetry** | Written to signed bundle files, transferred and imported in LightHouse | | **Commands** | Exported from LightHouse as a signed command file; results return the same way | | **Images and models** | Taken from Atlantic’s signed mirror and loaded into the organisation’s own registry and disk | | **Content** | Not read in place. LightHouse shows records and metrics only, current to the last imported bundle | [Air-gapped operation](/clouds/on-premises/#air-gapped-operation) describes how each file is signed and verified; the integrity of a transfer does not depend on the person who carries it. ## Stack contents **Get my stack** for an air-gapped site writes the same Compose stack as for an online site, with these differences: | Component | Air-gapped configuration | | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Relay | Offline mode: makes no outbound requests, seals signed bundles into its spool, has no proxy setting | | Content reader and live command channel | Not included | | Command handler | File-based: applies a signed command file placed in `./carry/in` and writes signed results to `./carry/out` | | `.env` | Takes images from the organisation’s own registry through one setting, which the mirror tooling rewrites; every digest is unchanged | | Guide | `lighthouse-air-gapped.md`, with the round trip in the engine’s and the CLI’s commands, and the tenant and deployment filled in | ## Procedure 1. **Once per release**: pack the images and models on a connected machine, transfer them, verify them on the site, and load them into the registry and model directory. Result: the release’s images and models are available on the site with their digests verified. 2. Start the stack and run its check. 3. **Telemetry out**: export the bundles written since the last one LightHouse holds, verify them, transfer them and import them in LightHouse (on the deployment’s page, or with `lighthouse-ai telemetry import`). Result: the deployment’s page shows the time of the last imported bundle. 4. **Commands in, results out**: export the command file from LightHouse (or with `lighthouse-ai commands export`), transfer it to the site and apply it; return the results with the next bundles. Result: the command results appear in LightHouse when that bundle is imported. ## Set-up mission The **See your stack report in** step is complete for an air-gapped site once a telemetry bundle from it has been imported. See [Organisation set-up](/enterprise/#in-the-set-up-mission). ## Manual settings **Get my stack** does not yet write two settings for a site with no internet access; they are added to the `.env` by hand: the offline profile for local inference, and the setting that loads retrieval’s models only from the installed mirror. [Self-hosted models](/clouds/on-premises/#self-hosted-models) and [Air-gapped operation](/clouds/on-premises/#air-gapped-operation) describe both. Source: https://docs.atlanticagenticlabs.com/enterprise/air-gapped/ --- # The security review pack > Atlantic's standard answers to a security questionnaire, each with the document that evidences it, in LightHouse and as a download. The **security review pack** is Atlantic’s versioned, dated set of standard answers to security questionnaires, each naming the document that evidences it. It is at **Settings → Security review** in LightHouse™ and is available to every role. ## Coverage | | | | ---------------------------------------- | --------------------------- | | Governance | Access control | | Identity and multi-factor authentication | Encryption | | Key management | Data location and residency | | Tenant isolation | Logging and audit | | Vulnerability management | Secure development | | Incident response and support | Vulnerability disclosure | | Business continuity and backups | Sub-processors | | Personal data and the DPA | Artificial intelligence | | Insurance | Certifications | The page also links the agreements in force, the [sub-processor list](/trust/subprocessors/) and the [security controls summary](/trust/security-controls/). ## Formats | Format | Content | | ------------------- | ------------------------------------------------------------------------------------------------------------------------- | | **Download (CSV)** | One answer per row, for transfer to a questionnaire. Cells that a spreadsheet would interpret as formulae are neutralised | | **Download (JSON)** | The same answers in a machine-readable file | | API | `GET /api/v1/security-review?format=csv` or `?format=json`, for any role in the tenant | The answers are in English, the language of the agreements. The surrounding page follows the tenant’s language setting. ## Maintenance | Control | Detail | | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Single source** | The page, the CSV, the JSON and the API read the same answers | | **Agreement versions** | Answers that name the MSA and DPA take the versions in force from LightHouse | | **Wording check** | An answer set that claims a certification, offers a guarantee or states outright that the service meets a standard is refused before publication. Certification to ISO/IEC 27001 and ISO/IEC 42001 is under way, and the pack states it in those terms | | **Evidence** | Each answer names its supporting document, published on the company site or on this site, or available under NDA | | **Versioning** | A change produces a new version. The version and date are shown on the page and in each download | ## Under NDA The pack contains no detail that would weaken a control if published. Further detail, including the architecture, configuration defaults, evaluation results and security assessment summaries, is available to named people under a mutual NDA, with a security walk-through by our certified forward-deployed engineers. See [Verify it yourself](/security/verify/#what-we-will-show-under-nda). Source: https://docs.atlanticagenticlabs.com/enterprise/security-review/ --- # What Octy is > Octy is Atlantic's conversational agent: it answers questions from an organisation's own knowledge, with a citation for every source, inside the organisation's deployment and at a recorded cost. **Octy™** answers questions from the organisation’s own knowledge: product documentation, policies, support content or sector regulation. Each answer cites the passages it was written from. Octy runs inside the organisation’s deployment, on the organisation’s models, and the cost of every model call is recorded in LightHouse™. Octy is one agent, with the same code, character and rules in every deployment. Each use is defined by an **Octy profile**: the knowledge it may read, who may ask it, the channels they use, the limits it runs under and where it runs. Client administrators create and manage Octy profiles in LightHouse. See [Octy profiles](/octy/profiles/) and [Manage Octy profiles](/octy/manage/). ## What it does - **Answers from the organisation’s knowledge.** Octy searches only the knowledge its profile names, within the access of the person asking, and answers from the passages it finds. Every answer cites its sources. When the knowledge does not cover a question, the answer states this. See [Knowledge and boundaries](/octy/knowledge/). - **Shows its evidence.** The sources behind an answer are shown with it, and each answer is checked against them before it is sent. Each answer carries a signed receipt that any party can verify. See [Evidence and question insights](/octy/evidence/). - **Does not act.** Octy answers, explains and routes. It holds no tool that approves, pays, changes access or changes a limit. Work goes to an agent, through an approval card that a person approves in LightHouse. See [Octy and agents](/octy/agents/). ## Cost Octy answers at the lowest cost that meets the profile’s quality bar. 1. **Retrieval first.** The knowledge base is searched inside the deployment, with no call to a model provider. A question the knowledge does not cover receives a “not covered” answer before an answering model is called. Answers composed of the retrieved passages, quoted with their sources, call no model. 2. **The cheapest model that meets the bar.** When an answer needs an explanation, a small model writes it from the retrieved passages, through the organisation’s gateway. Every such answer goes through the profile’s router, which selects the cheapest model that meets the profile’s quality bar and escalates only when an answer misses it. See [The router for every profile](/octy/router/). An explained answer typically costs a fraction of a cent, estimated. Sending every question to a large model costs many times more, estimated. 3. **A cap on every profile.** Each profile has a monthly spend cap, enforced before a model is called. See [Controls](/octy/controls/). One question to Octy 1. A question arrives from the profile's audience, on one of its channels. 2. Controls: who may ask, from where, how often, and within the spend cap. A question refused here costs nothing. 3. Retrieval searches the profile's knowledge only, within the caller's access scope. 4. Not covered: if nothing is relevant enough, Octy says so, and no answering model is called. 5. Retrieval answer (Coming): the passages themselves, quoted with their sources, and no model is called. 6. Explained answer: a small model writes the answer from the passages, through your gateway. The router choosing the cheapest model that meets the quality bar for each answer is Coming. 7. Evidence: every source is cited with the answer. A signed receipt is Coming. 8. Measurement: counts, timings and the cost of each answer go to LightHouse. No content does. Most of the work is retrieval, which runs in your deployment at almost no cost. A model is called only when an answer needs explaining, and then a small one. Dashed stages are Coming. [Cost analysis](/octy/costs/) describes how cost is measured for each profile. Every figure is labelled estimated. ## Where it runs An Octy profile runs where its knowledge is held. A profile over the organisation’s own knowledge runs in the organisation’s deployment: in its AWS, Azure or Google Cloud account, on its own servers, or air-gapped on local models, under any deployment profile. The profile uses the organisation’s models through its gateway, and the organisation pays its own provider. The knowledge remains in the organisation’s account and is read in place. Atlantic hosts the profiles that answer from Atlantic’s public material and from the tenant’s LightHouse data. See [Where Octy runs](/octy/where-it-runs/). ## Status | Capability | Status | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | Octy in a client deployment: answers from the organisation’s documents with citations, for people signed in through its identity provider | Built | | Octy in the LightHouse portal, answering from the tenant’s data under the person’s role | Built | | Channels: a web widget for the organisation’s website or intranet, Microsoft Teams, Slack, MCP for other agents | Built | | Controls: a monthly spend cap, rate limits per person, allowed origins | Built | | “Not covered” before any model is called; refusal of any request to act | Built | | Octy on these docs: answers from this documentation, with a monthly cap and rate limits | Built | | Retrieval answers with no model call, for every profile | Built | | The evidence panel and signed receipts | Built | | The Octy profiles page in LightHouse: create, test, publish, pause and delete a profile, with its knowledge, channels, controls and router, and the audit of every change | Built | | Profiles applied to a client deployment by signed command, or by command file when it is air-gapped | Built | | Rate limits per visitor, per session and overall; address allow and deny lists; allowed pages; the bot check for public profiles | Built | | The router for every profile, with each decision and escalation recorded | Built | | The website widget for any profile, the web panel, and the MCP and API channels per profile | Built | | Cost analysis and question insights for each profile | Built | | Octy profiles consulting each other | \[Coming] | ## In this section - [Octy profiles](/octy/profiles/): what a profile holds, its states and revisions, and the rules every profile keeps. - [Manage Octy profiles](/octy/manage/): the LightHouse page, from draft to live profile, and how a change reaches a deployment. - [Knowledge and boundaries](/octy/knowledge/): the knowledge Octy answers from, and how the boundary is enforced. - [Controls](/octy/controls/): who can ask, from where, how often and at what cost, in order of enforcement. - [The router for every profile](/octy/router/): the cheapest model that meets the profile’s quality bar. - [Cost analysis](/octy/costs/): model cost per answer, and the cost figures for each profile. - [Evidence and question insights](/octy/evidence/): citations, the evidence panel, verifiable receipts, and the questions each profile receives. - [Where Octy runs](/octy/where-it-runs/): Atlantic-hosted, each cloud, the organisation’s own servers, air-gapped, and each deployment profile. - [Channels](/octy/channels/): the web panel, the widget, the portal, Teams, Slack, MCP and the API. - [The website widget](/octy/widget/): the script tag, its content security policy, and the checks the service enforces. - [Octy and agents](/octy/agents/): how Octy differs from agents, and how it hands work to them. Source: https://docs.atlanticagenticlabs.com/octy/ --- # Octy profiles > An Octy profile is the configuration that puts Octy on a knowledge base for an audience: its knowledge, tier, channels, controls, router and where it runs. An Octy™ profile lets the organisation put Octy on a chosen body of knowledge for a chosen audience, with its own limits and monthly cap, without changing code. Octy is the same agent in every deployment, with an **Octy profile** for each use. A profile is configuration: it names the knowledge Octy may read, who may ask it, where they ask, the limits it runs under, how its models are chosen, and where it runs. Octy’s character and rules are defined in code. Profile settings cannot change them or grant a tool that writes, approves, pays or changes access. Octy profiles are managed on the **Octy profiles** page in LightHouse™ and applied to a client deployment by signed command. A client deployment applies them when its policy turns on `octy_profiles`, which is off by default. Without it, Octy in a client deployment is configured in one file in the organisation’s catalogue repository, as described [below](#before-octy-profiles). **An Octy profile**: set by client administrators in LightHouse - **Name and scope**: a short name, and one or two sentences on what it answers about - **Tier and audience**: public, NDA or internal; the public, signed-in customers, or staff - **Knowledge**: the corpora it may search, all held where the profile runs - **Channels**: web panel, website widget, portal, Teams, Slack, MCP, API - **Controls**: rate limits, address lists, origins and pages, bot check, monthly cap - **Router**: a quality bar, and optionally the models it may choose from - **Runs on**: Atlantic-hosted, or one of the organisation’s deployments Checked by LightHouse; enforced where the profile runs, outside the prompt - **Boundary** (downward): only the profile’s knowledge, within the caller’s access - **Controls** (downward): checked on every request, before any model is called - **Router** (downward): the cheapest model that meets the profile’s bar **Octy**: the same code, character and rules everywhere - **Answers**: from retrieved passages, each source cited - **Says when it cannot**: “not covered”, before an answering model is called - **Does not act**: no tool that approves, pays or changes access or a limit - **Hands work on**: to an agent, through an approval card A profile is configuration. LightHouse checks it on every change and again on publishing. The service that answers applies its boundary and controls outside the model's prompt, and the text of a question cannot widen them. ## The settings | Setting | Values | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Name and short name** | A display name, and a short name of lower-case letters, digits and hyphens that appears in the profile’s address and in the widget | | **Scope** | One or two plain sentences on what the profile answers about, shown to the people it answers. It sets the subject; it cannot change Octy’s rules | | **Disclosure tier** | Public, NDA or internal. The tier limits the knowledge the profile may hold. See [Disclosure tiers](/octy/knowledge/#disclosure-tiers) | | **Audience** | The public; signed-in customers; staff, through the organisation’s sign-in | | **Knowledge** | One or more corpora: a knowledge base, a [connected source](/connect/), an uploaded collection, the tenant’s LightHouse data, or Atlantic’s public documentation and published knowledge. See [Knowledge and boundaries](/octy/knowledge/) | | **Runs on** | Atlantic-hosted, or a named deployment of yours. A profile runs where its knowledge is held. See [Where Octy runs](/octy/where-it-runs/) | | **Channels** | Web panel, website widget, LightHouse portal, Microsoft Teams, Slack, MCP and the API, each switched on or off. See [Channels](/octy/channels/) | | **Controls** | Rate limits per visitor, per session and overall, with separate limits for answers that use a model; address allow and deny lists; allowed origins and pages; the bot check; a monthly cap with an alert. See [Controls](/octy/controls/) | | **Router** | A quality bar (standard, high or strict) and, optionally, the models the router may choose from. See [The router for every profile](/octy/router/) | Each tier has its own default controls, which LightHouse fills in when a profile is created or its tier changes, and which an administrator can then adjust within fixed ceilings. The defaults and ceilings are in the client documentation. ## States and revisions A profile is in one of three states: | State | What it means | | ---------- | ------------------------------------------------------------------------------------------------------- | | **Draft** | The initial state of every profile. Answers only test questions from a `client_admin` in the test panel | | **Live** | Published: it answers its audience on its channels | | **Paused** | Does not answer until resumed. A visitor receives a notice that Octy is unavailable | Every change makes a new **revision**, numbered from 1. Publishing runs every check again. An edit made against an earlier revision is refused. A live profile must be paused before it is deleted. See [Manage Octy profiles](/octy/manage/). ## Rules every profile keeps LightHouse checks these on every change and again on publishing, and refuses a profile that breaks one, naming the field. - **The tier fits the audience.** A public audience needs the public tier; the public tier answers only the public or signed-in customers. - **A public profile holds only published knowledge.** A corpus counts as published only when every document in it is cleared for the public tier. LightHouse determines this from the deployment’s report on its index. Values in the request are not used. - **A public profile has the bot check on.** It cannot be turned off for a public audience. - **Knowledge is read where it is held.** A profile over the client’s own knowledge runs in the client’s deployment. A profile over the tenant’s LightHouse data or Atlantic’s public material runs at Atlantic. A profile cannot mix the two. LightHouse does not store client content. - **Channels fit the audience.** The widget needs at least one allowed origin; MCP and the API need an audience that signs in; Teams and Slack need a deployment with that channel connected. - **The boundary is enforced in the engine.** A profile sees only its own corpora. The limit is applied inside the search, by the same access scoping that limits what a person can search, so the text of a question cannot widen it. - **Actions require a person.** A profile can hand work to an agent where its audience is signed in. It holds no approval, payment, role or key tool. See [Octy and agents](/octy/agents/). - **Who pays.** Profiles in a client deployment run on the client’s models, through its gateway, and the client pays its own provider. Atlantic-hosted profiles run in Atlantic’s account. - **Client separation.** Conversations, indexes, memory and credentials are not shared between one client’s profiles and another’s. ## Built-in profiles and profiles in use | Profile | Knowledge | Audience | Runs on | Status | | ----------------------------- | --------------------------------------------------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------- | | Octy in a client deployment | The organisation’s documents and sources, read in place | Staff, through the organisation’s channels | Client deployment | Built | | Octy in the LightHouse portal | The tenant’s LightHouse data, read under the person’s role | People signed in to the tenant | Atlantic-hosted | Built | | Octy on these docs | This documentation, the OpenAPI document and the MCP reference | The public | Atlantic-hosted | Built, as the built-in profile `docs` | | Client-created profiles | Any knowledge the deployment reports, or the tenant’s LightHouse data | Any audience the tier allows | Where the knowledge is | Built | Atlantic’s own public profiles, such as the one on these docs, are built-in profiles managed by Atlantic staff through the same checks. Their short name, owner and tier are fixed. ## Before Octy profiles Until the Octy profiles page is available in the tenant, Octy in a client deployment is configured in one file in the organisation’s catalogue repository, and released through the release gate like any agent change. Our certified forward-deployed engineers set it up and evaluate it with the organisation. Source: https://docs.atlanticagenticlabs.com/octy/profiles/ --- # Manage Octy profiles > The Octy profiles page in LightHouse: create a profile, test it, publish, pause, resume and delete it, view where it runs and whether its deployment applied it, and read the audit of every change. Client administrators create, test and publish Octy™ profiles in LightHouse without a release, and see for each profile where it runs, whether its deployment applied it, and every change in the audit. Octy profiles are managed in LightHouse under **Agents → Octy profiles**. The page lists the tenant’s profiles and where each runs, and links to each profile’s page. ## Who may do what | Role | Permitted actions | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Any role (`viewer` and above) | See the profiles, their settings, status, costs, the audit, and the widget’s snippet | | `content_viewer` and `client_admin` | Also read the redacted question text of a profile that runs in a client deployment, read in place. See [Question insights](/octy/evidence/#question-insights) | | `client_admin`, signed in as a person | Create, edit, test, publish, pause, resume and delete profiles; export a command file for an air-gapped deployment | A machine key cannot change a profile. Atlantic’s own public profiles are managed by Atlantic staff in the staff console, under the same checks and the same audit. ## Profile list **Profiles** shows each profile with its state (Draft, Live or Paused), its disclosure tier, its audience, where it runs and that deployment’s [deployment profile](/concepts/deployment-profiles/), its channels, model spend this month against its cap, and the answers given in the last 30 days. **Where they run** groups the profiles by location: Atlantic-hosted, or each of the client’s deployments. A deployment that sleeps between questions is marked as such, and an air-gapped deployment is marked offline. **Costs** opens the [cost analysis](/octy/costs/) for every profile. ## Create a profile 1. Choose **Create an Octy profile**. 2. **Name and scope.** Give the profile a name, a short name, and one or two sentences on what it answers about. 3. **Tier and audience.** Choose the disclosure tier and who may ask. LightHouse offers the tier’s default controls. Apply them, or keep the current values. 4. **Knowledge.** Choose corpora from those the client’s deployments report: knowledge bases, connected sources and uploaded collections, each with its document count and whether it is published. A corpus excluded by the tier or by where the profile runs is shown with the reason. 5. **Runs on.** Choose where the profile runs. This is where its knowledge is held. 6. **Channels.** Switch on the channels it answers on. A channel that the settings do not allow shows its requirement, such as an allowed origin for the widget. 7. **Controls.** Set the rate limits, the address lists, the allowed origins and pages, the bot check, the monthly cap and its alert, and the router’s quality bar and models. See [Controls](/octy/controls/) and [The router for every profile](/octy/router/). 8. Choose **Create draft**. Result: the profile is saved in the **Draft** state. It is published only when **Publish** is chosen. A field that breaks a rule is marked on the page, with the reason. The rules are in [Octy profiles](/octy/profiles/#rules-every-profile-keeps). ## Profile page Each profile’s page has six tabs: | Tab | What it shows | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Overview** | The profile’s knowledge, audience and channels; its status, including the revision its deployment applied and how the change travelled; and model spend this month | | **Settings** | Every setting, editable by a `client_admin`. Saving makes a new revision | | **Test** | A test panel. See [below](#test-before-publishing) | | **Widget** | The widget’s snippet and the content security policy entries for the website. See [The website widget](/octy/widget/) | | **Costs and questions** | The profile’s costs, the router’s decisions and its question insights. See [Cost analysis](/octy/costs/) and [Question insights](/octy/evidence/#question-insights) | | **Audit** | Every change, with its revision and the fields that changed | ## Test before publishing The **Test** tab answers questions from a draft, a live or a paused profile, as its audience would see the answer. Choose **Search only**, which uses no model, or **Explain with a model**, which goes through the router. Each test answer shows its passages, whether a model was used and what it cost. Test answers are marked as tests and visible only to the person testing. They are charged to the profile’s cap and recorded in the audit. They are excluded from the profile’s question insights and from the router’s evidence. ## Publish, pause, resume, delete | Action | From | What happens | | ----------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------- | | **Publish** | Draft or Paused | Every check runs again; the profile goes live and is sent to where it runs | | **Pause** | Live | The profile stops answering until it is resumed | | **Resume** | Paused | The profile answers again, at its current revision | | **Delete** | Draft or Paused | Its settings are removed and a remove command is sent to its deployment. A live profile must be paused first. The audit is kept | ## How a change reaches your deployment A profile that runs in a client deployment is applied there by a **signed command** from LightHouse, on publishing and on every later change, pause, resume or deletion. The command carries the profile and a digest of it. The deployment verifies Atlantic’s signature, as for every command, and then checks the profile before applying it. - **Client administrator**: in LightHouse - **LightHouse**: the tenant - **Client deployment**: the command handler and Octy A change 1. Client administrator to LightHouse: **Publish or change**. checked again; a new revision 2. LightHouse to Client deployment: **Signed command**. the profile and its digest, on the command channel, or in a command file for an air-gapped site Applied or refused 3. Client deployment: **Check and apply**. the signature, the deployment's policy, the digest, the revision, the corpora, the tier and the models 4. Client deployment to LightHouse: **Profile state**. applied, refused with a reason, or removed, in the deployment's signed telemetry LightHouse sends each change as a signed command, live or by command file. The deployment checks it, applies it or refuses it with a reason, and reports which revision it holds. The profile's status in LightHouse comes from that report. The deployment refuses a profile, with a reason, when: - the digest does not match the profile; - it already holds a newer revision; - the profile names a corpus the deployment does not have; - a public profile would read documents that are not public; - an air-gapped deployment is asked to use a model it does not serve locally; - a limit is outside the allowed range. The **Overview** tab shows the status: **Applied**, **Refused** with the reason, or **Pending**. Profile commands are off by default in the deployment’s policy, like every command type. The policy names the roles that may send them. **Air-gapped deployments.** The command goes into the next command file. The profile shows **Waiting for the command file**, with a link to export it. Transfer the file to the site and apply it, as for any command file. The profile shows as applied once the site’s next telemetry bundle is imported. See [Air-gapped operation](/clouds/on-premises/#air-gapped-operation). ## The audit Every change is recorded in the tenant’s audit log and on the profile’s **Audit** tab: created, changed, published, paused, resumed, tested and deleted, each with the person, the time, the revision and, for a change to the controls, the fields that changed with their old and new values. The audit does not record question text. ## The API and the MCP tool The same operations are in the [LightHouse API](/api/) under `/api/v1/octy-profiles`: | Route | What it does | | ------------------------------------------------------------------- | --------------------------------------------------------------------- | | `GET /api/v1/octy-profiles` | The profiles, and the default controls for each tier | | `POST /api/v1/octy-profiles` | Create a profile, as a draft | | `GET /api/v1/octy-profiles/{id}` | One profile, its status and its recent audit | | `PUT /api/v1/octy-profiles/{id}` | Replace its settings, with `If-Match: ` | | `POST /api/v1/octy-profiles/{id}/publish`, `/pause`, `/resume` | Change its state | | `DELETE /api/v1/octy-profiles/{id}` | Delete a draft or paused profile | | `POST /api/v1/octy-profiles/{id}/test` | A test answer | | `GET /api/v1/octy-profiles/{id}/widget` | The widget’s snippet and content security policy entries | | `GET /api/v1/octy-profiles/corpora` | The corpora the client’s deployments report, for the knowledge picker | | `GET /api/v1/octy-profiles/costs`, `/{id}/costs`, `/{id}/questions` | Cost analysis and question insights | A refused change returns `422` with the error code and the field concerned. An edit without `If-Match` returns `428`, and an edit against an old revision returns `409`. The [MCP server](/mcp/) provides an `ask_octy` tool: a profile’s short name and a question, asked as the caller, read only. Source: https://docs.atlanticagenticlabs.com/octy/manage/ --- # Knowledge and boundaries > The knowledge Octy answers from, how its boundary is enforced in the engine, and how disclosure tiers separate public and internal knowledge. Octy™ answers only from the knowledge its profile names, within the access of the person asking. The organisation’s documents are indexed and searched in its own account, and the boundary is enforced in the search. ## Knowledge A profile names one or more **corpora**: indexed collections of documents that Octy may search. A corpus can be: - **The organisation’s documents**: product documentation, policies, procedures, standards, support articles, contracts and guidance, indexed in the deployment. - **Connected sources**: SharePoint, Confluence, Amazon S3, Google Drive and the other systems in the [connector catalogue](/connect/), synced into the deployment on their own schedules. - **Uploaded collections**: files [uploaded](/connect/upload/) for a specific purpose. - **The tenant’s LightHouse™ data**: for Octy in the LightHouse portal, which reads the tenant’s agents, runs, costs and approvals through the same read routes as the API, under the person’s role. - **Published knowledge**: a public corpus, such as the regulation of a sector, curated and published for Octy to answer from. Every corpus is indexed and searched inside the deployment, in the organisation’s account. The documents, passages and indexes are stored there and read in place. See [How retrieval works](/concepts/retrieval/) and [Knowledge bases](/concepts/knowledge-bases/). ## The boundary The engine enforces the boundary outside the model’s prompt: - **The profile’s corpora only.** A search runs only over the corpora the profile names. Other corpora in the same deployment are excluded. - **The caller’s access.** Each document carries its access classification. The search applies the person’s access, taken from the identity provider’s sign-in, inside the query. Passages outside the person’s access are not retrieved. - **The channel’s access.** Each channel can be limited to specific classes of document. For example, a Slack or Teams channel can be limited to internal documents for every person who asks there. - **Retrieved text is evidence.** Passages reach the model inside sealed fences, as evidence to answer from. Instructions written in a document are not followed. See [MCP security](/security/mcp/) for the red-team suite that tests this. The boundary is applied in the search, and the wording of a question cannot widen it. ## Disclosure tiers Each profile has a **disclosure tier**: | Tier | Audience | Permitted knowledge | | ------------ | ----------------------------------------------------------------- | ----------------------------------------------------------------------- | | **Public** | Anyone, on a public website | Knowledge cleared for publication that has passed the publication guard | | **NDA** | Clients and prospects under a non-disclosure agreement, signed in | Knowledge cleared for readers under the agreement | | **Internal** | The organisation’s staff, signed in through its identity provider | Internal knowledge, within each person’s access | A public profile cannot hold an NDA or internal corpus. Atlantic’s own public Octy profiles answer only from knowledge that has passed the publication guard. For an Octy profile, the tier is checked when a profile is saved and again when it is published. A corpus is treated as published only when the deployment reports every document in it at the public tier. The deployment checks the tier again before it applies the profile, and for a public profile the search is limited to public documents. ## When the knowledge does not cover a question If no passage in the profile’s knowledge is sufficiently relevant, Octy states that the knowledge does not cover the question. This happens before an answering model is called, and the cost of the answer is close to zero. Octy does not answer from a model’s general knowledge. A question that matches the words of a document but not its facts reaches the model, which is instructed to state that the passages do not answer it. The answer is checked against its sources before it is sent. See [Evidence and question insights](/octy/evidence/). ## Keeping knowledge current Connected sources sync on their own schedules. New and changed documents are indexed, and deleted documents are removed. A document deleted at its source is not retrieved after the next sync. See [How retrieval works](/concepts/retrieval/#when-something-is-deleted). The knowledge picker on the Octy profiles page: choosing a profile’s corpora from the knowledge bases, connected sources and uploaded collections the organisation’s deployments report, each with its document count and publication state. [Question insights](/octy/evidence/#question-insights) list the questions the knowledge did not cover. Source: https://docs.atlanticagenticlabs.com/octy/knowledge/ --- # Controls > The controls on an Octy profile, in order of enforcement: sign-in, rate limits, address allow and deny lists, allowed origins and pages, the bot check and the monthly cap. The organisation sets, for each Octy™ profile, who may ask it, from which networks and websites, how often, and the maximum monthly model spend. Controls are checked on every request before any work is done, and a refused request incurs no cost. ## Controls | Control | What it does | Status | | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------ | | Sign-in | Staff and customer profiles answer only people signed in through the organisation’s identity provider | Built | | Rate limits per person | A limit per minute and per day for each person | Built | | Allowed origins | The websites from which the widget may call Octy | Built | | Spend cap | A daily and a monthly cap in the deployment, and a monthly Octy limit in LightHouse™ | Built | | Rate limits per profile | Per visitor, per session and overall, with separate limits for answers that use a model, and a limit on model steps per answer | Built | | Address allow and deny lists | The networks from which a profile may, or may not, be asked | Built | | Allowed pages | The pages of a website on which the widget may appear | Built | | Bot check | A check that a visitor is a person before an answer uses a model; always on for a public audience | Built | | Monthly cap per profile | A hard cap on the profile’s model spend, with an alert before it is reached | Built | ## The order of enforcement Controls set per profile on the Octy profiles page, enforced in this order by the service that answers the profile. 1. **The profile is live** : an unknown profile is not found; a paused one is unavailable Otherwise: Unavailable the request ends 2. **The address** : the deny list, then the allow list Otherwise: Refused the address is not allowed 3. **The origin and the page** : a listed website, and a page path the profile allows Otherwise: Refused another website or another page 4. **The rate limits** : per visitor, per session, then for every visitor together Otherwise: Wait the visitor receives a notice to try again later 5. **Retrieval** (no model) : the profile's knowledge, within the caller's access 6. **For a model answer** : the model limits, the bot check, then a reservation against the monthly cap Otherwise: Retrieval only with the cap reached, Octy answers from the passages, or states that the question is not covered 7. **The router** (a model call) : the cheapest model that meets the bar, for at most the profile's model steps Every request passes these checks in order, before retrieval. The last three apply only when the answer needs a model, and a question answered from retrieval alone does not reach them. The first refusal ends the request. For an Atlantic-hosted profile, the same address, origin and per-address minute limits are also applied at Atlantic’s edge, before a request reaches LightHouse. The edge limits are no stricter than the service’s. A request that the edge cannot check is passed to the service, and the service’s checks are authoritative. ## Rate limits A profile has limits per minute, per hour and per day: - **per visitor**, identified by a keyed hash of the address, held in memory only and not stored; - **per session**, for a visitor who keeps a session; - **for every visitor together**, per minute; - **for answers that use a model**, separately per visitor, per session and overall. Answers from retrieval alone do not count towards these limits; - **model steps per answer**: the maximum number of models the router tries for one answer. See [The router for every profile](/octy/router/#escalation). A visitor over a limit receives a notice to wait, and no model is called. Each tier has default limits, which a `client_admin` can adjust within fixed ceilings. The figures are in the client documentation. For staff and customer profiles in a client deployment, the deployment’s own per-person limits per minute and per day also apply. ## Address allow and deny lists An **allow list** of networks, in CIDR form for IPv4 or IPv6, restricts a profile to the listed networks, for example an internal profile reached only from office networks and VPN. An empty allow list allows every address. A **deny list** excludes networks, and takes precedence over the allow list. ## Allowed origins and pages **Allowed origins** are the websites that may call the profile from a browser, each exactly as `https://host` or `https://host:port`. A wildcard is refused. The widget channel requires at least one. Cross-origin requests are answered only for the listed origins. **Allowed pages** are the page paths on those websites where the widget may appear, such as `/help/*` or `/policies/**`: `*` matches one segment of a path and `**` any number. An empty list allows every page. The widget hides itself on other pages. The service refuses a question from any page not on the list, independently of the widget. See [The website widget](/octy/widget/). ## The bot check The bot check is a Cloudflare Turnstile check that a visitor is a person, made before a question may use a model. It is always on for a profile with a public audience, and can be turned on for any other. A visitor who has not passed it can still search the knowledge. A question that would call a model is refused until the check is passed. ## The monthly cap Each profile has a **monthly cap** on its model spend, in euro, and an **alert** at a configured percentage of the cap. Before each model call, the cost of the call is reserved against the cap; concurrent questions cannot exceed it. When the cap is reached, Octy answers from retrieval alone until the end of the month and states this in the answer. Test answers count towards the cap. The deployment’s own caps and LightHouse’s monthly **Octy** limit, set in **Limits** by a `client_admin`, apply above every profile’s cap. See [Limits and alerts](/operations/limits-and-alerts/). The gateway’s kill switch, outside the agent, stops every model call at once. See [Engine and gateway](/security/engine/). ## Sign-in Staff and customer profiles verify each person’s sign-in token from the organisation’s identity provider (Entra ID, Okta, Google, Keycloak or any OpenID Connect provider) before answering. A deployment published through an edge sign-in, such as Cloudflare Access, can use the edge’s token instead. The person’s groups determine the classes of document the person may read. See [Knowledge and boundaries](/octy/knowledge/#the-boundary). ## What Octy always refuses Regardless of profile settings, Octy refuses the following requests immediately, before any model is called: - approve, reject or sign off anything; - pay, transfer, refund or release a payment; - grant or change access, roles, keys or passwords; - change a limit; - send content to an outside address. The refusal uses fixed wording and links to LightHouse, where a person can act. A request for work is handled separately: Octy can raise it to an agent as an approval card. See [Octy and agents](/octy/agents/). After an answer is written and before it is sent, sentences that claim a verdict, a guarantee or a certification, or that state that Octy approved, paid or sent something, are removed. Links to hosts the profile does not allow are removed. Source: https://docs.atlanticagenticlabs.com/octy/controls/ --- # The router for every profile > Every answer that needs a model goes through the router, which picks the cheapest model that meets the profile's quality bar, escalates only when an answer misses it, and records each decision. Each Octy™ answer that needs a model uses the cheapest model that meets the profile’s quality bar, and every routing decision is recorded for review in LightHouse™. An Octy profile has no fixed model. Every answer that needs a model goes through the [model router](/router/), which picks the cheapest model that meets the profile’s quality bar for the answer. Questions answered from retrieval alone, and questions the knowledge does not cover, do not reach the router. 1. **Candidates** : the models allowed where the profile runs, restricted to the profile's own list if it has one 2. **Evidence** : how often each model's answers have met this profile's bar; a model below the bar is dropped, and one not yet measured is tried only after the measured ones 3. **Order** : cheapest first, by the provider's price for a typical answer 4. **Answer and check** : the chosen model writes the answer from the passages; the answer is checked against the profile's bar Otherwise: Escalate missed the bar: try the next candidate, while model steps remain 5. **Record** : each decision and escalation, with the model, the reason and the cost The router keeps the candidates the profile allows, orders them by evidence and price, and tries the cheapest first. A model's answer that misses the profile's bar is escalated to the next candidate, up to the profile's model steps. Every rung is recorded as a routing decision. ## The quality bar Each profile sets one of three bars. Every answer that used a model is checked against the bar before it is sent. | Bar | What an answer must do | | ------------ | --------------------------------------------------------------------------------------------- | | **Standard** | Not empty, and cites only the passages it was given | | **High** | As standard; cites more than one source where more than one was found; meets a minimum length | | **Strict** | As high; every sentence carries a citation | A stricter bar increases the estimated cost per answer. Cheaper models miss a stricter bar more often, and more answers are escalated. The exact definitions are in the client documentation. ## Candidates By default the router chooses from every model allowed where the profile runs: - **In a client deployment**, the models the gateway’s policy allows and prices, in the deployment’s region. See [Inputs](/router/inputs/). - **Atlantic-hosted**, the models Atlantic runs for Octy in its own account. - **Air-gapped**, only the models served on the site’s own hardware. A profile that names any other model is refused by the deployment. See [Where Octy runs](/octy/where-it-runs/#air-gapped-on-local-models). A profile can list the models the router may choose from. The list restricts the candidates. The router determines their order by evidence and price. ## Escalation When a cheaper model’s answer misses the bar, the router tries the next candidate. The profile’s **model steps** setting caps the number of models tried for one answer, which bounds the cost of a single answer. If no answer meets the bar within the allowed steps, Octy returns the retrieved passages with their sources, and the answer that missed the bar is not sent. Octy responds the same way when the monthly cap is reached. Escalation for agents is described in [Escalation](/router/escalation/). Each escalation is recorded with the reason the cheaper answer missed the bar, such as an empty answer, a missing citation, a citation of a passage it was not given, a single source where several were needed, or a sentence without a citation. ## Where the router runs | Profile runs on | The router | Its evidence | | ----------------- | ------------------------------------------------------------------ | ------------------------------------------ | | Client deployment | The engine’s router, in the deployment, as for the client’s agents | Measured in the deployment, on its answers | | Atlantic-hosted | LightHouse’s router for Octy, with the same rules | The profile’s own answers | Test answers are recorded and marked as tests. They are not counted as evidence. ## Reading the decisions The profile’s **Costs and questions** tab shows the router’s decisions for the period: the model chosen first, how often answers were escalated and to which model, why answers missed the bar, and what each model cost. A deployment’s decisions also appear with its other routing decisions under **Agents → Routing**, and from `GET /api/v1/routing`. See [Cost analysis](/octy/costs/) and [Control](/router/control/). Source: https://docs.atlanticagenticlabs.com/octy/router/ --- # Cost analysis > How Octy keeps model cost per answer low, and the cost analysis for each Octy profile: spend against the cap, cost per answer, the share answered without a model, the model mix and the estimated saving. The organisation sees what each Octy™ answer costs and pays its own model provider at its own rates. Octy finds the relevant passages without a model call, and calls a model only when an answer needs an explanation, choosing the cheapest model that meets the profile’s quality bar. One question to Octy 1. A question arrives from the profile's audience, on one of its channels. 2. Controls: who may ask, from where, how often, and within the spend cap. A question refused here costs nothing. 3. Retrieval searches the profile's knowledge only, within the caller's access scope. 4. Not covered: if nothing is relevant enough, Octy says so, and no answering model is called. 5. Retrieval answer (Coming): the passages themselves, quoted with their sources, and no model is called. 6. Explained answer: a small model writes the answer from the passages, through your gateway. The router choosing the cheapest model that meets the quality bar for each answer is Coming. 7. Evidence: every source is cited with the answer. A signed receipt is Coming. 8. Measurement: counts, timings and the cost of each answer go to LightHouse. No content does. Most of the work is retrieval, which runs in your deployment at almost no cost. A model is called only when an answer needs explaining, and then a small one. Dashed stages are Coming. ## Retrieval, at almost no cost The search over the profile’s knowledge runs inside the deployment, on a keyword index and a meaning index built and searched there. Its cost is the compute the deployment already runs. See [How retrieval works](/concepts/retrieval/). Two kinds of answer come from retrieval alone: - **Not covered.** When no passage in the knowledge is sufficiently relevant, Octy states this before an answering model is called. - **Retrieval answers.** The passages themselves, quoted with their sources, answer many questions directly, such as “where is the policy on X” or “what does section 4 say”. A retrieval answer calls no model, and its cost is close to zero. Every profile, including Octy on these docs, uses retrieval answers. ## Explained answers through the router When a question needs an explanation that draws several passages together, a model writes the answer from the passages, through the organisation’s gateway. Octy in a deployment without Octy profiles names its models in its configuration: a small one that decides how to handle the question, and one that writes the answer. Only models that the gateway’s policy allows and prices, in the deployment’s region, can be named. For an Octy profile, every explained answer goes through the router. It keeps the models allowed where the profile runs, drops those whose answers fall short of the profile’s quality bar, tries the cheapest first, and escalates only when an answer misses the bar. See [The router for every profile](/octy/router/). An explained answer is a short prompt of a few passages and a short reply, run on a small model. It typically costs a fraction of a cent, estimated. Sending every question, with whole documents as context, to a large model costs many times more, estimated. ## Who pays for the models Profiles in a client deployment call models through the client’s gateway, on the client’s provider account: Amazon Bedrock, Azure AI Foundry, Google Vertex AI, the Claude API, or an open-weight model on the client’s GPUs. The client pays its provider directly, at its own rates. Atlantic does not resell model usage. Atlantic-hosted profiles run on models in Atlantic’s account. ## Caps Every profile has a monthly cap on its model spend, reserved before each model call. See [Controls](/octy/controls/#the-monthly-cap). ## Cost analysis per profile Octy’s model calls in a deployment are recorded by the gateway with the deployment’s other usage, and shown in LightHouse™ under cost and routing. See [What is measured](/cost/what-is-measured/). A cost analysis for each Octy profile, on its **Costs and questions** tab and, for every profile together, under **Octy profiles → Costs**, for the last 7, 30 or 90 days. | Figure | What it is | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Answers** | Answers given in the period, split into those from retrieval alone and those that used a model | | **Without a model** | The share of answers made from retrieval alone | | **Model spend** | What the profile’s model calls cost, against its monthly cap | | **Cost per answer** | Model spend divided by answers | | **Model mix** | Each model’s answers, cost and share | | **Router decisions** | The model chosen first, escalations, and why answers missed the bar. See [Reading the decisions](/octy/router/#reading-the-decisions) | | **Latency** | The median and 95th percentile time to answer | | **First answer after a wake** | For a deployment that sleeps between questions, the median and 95th percentile time of the first answer after it wakes, and how many wakes there were. See [Deployment profiles](/octy/where-it-runs/#deployment-profiles) | | **Estimated saving** | What the same answers would have cost had every one gone to a large baseline model, less what they cost. The baseline model is named beside the figure | | **Answers per day** | The daily count, split by how each answer was made | The figures come from the counts, tokens and costs each answer reports: from LightHouse for an Atlantic-hosted profile, and from the deployment’s operational telemetry for a profile in a client deployment, or from its imported bundles when it is air-gapped. The figures do not use question or answer text. The API is `GET /api/v1/octy-profiles/costs` for every profile and `GET /api/v1/octy-profiles/{id}/costs` for one. The saving uses the same method as the other savings LightHouse shows. See [How a saving is calculated](/cost/savings/). ## Every figure says estimated A cost per answer is measured from the provider’s own prices for the tokens each call used. A saving is a comparison with a counterfactual. It is an estimate, and LightHouse labels it as one wherever it is shown. See [Why every figure says estimated](/cost/estimated/). Source: https://docs.atlanticagenticlabs.com/octy/costs/ --- # Evidence and question insights > Citations on every answer, the evidence panel with its passages, signed receipts that any party can verify, and question insights for each Octy profile. Every Octy™ answer cites the passages it was written from and is checked against them before it is sent. The organisation can review what was answered, from which sources, and what each profile is asked. The evidence panel and signed receipts allow any party to check an answer afterwards. ## Citations and the grounding check Every answer carries its **citations**: the documents and passages it was written from, with links where the source has one. The answer is checked against those passages before it is sent. A sentence the passages do not support is flagged or removed, as the profile specifies. Each answer reports whether it was grounded, and the count reaches LightHouse with the turn’s other figures. See [Evidence](/concepts/evidence/). ## The evidence panel An **evidence panel** beside every answer, on every channel that can show one. For each source it shows the title and section, the passage exactly as indexed, the version or publication date of the source, and whether the answer cited it. The panel shows the passages Octy read as well as the answer. ## Signed receipts Every answer carries a **signed receipt**: a small signed record of the answer, issued for the Octy profile that gave it. A receipt holds a digest of the question, a digest of the answer, the time, the Octy profile that answered, and a digest of each passage it was written from. It contains no question or answer text, no model name and no score. It is signed with Ed25519 under the issuer’s published key: Atlantic’s Octy key for an Atlantic-hosted profile, LightHouse’s Octy key for Octy in the portal, and the deployment’s own key for a profile that runs in a client deployment. Any party with the receipt and the published key can verify it. A receipt establishes that a specific Octy profile gave a specific answer to a specific question, at a specific time, from specific passages. A changed word in the answer, or a substituted passage, fails verification. A receipt does not establish that the answer is correct. That judgement rests on the evidence panel and the cited sources. ## Verifying a receipt Verification in the browser, from the evidence panel, and from the command line with `lighthouse-ai verify-answer`. Both check the signature against the issuer’s published key and compare the digests with the answer and passages shown. ## Audit Each turn is recorded in the deployment and reported to LightHouse as operational telemetry: the time, the route taken, the cost, whether the answer was grounded, and the outcome. Content remains in the organisation’s account. A person is identified to LightHouse only by a keyed hash. See [The telemetry contract](/concepts/telemetry-contract/). Changes to Octy’s configuration in a deployment are released through the release gate, like any agent change, and recorded there. Each change to an Octy profile is recorded in LightHouse™ with its revision and the changed fields. See [The audit](/octy/manage/#the-audit). ## Question insights **Question insights** for each Octy profile, on its **Costs and questions** tab in LightHouse, for the last 7, 30 or 90 days. Question insights show what a profile is asked: the questions by outcome (answered from retrieval, answered with a model, not covered, refused, or handed on), the top questions, the questions the knowledge did not cover, the sources cited most, and the volume per day. Where a GitLab or Jira connector is set up, a gap can be opened as an issue for the team that owns the knowledge. Test answers are excluded. Question text is redacted before storage, carries no identifier of the person who asked, and is retained for twelve months. The storage location depends on where the profile runs: | Profile runs on | Question text storage | LightHouse view | | ----------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Atlantic-hosted | In LightHouse, under the tenant’s row-level security | The redacted questions | | Client deployment, connected | In the deployment’s own store | The redacted questions, read in place for this page only and not stored in LightHouse. Visible to `client_admin` and `content_viewer` only | | Client deployment, air-gapped | On site | Counts, outcomes and clusters of equal questions, identified by a keyed hash. The text is on the site’s own Octy insights page, behind the site’s sign-in, where an administrator can match each cluster to its questions | The keyed hash groups equal questions for counting. A guessed question cannot be tested against the hash without the deployment’s key. Source: https://docs.atlanticagenticlabs.com/octy/evidence/ --- # Where Octy runs > Octy runs where its knowledge is held: Atlantic-hosted, in the organisation's AWS, Azure or Google Cloud account, on its own servers, or air-gapped on local models, under every deployment profile. Octy™ runs inside the organisation’s deployment of the Atlantic Agentic Engine, in its own cloud account, on its own servers or air-gapped, beside its gateway and indexes. Questions, passages and answers are stored in the deployment. LightHouse™ receives counts, timings and costs. **LightHouse**: in Atlantic's account - **Limits and cost**: the monthly Octy limit, and the cost of its model calls - **Approvals**: the cards Octy raises, approved by a person - **Portal Octy**: answers from the tenant’s LightHouse data Operational telemetry; no content - **Telemetry** (upward): turns, routes, costs, timings and outcomes - **Signed commands** (downward): limits, pauses and releases **Client deployment**: wherever the engine runs - **Own cloud**: AWS, Azure or Google Cloud, in the chosen region - **Own servers**: Docker or Podman, beside the gateway and the knowledge database - **Air-gapped**: no network path out; local models on the organisation’s GPUs - **Atlantic-hosted**: the same engine, in a dedicated account run for the client Octy runs in the client deployment, on the organisation's models. Operational telemetry is the only data sent to LightHouse; an air-gapped deployment sends it by file. ## Where a profile runs Each [Octy profile](/octy/profiles/) runs where its knowledge is held: | Knowledge | Runs on | Reason | | ------------------------------------------------------------------------------ | ------------------------------- | ------------------------------------------------------------------------------- | | The organisation’s knowledge bases, connected sources and uploaded collections | One of the client’s deployments | Content is read in place, in the client’s account. LightHouse does not store it | | The tenant’s LightHouse data | Atlantic-hosted | It is the portal’s own data, read under the person’s role | | Atlantic’s public documentation and published knowledge | Atlantic-hosted | Atlantic’s own material, for Atlantic’s public profiles | In this table, Atlantic-hosted means that LightHouse answers the profile, in Atlantic’s account. An [Atlantic-hosted deployment](/clouds/atlantic-hosted/), run for a client in a dedicated account, counts as one of the client’s deployments. A profile cannot mix knowledge from both places. LightHouse sends a profile to the deployment that runs it as a signed command, or by command file to an air-gapped site, and shows whether the deployment applied it. See [How a change reaches your deployment](/octy/manage/#how-a-change-reaches-your-deployment). ## The deployment matrix | Where | How Octy runs there | Models | Status | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------- | | **AWS** | A private service on the deployment’s load balancer, beside the client stack | Amazon Bedrock or the Claude API, through the gateway | Built | | **Own servers** | The Octy container in the stack LightHouse generates, beside the gateway and the knowledge database. See [On-premises](/clouds/on-premises/) | Any provider the gateway reaches, or a local model | Built | | **Air-gapped** | As on the organisation’s own servers, with no network path out | An open-weight model on the organisation’s NVIDIA GPUs | Built | | **Azure** | The same image on Azure Container Apps, behind the stack’s ingress | Azure AI Foundry, through the gateway | The image runs there; the one-click module is \[Coming] | | **Google Cloud** | The same image on Cloud Run, behind the stack’s ingress | Vertex AI, through the gateway | The image runs there; the one-click module is \[Coming] | | **Atlantic-hosted** | As on AWS, in a dedicated account that Atlantic runs for the client. See [Atlantic-hosted](/clouds/atlantic-hosted/) | As on AWS | Built | In every deployment, Octy holds no provider key. The gateway holds the only model credential, the budgets and the kill switch. The Octy image contains no model SDK. ## Air-gapped, on local models Octy can run with no network path out of the organisation’s environment: - **Local models.** An open-weight model runs on the organisation’s NVIDIA GPUs, served by vLLM, or by NVIDIA NIM under the organisation’s licence, and the gateway calls it on the local network. Prompts and answers remain on the organisation’s machines. See [Self-hosted models](/clouds/on-premises/#self-hosted-models). - **Local knowledge.** Documents are indexed into the knowledge database in the organisation’s environment. The embedding model that builds the meaning index runs there too. - **Telemetry by file.** The deployment keeps its telemetry as signed, numbered bundle files, which an operator carries to LightHouse. Commands come back in a signed command file. See [Air-gapped operation](/clouds/on-premises/#air-gapped-operation). With Octy profiles, an air-gapped site operates as follows: - **Profiles by command file.** A change to a profile goes into the next command file, and the profile shows as waiting for it in LightHouse. The site applies the file, and the change shows as applied once the site’s next telemetry bundle is imported. - **Local models only.** The router’s candidates are the models served on the site. A profile that names any other model is refused by the deployment. - **Question text on site.** LightHouse shows counts, outcomes, costs and hashed clusters of equal questions from the imported bundles. The question text is on the site’s own Octy insights page, behind the site’s sign-in. See [Question insights](/octy/evidence/#question-insights). - **Receipts signed on site.** Answers are signed with the deployment’s own key and can be verified without a call to Atlantic. ## Deployment profiles Octy works under each [deployment profile](/concepts/deployment-profiles/): | Profile | What it means for Octy | | ------------- | -------------------------------------------------------------------------------------------------------------- | | **Always-on** | Answers at once, at any hour | | **Ephemeral** | Services sleep when idle. The first question after a quiet period wakes Octy, and is answered once it is ready | | **Scheduled** | Warm in the configured wake window, such as working hours; outside it, woken on demand as under ephemeral | While a deployment wakes, the caller receives a notice that Octy is starting and the time after which to ask again. The website widget shows the notice and asks again automatically. On the organisation’s own servers, Octy runs continuously. The [cost analysis](/octy/costs/#cost-analysis-per-profile) shows the time of the first answer after a wake for each profile. For Octy used only in working hours, the scheduled profile answers immediately during the wake window and costs less than always-on, estimated. See [Estimated savings against always-on](/concepts/deployment-profiles/#estimated-savings-against-always-on). ## Residency Octy keeps its inference in the region its deployment names. Cross-region model profiles are refused unless the deployment allows them, and the gateway’s policy refuses them again. Documents, indexes and conversations remain in the organisation’s account. See [Data sovereignty](/data-sovereignty/) and [Regions](/data-sovereignty/regions/). Source: https://docs.atlanticagenticlabs.com/octy/where-it-runs/ --- # Channels > The channels on which people and agents ask an Octy profile: the web panel, the website widget, the LightHouse portal, Microsoft Teams, Slack, MCP and the API. Octy™ answers in the tools the organisation already uses: its website or intranet, Microsoft Teams, Slack, the LightHouse™ portal, MCP clients and its own applications. The answer, its citations and its controls are the same on every channel. A **channel** is a surface on which people or agents ask Octy. Each channel is switched on per profile, and each can be limited to specific classes of document. | Channel | Who asks there | Status | | -------------------------- | -------------------------------------------------------------------------- | ------ | | Web panel | Anyone the profile’s audience allows, at the profile’s own address | Built | | Website or intranet widget | Visitors to the organisation’s website or intranet | Built | | LightHouse portal | People signed in to the tenant | Built | | Microsoft Teams | The organisation’s staff, in Teams | Built | | Slack | The organisation’s staff, in Slack | Built | | MCP | Other agents; GitHub Copilot, Copilot Studio, Claude and other MCP clients | Built | | API | The organisation’s own applications | Built | ## Requirements | Channel | Requirement | | ------------------------- | -------------------------------------------------------- | | Website widget | At least one allowed origin | | MCP and API | A signed-in audience. Not available to a public audience | | LightHouse portal | The signed-in customers audience | | Microsoft Teams and Slack | A deployment with that channel connected | See [Octy profiles](/octy/profiles/#rules-every-profile-keeps). ## Web panel A full-page panel at the profile’s own address, for any profile with the web channel on. Octy on these docs uses this panel, opened from the **Ask Octy** button on every page. ## Website or intranet widget The widget is one script and one element on the page. Octy serves it from the deployment, with no third-party host. In this example Octy is published on the intranet’s own host: ```html ``` The page supplies the person’s sign-in token from the intranet’s own sign-in. Behind an edge sign-in such as Cloudflare Access, the widget sends the edge’s cookie on its own origin. The content security policy needs only `script-src 'self'`, `style-src 'self'` and `connect-src` to Octy. The widget follows the page’s light or dark theme, and a React component is included. A nickname can be added beside the name Octy. The octopus and the line “Octy™, by Atlantic Agentic” remain in the widget. The widget for any Octy profile: one script tag keyed to the profile, for a public website or an intranet, with the bot check, the evidence panel and receipt verification built in, and its content security policy entries on the profile’s **Widget** tab. See [The website widget](/octy/widget/). ## LightHouse portal Every LightHouse tenant has Octy in its portal. It answers questions about the tenant’s agents, runs, costs and approvals from the tenant’s LightHouse data, through the same read routes as the API, under the role of the person asking. It links to the page where a person can act, and does not act itself. ## Microsoft Teams and Slack - **Microsoft Teams.** The organisation registers a bot for Octy in its own Entra tenant. Each message’s token is verified against the Bot Framework’s published keys before the message is read, and only the organisation’s Entra tenants are answered. Replies are Adaptive Cards with sources and links. - **Slack.** Octy receives the Slack app’s events, signed with its signing secret, and replies in the thread with sources and link buttons. On both channels, replies carry links only; a chat has no approve button. A person in Teams or Slack reads only the classes of document the channel allows, and cannot raise work for approval from the chat. Each channel’s secrets are held in the organisation’s own secret store. ## MCP Other agents can ask Octy as a tool over the Model Context Protocol. In a client deployment, Octy serves an `ask_octy` tool to the organisation’s own agents, with the channel’s own classes of document. An agent that asks cannot raise work for approval. LightHouse’s hosted MCP server provides GitHub Copilot and Microsoft Copilot Studio with its read-only tools, including knowledge retrieval from the organisation’s own sources. See [Use LightHouse in GitHub Copilot](/mcp/github-copilot/) and [Use LightHouse in Microsoft Copilot Studio](/mcp/copilot-studio/). An `ask_octy` tool on LightHouse’s hosted MCP server: a profile’s short name and a question, asked as the signed-in caller, read only, under the profile’s own controls and cap. A profile that runs in a client deployment answers there, and the tool response states where to ask it. ## API In a client deployment, Octy answers on its own HTTP route, `POST /v1/octy/chat`, with the person’s sign-in token. The answer streams back as server-sent events: the text, the citations, any notice or link, and the outcome. Publish the route through the organisation’s own front door. An API route for each Octy profile: `POST /api/v1/octy-profiles/{id}/ask` in LightHouse for an Atlantic-hosted profile, and `POST /v1/octy/p/{slug}/ask` on the deployment’s Octy service for a profile that runs there. Both return the same response shape as the web panel. Source: https://docs.atlanticagenticlabs.com/octy/channels/ --- # The website widget > Adding an Octy profile to a website or intranet with one script tag: the snippet, the content security policy, origins and pages, the bot check and the evidence panel. The widget adds an Octy™ profile to the organisation’s website or intranet with one script tag. Visitors receive answers from the profile’s knowledge with their sources, under the profile’s controls. The widget places an Octy profile on a page of a website or intranet: a launcher in the corner of the page that opens a panel with one question box. It answers from the profile’s knowledge, under the profile’s controls, and shows the evidence for each answer. ## Setup 1. Open the profile in LightHouse™ (**Agents → Octy profiles**) and, on **Settings**, add the websites that will carry the widget under **Allowed origins**, each exactly as `https://host` or `https://host:port`. 2. Optionally, under **Allowed pages**, list the page paths where it may appear, such as `/help/*` or `/policies/**`. An empty list allows every page on the allowed origins. 3. Switch on the **Website widget** channel and save. 4. Open the **Widget** tab. Result: the tab shows the snippet and the content security policy entries. ## The snippet Place the snippet once, before the closing `` tag, on each page where Octy should appear. For an Atlantic-hosted profile it reads: ```html ``` For a profile that runs in a client deployment, `data-octy-api` names the deployment’s Octy service, which answers the questions: `https://YOUR-OCTY-HOST/v1/octy/p/customer-help`. Replace `YOUR-OCTY-HOST` with the host on which Octy is published, behind the organisation’s own front door. The script is served by Atlantic and contains no data. Copy the exact snippet for each profile from the **Widget** tab. ## Content security policy If the website’s pages send a `Content-Security-Policy` header, add the sources listed on the **Widget** tab: | Directive | Source | Purpose | | ---------------------------- | -------------------------------------------------------------------- | ----------------------------------------------- | | `script-src` | `https://ask.atlanticagenticlabs.com` | The widget’s script | | `connect-src` | `https://ask.atlanticagenticlabs.com`, or the deployment’s Octy host | The service that answers the widget’s questions | | `script-src` and `frame-src` | `https://challenges.cloudflare.com` | The bot check, when it is on for the profile | The widget’s requests carry no credentials. ## Pages and origins The widget reads the profile’s allowed pages and hides itself on any other page. This affects display only. The service that answers checks the origin and the page of every request, and refuses a question from an origin or page the profile does not allow. See [Controls](/octy/controls/#allowed-origins-and-pages). ## The bot check, the evidence panel and receipts - **The bot check.** For a profile with the bot check on, the widget shows a Cloudflare Turnstile check before a question may use a model. A visitor who has not passed it can still search. A public profile always has it on. - **The evidence panel.** Each answer lists its sources, and the panel shows the passages it was written from. - **Receipts.** Each answer’s signed receipt can be verified in the widget, against the published key of the profile that answered. See [Evidence and question insights](/octy/evidence/). ## Deployment wake-up A deployment that sleeps between questions may be starting when a question arrives. The widget then shows that Octy is starting, waits for the time the service gives, and asks again automatically. See [Deployment profiles](/octy/where-it-runs/#deployment-profiles). ## Integrity of the script The widget’s script is served only if it matches the SHA-256 digest LightHouse holds for it, and the snippet carries the same digest as its `integrity` attribute. A browser refuses a script that does not match the digest. Source: https://docs.atlanticagenticlabs.com/octy/widget/ --- # Octy and agents > Octy answers and routes with read-only tools; agents perform work, which reaches them through approval cards that a person approves in LightHouse. Octy™ gives the organisation a read-only point of contact for questions and requests. Work that has an effect is performed by agents and approved by a person in LightHouse™, with the approval recorded. Octy answers, explains and routes. Agents perform specialist work, such as a design review, a research brief or a draft for sign-off. ## Octy and agents compared | | Octy | An agent | | --------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | **Definition** | One conversational agent, configured per use by an Octy profile | A versioned card for one job, from the library, the builder or code. See [Agents](/concepts/agents/) | | **Function** | Answers questions from a profile’s knowledge, with citations | Performs work: reads, drafts, analyses and, where its card permits, acts | | **Tools** | Read-only. Profile settings cannot grant a tool that writes, approves, pays or changes access | The tools its card declares, each authorised at run time by the tool gate | | **Changed by** | Editing the profile in LightHouse. Each change is a new revision, applied by signed command | Releasing a new version of the card through the release gate and its evaluations | | **Audience** | The profile’s audience, on its channels: the public, customers or staff | The people and systems that start it, with handlers who sign off its work | | **Models** | The router, against the profile’s quality bar | The router, against the card’s task class and quality bar | | **Cost limits** | The profile’s rate limits and monthly cap | The card’s caps, and the limits above it | | **Approvals** | Does not approve. Hands work on as an approval card | Stops at **awaiting approval** for anything with an effect outside the deployment | ## Read-only by design Every tool Octy may call is declared as a read. The engine’s tool gate authorises each call at run time, under a policy generated from Octy’s configuration. A tool the configuration does not grant is refused, regardless of the conversation. Octy holds no credential to act with, and no tool that approves, pays, changes access, changes a limit or sends content out. See [Controls](/octy/controls/#what-octy-always-refuses). ## Handing work to an agent When a person requests work instead of an answer, Octy hands the request to an agent: 1. Octy identifies the request as work for an agent, such as “review this design against our standards”. 2. Octy starts that agent’s card through the orchestrator, with the person’s request as its input. 3. The agent performs the work. A card with an effect outside the deployment stops at **awaiting approval**. 4. Octy confirms to the person that the work has been raised, with a link to it in LightHouse. Only a signed-in person can raise work this way. Requests through Slack, Teams or MCP cannot raise work. ## Approved in LightHouse Approval cards are approved by a person in LightHouse only. Octy contains no approval code. Where Octy shows the status of work, it links to the attention queue in LightHouse, where the handler reviews the evidence and decides. See [Approvals](/concepts/approvals/) and [Handlers](/concepts/handlers/). ## Octy profiles consulting each other > **Coming:** > > Octy profiles consulting each other, as a **consortium**. Each profile acts as a tool for the others, within its own boundary. A profile declares which other profiles it may consult, and each consulted profile answers only what its own tier and the caller’s audience allow; a public profile cannot obtain internal knowledge through another profile. Each consulted profile signs its own receipt, and the caller’s receipt carries those receipts. The evidence panel shows the whole chain: the profiles consulted, the sources each cited, and each verified signature. Each profile keeps its own cap, and a consultation carries a depth limit and a budget. Source: https://docs.atlanticagenticlabs.com/octy/agents/ --- # Concepts > The ideas LightHouse and the engine are built from, and how they fit together. LightHouse and the engine are built from a small set of ideas. Each has a page; this one shows how they fit. **LightHouse**: your tenant, at https\://\.atlanticagenticlabs.com, in Atlantic's account - **People and roles**: who signs in, through your identity provider - **Keys**: machine keys and signed-in tools - **Approvals and limits**: sign-offs, caps and cost limits - **Billing**: cost, usage, payments and invoices - **API, MCP and portal**: the ways in, at your tenant's address * **Operational telemetry** (upward): counts, timings and costs * **Signed commands** (downward): pause, approve, set a cap **Your deployment**: the Atlantic Agentic Engine, in your account - **Gateway**: the only path to your models - **Orchestrator**: runs your agents, each defined by a card - **Knowledge bases**: your sources, indexed in your account - **Content reader**: serves read-only views of your content in place LightHouse runs in Atlantic's account at your tenant's address; the engine runs in your account. Telemetry goes up and signed commands come down, on connections your deployment opens. - **[Tenants](/concepts/tenants/).** One client: its own address, identity provider, people, keys, settings and audit log. Its control-plane records are isolated from other tenants’ by row-level security in a shared database; its content stays in its own deployment. - **[Agents](/concepts/agents/).** An agent is a card: its job, its tools, its budget, its effect and its autonomy. Its ID is `:`. - **[Handlers](/concepts/handlers/).** The people who pause agents, set caps, grant pre-approvals and decide on outputs. - **[Knowledge bases](/concepts/knowledge-bases/).** Your sources, indexed in your account and read in place. - **[How retrieval works](/concepts/retrieval/).** How an agent finds and cites the passages it answers from, or abstains, inside your deployment. - **[Evidence](/concepts/evidence/).** What an answer was grounded in, and how strong that evidence is. - **[Approvals](/concepts/approvals/).** A person signs off an output before it counts. An agent or a key cannot approve. - **[Runs](/concepts/runs/).** One execution of a pack’s agents: its steps, calls, cost and outcome. - **[The gateway](/concepts/gateway/).** The only thing that calls a model, where caps, the kill switch and the tool gate are enforced. - **[Deployment profiles](/concepts/deployment-profiles/).** Ephemeral or always-on: whether the engine’s services sleep when nothing is asked of them. - **[How LightHouse scales](/concepts/scaling/).** How LightHouse adds capacity under load, how rate limits apply across copies, and how the engine scales in the client’s own cloud. - **[The telemetry contract](/concepts/telemetry-contract/).** What crosses from your account to LightHouse: counts and timings only; content is not transmitted. Source: https://docs.atlanticagenticlabs.com/concepts/ --- # Tenants > A tenant is one client of LightHouse: its own address, identity provider, people, keys, settings and audit log, with its records isolated by row-level security in a shared database. A **tenant** is one client of LightHouse: its own address, its own identity provider, and its own people, keys, settings and audit log. LightHouse is one multi-tenant control plane: its services and its PostgreSQL database are shared by all tenants. Each tenant’s control-plane records are isolated from every other tenant’s by row-level security in a shared database. Tenant content stays in the tenant’s own deployment and is not stored by LightHouse. ## The tenant ID Every tenant has a **tenant ID**: `t-` followed by ten characters. The characters are lower-case letters and digits, without the ones that are easily misread (`0` and `o`; `1`, `i` and `l`), so an ID read aloud or copied by hand stays correct. The ID is random. It never names the client, because a hostname is public: it shows up in DNS records, certificates, browser history and screenshots. Atlantic generates the ID at random when the tenant is created; nobody chooses it. Atlantic can replace it on request. The replacement is audited, and the old ID stops working permanently. ## The tenant’s address Your tenant lives at `https://.atlanticagenticlabs.com`: the portal, the [API](/api/) and the [MCP server](/mcp/) all answer there. You start at `platform.atlanticagenticlabs.com`, enter your tenant ID, and are sent to your tenant’s address to sign in. LightHouse takes the tenant from the address and nowhere else. No header or parameter can name another tenant. A key belongs to the tenant that issued it, and at any other tenant’s address it is refused with `401 unauthenticated`. ## Isolation Every read and write runs under the tenant’s own scope, and PostgreSQL row-level security enforces it in the database. A query that does not filter by tenant returns an error rather than another tenant’s rows. See [API security](/security/api/). ## People, roles and keys - **People** sign in through your own identity provider (Microsoft Entra ID, Google, Okta, GitHub, GitLab, or any SAML or OIDC provider), and must prove a second factor. Who may sign in, and with which role, is your tenant’s **access rules** (**Settings → Users and roles**). - **Roles** are cumulative: `viewer`, `content_viewer`, `handler`, `client_admin`. Beside them, `billing` lets a viewer run the tenant’s payments. See [Roles](/api/roles/). - **Machine keys** let your own tools read the API and MCP. A key is `viewer` or `content_viewer` and holds no higher role. See [Authentication](/api/authentication/). - **Atlantic staff** hold `viewer` on every tenant, and `content_viewer` only where your access rules say so. They do not administer your tenant. See [Who can see what](/data-sovereignty/access/). ## States | State | Sign-in | Notes | | ----------- | ------- | --------------------------------------------------------------------------------------------------------------------------- | | `sandbox` | Yes | A tenant made by self-serve sign-up. It can read and set up, and cannot spend until a payment method or invoice terms exist | | `active` | Yes | | | `suspended` | No | Sign-in and reads are off; deployments’ telemetry still arrives. See [Suspension](/operations/suspension/) | ## In the API `GET /api/v1/me` returns your tenant (`client.tenant_id`, `client.hostname`, `client.portal_url`), who you are and your role. See [Me](/api/reference/people-and-preferences/#me). Source: https://docs.atlanticagenticlabs.com/concepts/tenants/ --- # Agents > An agent is a versioned card: its job, its model, its tools, its caps and its approvals. An **agent** is one card in a pack’s catalogue: a versioned declaration of the job it does, the tools it may use, the model it may call, its budget, whether its work has an effect outside the run, and how much autonomy it has. The engine runs an agent only under its card, and grants nothing the card does not list. ## The agent card A pack’s catalogue is a YAML file kept in your own repository. Each card declares: | Field | What it says | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | The card’s name in its pack | | `purpose` | What it is for, in one line | | `executor` | How it runs: `python` (a function), `command` (a program) or `claude-code` | | `overseer` | The named person answerable for it | | `budget_usd` | Its spending cap per run, enforced by the [gateway](/concepts/gateway/) | | `tools` | The whole list of tools it may use; nothing else is granted | | `model` | A model or a tier, checked by the gateway | | `needs` | The cards whose output it is given | | `produces` | The artefact that proves it ran; a card that writes nothing has failed | | `effect` | `internal` (writes only to the run’s own store) or `external` (sends, publishes or writes into one of your systems). The default is `external` | | `autonomy` | For an external effect: 0, 1 or 2 (below) | | `timeout_s`, `retries` | How long it may take, and how often it is retried | If any card in a catalogue is malformed, the engine refuses the whole catalogue, so no agent runs under a partly loaded set of rules. To write one, see [In code](/build/code/). An agent that answers from your content searches your knowledge bases and cites the passages it used, or reports that nothing relevant was found. See [How retrieval works](/concepts/retrieval/). ## Packs and agent IDs Cards are grouped in **packs**: one catalogue, one team’s agents, with one autonomy ceiling. An agent’s ID is `:`, for example `research:summary`. The pack is a lower-case slug; the card is letters, digits and `._:-`. The API and MCP use this ID everywhere. ## Autonomy Autonomy applies to actions with an effect outside the run, so only an `external` card is gated. | Level | Shown as | What happens to its output | | --------------- | -------------- | ---------------------------------------------------------------------------------- | | internal effect | `internal` | Runs unattended; it writes only to the run’s own store | | 0 | `draft` | A draft. Nothing downstream may use it | | 1 | `sign-off` | Waits for a named person to approve it in LightHouse | | 2 | `pre-approved` | Goes ahead within a standing pre-approval’s limits; otherwise waits, as at level 1 | A pack’s ceiling can lower a card’s level and cannot raise it. The default ceiling is 1: a pack opts in to level 2 by saying `ceiling: 2`. Level 3 and above are refused. See [Approvals](/concepts/approvals/). ## Live state LightHouse derives each agent’s state from what its deployment has reported: | State | Means | | ------------------- | ----------------------------------------------------------------------- | | `running` | It has called a model in the last ten minutes, since its last run ended | | `idle` | No record says otherwise | | `failing` | Its last run failed | | `paused` | The kill switch is on for it, its pack or the whole tenant | | `awaiting-sign-off` | Its last run’s output is waiting for a person | ## In LightHouse and the API - **Agents → Hub** lists every agent with its state, spend and last run; **Agents → Map** draws how they hand work to each other. - `GET /api/v1/agents` (filter by `status`), `GET /api/v1/agents/{agent_id}`, `GET /api/v1/agent-map`: see the [Read reference](/api/reference/read/#agents-list). - MCP: [`agents`](/mcp/tools/agents/), [`agent`](/mcp/tools/agent/), [`agent_map`](/mcp/tools/agent-map/). A card’s instructions, command and prompts never leave your account. LightHouse sees its settings, and its `purpose` only if the pack chooses to publish it. Source: https://docs.atlanticagenticlabs.com/concepts/agents/ --- # Handlers > Handlers are the people who sign off, pause and command agents. A **handler** is a person who acts on agents from LightHouse: pausing and resuming them, setting their spending caps, granting standing pre-approvals, deciding on outputs that wait for sign-off, and making a released version current. In LightHouse this is the **Agent handler** (`handler`) role. A **Client administrator** (`client_admin`) can do everything a handler can, plus the tenant-wide commands in the table below. Each of these actions reaches your deployment as a signed **command**. LightHouse never changes your deployment directly. ## The commands | Command | Who can issue it | What it does in your deployment | | --------------------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `agent.pause` | `handler` | Turns the kill switch on for that agent | | `agent.resume` | `handler` | Turns it off again | | `budget.set` | `handler` | Sets the agent’s cap (`total`, `month` or `day`). Lowering is always allowed; raising needs a role your policy names, and never goes above its ceiling | | `preapproval.grant`, `preapproval.limits`, `preapproval.revoke` | `handler` | A standing pre-approval: grant one, change its limits, revoke it | | `approval.decide` | `handler` | Approve or reject an output waiting for sign-off | | `release.add` | `handler` | Make a released version the current one; refused unless that version passed the release gate. Also what `lighthouse-ai agents deploy` and `rollback` send. See [Versioning and rollback](/build/versioning/) | | `eval.run` | `handler` | Run an agent’s evaluation once now, under a spend cap. From the agent’s **Evaluations** section, or `lighthouse-ai evals run`, and for an agent drafted in [the builder](/build/builder/) (`proposal`). See [Evaluations](/build/evaluations/) | | `card.propose` | `handler` | Keep an agent drafted in [the builder](/build/builder/): the draft, sealed to your deployment’s key, is opened, validated and kept. Answers `applied` (`proposed`), or `card-invalid`, `card-exists`, `sealed` or `sealing-key`. Off by default on both sides | | `card.publish` | `handler` | Publish an agent the builder drafted, once its evaluation and red team passed in your deployment and a person with a second factor approved it. Answers `applied` (`published`), `gate-not-passed`, `evidence-changed`, `card-invalid` or `unknown-proposal`. Followed by `release.add`. Off by default on both sides | | `limit.set`, `limit.clear` | `client_admin` | Set or clear a spending limit, from **Billing → Limits** | | `routing.set` | `client_admin` | Change the model router’s settings for the tenant: on or off, a quality bar for one task class, a pinned model, an excluded model, and removing a pin or lifting an exclusion LightHouse set. See [Control](/router/control/) | | `benchmark.schedule` | `client_admin` | Set when the Token Value Benchmark runs by itself: a monthly day, and triggers for a new model, a price change or a model version change, each run under a cap. See [Schedule and triggers](/cost/token-value-benchmark/#schedule-and-triggers) | | `benchmark.start` | `client_admin` | Run the [Token Value Benchmark](/cost/token-value-benchmark/) once, under the cap the command carries | | `connector.schedule` | `client_admin` | Set how often a source syncs: `off`, `every_15m`, `hourly`, `working_hours` (with `tz`) or `daily` (with `at` and `tz`). Your policy can narrow the modes allowed. See [Sync schedules](/connect/#sync-schedules) | | `connector.sync` | `client_admin` | Sync a source once, at your deployment’s next scheduler tick, whatever its schedule | | `secret.put` | `client_admin` | Open a connector credential sealed to your deployment, check it is the connector’s shape, and write it to your own secrets store. Answers `stored`, or `unchanged` where the same credential is already kept. Sent when you connect in LightHouse. See [Where every credential is held](/connect/#where-every-credential-is-held) | | `secret.delete` | `client_admin` | Delete a credential from your store: `deleted`, or `absent`. Sent when a new credential replaces it, once the new one is kept | | `connector.check` | `client_admin` | Check a kept credential at the provider, from your account: `ok`, `auth_failed`, `scope_missing`, `write_capable`, `unverified`, `unreachable` or `absent`. Sent after every `secret.put`, and by **Check it now** | | `connector.revoke` | `client_admin` | Revoke a credential at the provider where it can revoke itself (`revoked`), otherwise answer `provider_manual` naming where to revoke it; delete it from your store either way. Sent by **Disconnect** | `handler` here means `handler` or `client_admin`. Every command needs a `reason` (up to 1,000 characters), which is kept in the audit log. The four credential commands, `secret.put`, `secret.delete`, `connector.check` and `connector.revoke`, are **tenant commands**: they act on your tenant’s connections, not on an agent (`"target": {"scope_kind": "tenant", "scope": ""}`). LightHouse creates them from the Connectors page, never from an agent’s page, and gives each 15 minutes to be taken. A sealed credential in a `secret.put` is never shown in a read or the audit log, and is replaced by `[redacted]` in the stored command once the command is final. ## Where commands are issued in LightHouse - **An agent’s page** (open it from **Agents → Hub**): the **Change or stop** card has **Pause** or **Resume**, **Set budget cap** and **Make a version current** (offered only for versions that passed the release gate). For a pre-approved agent, the **Autonomy** card adjusts, revokes or re-grants its pre-approvals; see [Approvals in Build agents](/build/approvals/#manage-pre-approvals-in-lighthouse). - **Agents → Hub**, the attention queue: **Approve** and **Reject**. See [Approvals](/concepts/approvals/#approve-or-reject-an-output). - **Billing → Limits**: spending limits (`client_admin`). - **Agents → Routing**: the router’s settings and the Token Value Benchmark (`client_admin`). - **Setup and admin → Connectors**, on a connection’s card: **Save schedule** and **Sync now**, and, for a credential in your own store, **Check it now** and **Disconnect**. Connecting sends `secret.put` (`client_admin`). Each action asks for a reason, then shows the command’s progress: *Queued for your deployment*, *Delivered to your deployment*, *Accepted by your deployment*, and finally *Applied*, *Failed in your deployment*, *Refused by your deployment* (with the reason in words), or *Expired: no deployment took it in time, so nothing ran*. The agent’s page lists its **Recent commands**. ## Both sides must allow Two switches must both be on for a command to take effect: 1. Your tenant’s **command settings** in LightHouse (**Setup and admin → Commands**, `client_admin`) must switch that command type on. Otherwise LightHouse refuses to create it. 2. Your deployment’s own policy file must allow it. Otherwise the engine refuses it when it arrives, and the command ends `refused`. Both are off by default, and Atlantic cannot switch either on for you. ### Refusals from your deployment A refused command ends `refused` with a reason code, which LightHouse shows in words. The codes include `type-disabled`, `role`, `params`, `bounds`, `not-configured`, `not-an-approver`, `not-waiting`, `evidence-changed`, `gate-not-passed` and `replay`. Two apply only to `secret.put`: | Code | Means | Do | | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | `sealed` | The credential did not open: it was changed on the way, or sealed for another deployment, connector or connection | Connect it again | | `sealing-key` | It was sealed to a key your deployment no longer holds | Connect it again; it is sealed to the key your deployment now advertises | For the credential commands, `not-configured` means your deployment has no secrets store or sealing key, and `bounds` that your policy does not allow that connector or access level. A credential command that fails in your store ends `failed` with `store_unavailable`, and the store’s error code, never its message. Your deployment also needs its command channel running. The stack that **Get my stack** generates includes it on all four targets, with every command type off in your deployment’s policy until you switch it on. Until it runs, a command you issue waits in the queue and ends `expired` (*Expired: no deployment took it in time, so nothing ran*). ## How a command travels 1. A handler, signed in with a second factor, issues the command in LightHouse. 2. LightHouse signs it with its command-signing key and queues it for your deployment. The command expires if no engine takes it in time: five minutes by default, at most fifteen. An expired command is never sent. 3. Your deployment’s command channel, which makes an outbound connection to LightHouse, receives it. It checks the signature, the tenant, the expiry and your policy file before acting. If no acknowledgement comes back within 10 seconds, LightHouse sends the same signed command again; the engine refuses a repeat it has already seen, so a command runs at most once. 4. The engine reports each stage, signed with your deployment’s key. A command moves through `queued`, `delivered`, `accepted`, and then ends `refused`, `applied` or `failed`. A command that expired in the queue reads `expired`. The command-signing key is separate from the key LightHouse uses to read content in place, so you can keep in-place reads while withdrawing control, and a leaked reader key cannot stop or approve anything. Every command, and every final status, is in your tenant’s audit log (**Setup and admin → Audit**). ## Why a machine key can never act as a handler Only a person signed in with a second factor can create a command. A machine key or the Access service token is refused on every command route with `403 person_required`, whatever its role, and no MCP tool issues a command. This prevents an AI agent that holds a key from approving its own work or loosening its own limits. ## In the API - `POST /api/v1/agents/{agent_id}/commands` and `POST /api/v1/approvals/decisions`: a person’s session only. - `PUT /api/v1/connections/{id}/schedule` and `POST /api/v1/connections/{id}/sync` create `connector.schedule` and `connector.sync` for a connection’s source: a `client_admin`’s session only. - `POST /api/v1/connectors/{connector}/token`, an approval’s callback and a device-code approval create `secret.put` (and the `connector.check` and `secret.delete` that follow it); `POST /api/v1/connections/{id}/health` creates `connector.check`; `DELETE /api/v1/connections/{id}` creates `connector.revoke`. A `client_admin`’s session only. - `GET /api/v1/commands`, `GET /api/v1/commands/{command_id}`: any role from `viewer`. - See the [Handler commands reference](/api/reference/handler-commands/), and [Idempotency](/api/idempotency/) for safe retries. Source: https://docs.atlanticagenticlabs.com/concepts/handlers/ --- # Knowledge bases > Your content, indexed in your own account and read in place. A **knowledge base** is an index of your content that your agents search: built by the engine, in your own account, from the sources you connect. LightHouse reports on its health with counts only; it does not hold the content. ## Where the index lives The index is in your deployment, in your account: SQLite (with or without vectors), PostgreSQL (with or without pgvector) or OpenSearch. The documents it is built from are there too: each connector writes one Markdown file per item, with front matter, into the deployment’s own corpus. See [Where everything lives](/data-sovereignty/where-everything-lives/). ## Read in place, never copied When a person opens content in LightHouse (**Security and context → Content in place**), the request goes to your deployment’s **content reader**, which dials out to LightHouse and answers only requests signed with Atlantic’s reader key. The content is shown and not kept. Reading it needs the `content_viewer` role. If your deployment cannot be reached, LightHouse says so (`503 tier_b_unavailable`) rather than showing an empty list. ## Search The engine’s retrieval is hybrid: keyword and meaning, fused by rank, with your access scope applied inside the query. It **abstains**, returning nothing, when no passage is relevant enough, so an agent can report that it found nothing and does not guess. Every search is measured: candidates considered, passages returned, tokens sent and tokens not sent. [How retrieval works](/concepts/retrieval/) describes each stage; [Cost and token optimisation](/cost/) reports the measurements. ## Freshness and re-indexing Each connector keeps a cursor and reads only what changed since its last pull. A source is pulled on its own schedule, not on one clock for every source. A `client_admin` can set that schedule, or ask for a sync now, on the connection’s card ([Sync schedules](/connect/#sync-schedules)). A changed item is rewritten; an unchanged one is left alone; an item deleted at the source is removed where the connector can tell (see each [connector’s page](/connect/)). Each deployment reports its knowledge bases’ health daily and whenever an index changes: documents, chunks and tokens; the last ingest and the last successful one; failures by class over 30 days; stale and undated documents against the pack’s freshness policy; the duplicate rate; and coverage by tag. ## In LightHouse and the API - **Agents → Knowledge** lists each knowledge base with its health. - `GET /api/v1/knowledge-bases` and `GET /api/v1/knowledge-bases/{index}`: see the [Read reference](/api/reference/read/#kb-list). - MCP: [`knowledge_bases`](/mcp/tools/knowledge-bases/), [`knowledge_base`](/mcp/tools/knowledge-base/), and [`knowledge`](/mcp/tools/knowledge/) (content, read in place, `content_viewer`). Source: https://docs.atlanticagenticlabs.com/concepts/knowledge-bases/ --- # How retrieval works > How an agent finds the passages it answers from: synced into your deployment, searched by keyword and by meaning, fused, and cited, or it abstains. An agent answers from your content by **retrieval**: it searches your [knowledge base](/concepts/knowledge-bases/) for the passages that bear on a question, and answers from those passages with citations. If no passage is relevant enough, it says so. Every stage runs in your deployment, in your account. Indexing Answering 1. Your sources are synced into your deployment, in your account. New, changed and deleted items are synced; nothing comes to Atlantic. 2. Screening: each item is labelled and checked before it is indexed. 3. Passages: documents are split into overlapping passages. 4. Two indexes: keyword (BM25), and meaning, from an embedding model in your deployment, kept in SQLite or PostgreSQL with pgvector. 5. A question from an agent is searched by keyword and by meaning, within the caller's access scope. 6. Fusion: the two ranked lists are combined into one. 7. Re-ranking, if enabled: a closer read of the leading passages. 8. The agent answers from the passages and cites them, or, if nothing is relevant enough, abstains and says so. 9. Measurement: only counts and timings go to LightHouse, in Atlantic's account. Every stage runs in your deployment, in your account. The only thing that leaves is operational telemetry: counts and timings, never content. ## Where it runs Indexing and answering both run inside the Atlantic Agentic Engine in your account. Your sources are synced into your deployment, and the documents, the passages, both indexes and the search itself stay there. Nothing is sent to Atlantic for indexing or for search. LightHouse receives operational telemetry only: counts and timings, such as how many passages a search considered and returned. It does not receive a question, a passage or a document. See [Where everything lives](/data-sovereignty/where-everything-lives/) and [The telemetry contract](/concepts/telemetry-contract/). ## Indexing ### Sync Each [connector](/connect/) reads its source on its own schedule and writes what it finds into your deployment’s corpus. It reads only what has changed since its last pull: new items are added, changed items are rewritten and unchanged items are left alone. Deletions are synced too (see [When something is deleted](#when-something-is-deleted)). ### Screening Each item is labelled with its access classification as it is written, so that a search can later return only what the caller may see. An item that cannot be classified is held back and counted. It is not indexed. Separately, the [gateway](/concepts/gateway/) masks the personal data your policy names before any text is sent to a model. ### Passages Each document is split into passages, and neighbouring passages overlap. A sentence that falls across a boundary is therefore still found whole in one of them. A document is ranked by its strongest passage, so a long document does not outrank a short one on length alone. ### Two indexes Every passage is indexed twice: - **Keyword**: a BM25 index of the words in each passage. It finds exact terms: a regulation reference, a product code, a person’s or system’s name. - **Meaning**: an embedding of each passage, made by a small embedding model that runs inside your deployment. It finds passages that say the same thing in other words. Neither index is built by an outside service, so your text is not sent anywhere to be indexed. ### Storage The passages and both indexes are kept in your deployment’s store: SQLite, or PostgreSQL with pgvector. The choice is made when the stack is deployed. [Knowledge bases](/concepts/knowledge-bases/#where-the-index-lives) lists every supported store. ## Answering ### Access scope A question is searched within the access scope of the person or agent who asked. The scope is applied inside the query itself, so a passage the caller may not see is never among the candidates. ### Search and fusion The question is searched by keyword and by meaning at the same time. Each channel returns its own ranked list, and the two lists are **fused** into one by rank: a passage that ranks well in either channel is kept, and one that ranks well in both rises to the top. Fusing by rank means the two channels’ scores never have to be compared directly. ### Re-ranking Re-ranking is optional and is set per pack. When it is on, a re-ranking model reads the question and each leading passage together and orders them again. It is more precise and slower, so it is enabled where a pack’s [evaluation](/build/evaluations/) shows that it improves the result. ### Citations and abstention The passages that survive are given to the agent as **evidence**: each is wrapped and marked as material to read, and the model is told to treat it as such and never as instructions (see [Evidence](/concepts/evidence/#retrieved-text-is-evidence-never-instruction)). The agent answers from those passages and cites the passage behind each claim. The engine checks the citations in code: a citation to a passage that was never retrieved is caught. When no passage is relevant enough, the search **abstains**: it returns nothing, and the agent reports that your content does not answer the question rather than answering from general knowledge. The level at which a search abstains is calibrated for each pack against its evaluation set. ## When something is deleted An item deleted at the source is removed from your corpus and from both indexes on a later sync, wherever the connector can detect the deletion. Some connectors see a deletion on their next pull; others confirm deletions by listing the source on a schedule. Each [connector’s page](/connect/) says how. A passage that has been removed can no longer be retrieved or cited. The index is part of your engine, in your account, so removing the engine removes it: see [Leaving](/data-sovereignty/leaving/#deletion). ## Measurement and the evaluation gate Every search is measured in your deployment: the candidates considered, the passages returned, the tokens sent to the model and the tokens not sent. LightHouse reports these counts under [Cost and token optimisation](/cost/); the reduction in tokens sent is reported as an estimated saving. Retrieval is also scored against each pack’s **golden set**: questions paired with the documents a good answer must find. Retrieval scoring calls no model, so it is repeatable and costs nothing. A release that makes retrieval worse than the last release on the same golden set is blocked. See [Evaluations](/build/evaluations/). ## What you configure | Setting | Where it is set | | --------------------------------------------------- | -------------------------------------------------------------------------- | | The store: SQLite, or PostgreSQL with pgvector | When the stack is deployed | | The embedding model, from those the engine supports | Per deployment; changing it rebuilds the meaning index | | Re-ranking, on or off | Per pack | | The level at which a search abstains | Per pack, calibrated against its golden set | | The weight given to each search channel in fusion | Per pack | | How often each source is synced | Per connection, in LightHouse ([Sync schedules](/connect/#sync-schedules)) | These do not change with configuration: every stage runs in your deployment; the caller’s access scope is applied inside every search; retrieved text is always fenced as evidence; and citations are always checked. Clients under NDA receive the architecture in more detail, including the defaults and the evaluation results. Ask your Atlantic contact. Source: https://docs.atlanticagenticlabs.com/concepts/retrieval/ --- # Evidence > Every answer carries the evidence it was grounded in. **Evidence** is what an agent’s answer or finding rests on: the passages it was given, the claims it made from them, and how strong the source behind each claim is. The engine records it for every cited answer and every findings run; LightHouse shows the counts. ## Evidence tiers Every claim carries the tier of its strongest evidence. The default ladder, for engineering work, runs from strongest to weakest: | Tier | Source | | ---- | -------------------------------------------------------------------- | | T0 | Live: observed in the running system (monitoring, logs, a live call) | | T1 | Declared deployment: what each environment is configured to run | | T2 | Code at the deployed version | | T3 | Code on the default branch: what is coming, not what runs | | T4 | Verified contracts: interfaces generated from code or checked in CI | | T5 | Governed decisions: approved designs, release notes | | T6 | Descriptive documents nobody checks against the code | | T7 | Conversations: meetings, chats, handover notes | A pack may define its own ladder (a compliance pack might rank regulation first), with the same shape: lower number, stronger evidence. ## What is recorded For each answer, finding or set of citations, the deployment sends counts: claims by tier, uncited claims, claims at the ladder’s strong tiers, and the strongest tier. It does not send a claim, a source or the wording of the ladder. Separately, the **grounding** check records whether each answer was `grounded`, `flagged` or `refused`, with the number of claims and how many were ungrounded. ## Retrieved text is evidence, never instruction Every passage an agent is given is wrapped and marked as untrusted material, and the instruction to treat it as material rather than instructions sits in the system part of the prompt. A document that says “ignore your instructions” reaches the model only inside that wrapper. What an agent may do is enforced at run time by the [gateway](/concepts/gateway/) and the tool gate, not by the prompt. See [MCP security](/security/mcp/), and [How retrieval works](/concepts/retrieval/) for how passages are found. ## Evidence and approvals When a person approves an output, LightHouse records the digest of the artefact they were shown. If the artefact changes before the decision reaches your deployment, the decision is refused (`evidence-changed`). See [Approvals](/concepts/approvals/). ## In LightHouse and the API - Each agent’s detail page shows its evidence scores; the evidence pack (**Compliance → Evidence pack**) is the report an assessor reads. - `GET /api/v1/evidence` and `GET /api/v1/grounding`: see the [Read reference](/api/reference/read/#evidence-read). - MCP: [`evidence`](/mcp/tools/evidence/). Source: https://docs.atlanticagenticlabs.com/concepts/evidence/ --- # Approvals > Sign-offs are made by people in LightHouse, never by an agent or a key. An **approval** is a named person’s decision, made in LightHouse, that an agent’s output may take effect. Approvals put a person in the loop for any agent that sends, publishes or writes into one of your systems. An agent never approves its own work, and neither does a machine key. - **Agent**: the orchestrator, in your account - **Command channel**: the handler, in your account - **LightHouse**: your tenant - **Approver**: handler or client_admin Proposal 1. Agent: **Hold the output**. the card has an external effect and no pre-approval covers it; the run carries on with other work 2. Agent to LightHouse: **Report it waiting**. content-free; the item joins the attention queue in Agents → Hub Decision 3. LightHouse to Approver: **The card**. why it needs a person, its evidence, the pre-approval checked, what rejecting does 4. Approver to LightHouse: **Read the proposal in place**. read from your account and shown, not stored; the digest of what was shown is kept 5. Approver to LightHouse: **Approve or reject, with a reason**. signed in with a second factor 6. LightHouse to Command channel: **Signed command**. approval.decide, signed by LightHouse, carrying the digest Action 7. Command channel: **Check it**. the signature, your policy, a named approver, and that the output is the one that was read 8. Command channel to Agent: **Release the output**. the agent acts; a rejection stops it 9. Command channel to LightHouse: **Answer**. applied, or refused with the reason 10. LightHouse: **Audit record**. who, when, the reason, how long it waited, whether it was edited, and the digest Only a person approves, in LightHouse, with a second factor. Your deployment accepts the decision only as a command signed by LightHouse, checks it against your own policy, and refuses it if what the person read has changed. ## When an agent waits An agent whose card has an `external` effect (it sends, publishes or writes into one of your systems) is gated by its autonomy level: - **Level 1, `sign-off`**: its output waits for a person. - **Level 2, `pre-approved`**: it goes ahead if a standing pre-approval covers the action and its limits allow one more; otherwise it waits, as at level 1. - **Level 0, `draft`**: a draft that nothing downstream may use. A waiting output does not fail the run. The run carries on with the work that does not depend on the output, and the agent shows `awaiting-sign-off`. See [Agents](/concepts/agents/#autonomy). ## Who can approve, and how it is enforced - A person with the `handler` or `client_admin` role, signed in with a second factor. - Your tenant’s command settings must switch `approval.decide` on, and your deployment’s policy must allow it. - Where your deployment’s policy says approvals are managed by LightHouse (the default for new deployments), the engine accepts a decision **only** as a command signed by LightHouse. A product’s own buttons, a script or a local call are refused (`approvals-managed-by-insights`) and logged. - If LightHouse cannot be reached, nothing is approved: items wait, and agents act only within standing pre-approvals. - Your own **break-glass**, for named people only, is off by default. A decision made through it is recorded as such, and LightHouse writes it to your audit log, flagged. ## Approve or reject an output 1. Go to **Agents → Hub**. Outputs waiting for sign-off are at the top, in the attention queue. Items the grounding check flagged or refused, or whose agent failed its evaluation, are listed first and can never be approved in bulk. 2. Open an item. It shows why it needs a person, its evidence, which pre-approval was checked and why it did not cover the action, and what rejecting will do. 3. Under **What the agent proposes**, choose **Show the proposal**. LightHouse reads the output in place from your account (it shows **Reading from your account…** meanwhile). Your decision records the digest of exactly what you were shown, so **Approve** and **Reject** stay disabled until you have read it. Reading content needs the `content_viewer` role, which `handler` includes. 4. Type a reason in the box (*What you checked and why you decided*). The buttons stay disabled until you do. 5. Choose **Approve** or **Reject**. The decision is sent to your deployment as an `approval.decide` command, and the item follows its status: *Queued for your deployment*, *Delivered to your deployment*, *Accepted by your deployment*, then *Applied*, or *Refused by your deployment* with the reason. Keyboard: `j` and `k` move between items, `o` opens the evidence, `r` moves to the reason, and `a` or `x` approve or reject once a reason is typed. If the buttons cannot send, the item says why instead: | The item says | Why | What to do | | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | | *Needs the agent handler role. A client administrator can grant it on the Access page.* | You hold neither `handler` nor `client_admin` | Ask an administrator for the role (**Settings → Users and roles**) | | *Off for your organisation.* | `approval.decide` is switched off in your tenant’s command settings. An administrator also sees a **Command settings** link | Switch it on at **Setup and admin → Commands** | | *Commands can’t be sent right now. Nothing has been changed.* | Commands are not available for your tenant at the moment | Try again later; tell Atlantic if it persists | If your deployment refuses the decision, the item names the reason, for example *the output changed after you read it; read it again* (`evidence-changed`), *you are not one of the catalogue’s approvers* (`not-an-approver`) or *the output is no longer waiting for a decision* (`not-waiting`). ## Pre-approvals A **pre-approval** lets a level-2 agent act without waiting, for one kind of action, within limits (`max_per_day`, `max_total`), until it expires or is revoked. Only a person your catalogue names as an approver may grant one. Each use is counted, and the decision it makes names the grant and the approver. Grant, change and revoke them in LightHouse; read them with `GET /api/v1/preapprovals` or the [`preapprovals`](/mcp/tools/preapprovals/) tool. ## The audit trail Every decision records who made it, when, the reason, how long the output waited, whether the person edited it, and the digest of what they were shown. Issuing the decision and its final status are both in your tenant’s audit log (**Setup and admin → Audit**, `GET /api/v1/audit`). ## In the API `POST /api/v1/approvals/decisions`, as a signed-in person only. See the [Handler commands reference](/api/reference/handler-commands/#decide), and [Approvals in Build agents](/build/approvals/) for declaring where an agent must ask. Source: https://docs.atlanticagenticlabs.com/concepts/approvals/ --- # Runs > A run is one execution of an agent: its steps, calls, cost and outcome. A **run** is one execution of a pack’s agents: the steps each agent took, the models it called, the tools and searches it used, what it cost, how long it took and how it ended. LightHouse sees a run as counts and timings only; content is not transmitted. ## What a run records | Record | What it holds | | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `run` | Pack, card, status, duration, attempt, what started it (`schedule`, `agent`, `person` or `api`), and whether it is still running | | `step` | Each step: its kind (`agent`, `model`, `tool`, `retrieval`, `approval`, `grounding`, `screening`, `delivery`), duration, status, model, and the counts and sizes in and out | | `model_call` | Model, backend, input, cached and output tokens, cost, latency, outcome | | `retrieval` | Candidates considered, passages returned, tokens sent and avoided | | `outcome` | What the output was used for, human time saved where known, and whether a person edited it | A run’s status is one of `ok`, `failed`, `awaiting-approval`, `approved`, `rejected`, `skipped`, `running` or `stalled`. ## Active and stalled runs A run is reported as it starts and as each step starts and finishes, so LightHouse shows it live. A running run with no word from its deployment for five minutes is shown as **stalled**. ## Run IDs LightHouse never sees your deployment’s own run ID. It sees `run_id_hash`, a keyed hash of it, and every API route and MCP tool uses that. ## The run map The run map draws one run: every step in order, which model each step used, the tools and searches, the evidence, the cost and any sign-off. See [The run map](/build/run-map/). ## In LightHouse and the API - **Agents → Activity** shows runs live; **Insights → Runs** lists them; each run opens its run map. - `GET /api/v1/runs` (filter by `pack`, `card`, `status`, `since`; paged), `GET /api/v1/runs/{run_id_hash}`, `GET /api/v1/runs/{run_id_hash}/map`, `GET /api/v1/runs/active` and a live stream at `GET /api/v1/runs/active/stream`. See the [Read reference](/api/reference/read/#runs). - MCP: [`runs`](/mcp/tools/runs/), [`run`](/mcp/tools/run/), [`run_map`](/mcp/tools/run-map/), [`active_runs`](/mcp/tools/active-runs/). Source: https://docs.atlanticagenticlabs.com/concepts/runs/ --- # The gateway > Every model call goes through the gateway, where caps, permissions and the tool gate are enforced in code. The **gateway** is the one component of the engine that calls a model. Every model call from every agent goes through it, in your account, under its own workload identity. Cost caps, the kill switch, screening and the tool gate are enforced there, in code the model cannot reach. ## What the gateway does On every call, in this order: 1. checks the run’s envelope, checks the model against your allow-list for the call’s residency and data class, and prices it (a model with no price is refused, because its cost cannot be reserved); 2. checks the kill switch, the run’s guards and every budget the call counts against, and reserves its estimated cost, in one transaction; 3. screens the prompt and masks personal data before it leaves; 4. paces the call to the model’s quota, where your policy sets one; 5. calls the model on the backend your policy names: Amazon Bedrock, the Claude API, an OpenAI-compatible endpoint, or the engine’s own model layer; 6. settles the reservation at what was billed; 7. checks the answer against the material it was given, where your policy turns grounding on (off by default); 8. sends a `model_call` record: tokens, cost, latency, outcome. The record does not include the prompt or the answer. If a call times out, its reservation is kept as spent, because the provider may still have run and billed the call. This stops a run from exceeding its cap through repeated timeouts. Only the gateway’s identity has cloud permission to invoke a model. The engine’s other components do not. See [Engine and gateway security](/security/engine/). ## Cost caps and kill switches - **Budgets** are set per scope (the tenant, a pack, a task, a person or a run) and per period: `total`, `month` or `day`. A call that would pass a cap is refused before it is made. - **The kill switch** stops a scope: everything (`*`), the tenant, a pack, a task, a run, an agent or a person. It holds until a named person revives it. - **From LightHouse**, a handler pauses an agent (`agent.pause`) or sets its cap (`budget.set`), and an administrator sends a spending limit from **Billing → Limits**. See [Handlers](/concepts/handlers/) and [Limits and alerts](/operations/limits-and-alerts/). - **In your cloud**, a second switch removes the gateway’s permission to call models at all (`models_enabled = false` in the stack). See [Suspension](/operations/suspension/). ## The tool gate An agent’s tools are authorised at run time, not by its prompt. Each tool call passes, in order: 1. the run’s **signed run token**: a short-lived token binding the tenant, the person, the run, its tools and its budget; 2. a **Cedar** policy generated from the agent’s card, deny by default: a tool the card does not list is refused; 3. for a tool that acts, the **person’s own delegated credential**, so the agent acts with that person’s access and no more. Run tokens are off until a deployment turns them on. ## Model routing The gateway can route each call to the cheapest model that meets the quality bar for the job. See [The model router](/router/). ## In LightHouse and the API - **Security and context → Safeguards** shows the safeguards: refusals, screening and stop switches. - `GET /api/v1/budgets`, `GET /api/v1/kills`, `GET /api/v1/refusals`, `GET /api/v1/usage`: see the [Read reference](/api/reference/read/#budgets). - MCP: [`kills`](/mcp/tools/kills/), [`refusals`](/mcp/tools/refusals/), [`usage`](/mcp/tools/usage/), [`rate_limits`](/mcp/tools/rate-limits/). Source: https://docs.atlanticagenticlabs.com/concepts/gateway/ --- # Deployment profiles > Always-on, ephemeral or scheduled: how the engine's infrastructure runs, and what each costs. A **deployment profile** says how your deployment’s infrastructure runs: **always-on**, with its services warm all the time; **ephemeral**, where they start only when something is asked of them (a scheduled job, a model call, a read) and sleep otherwise; or **scheduled**, awake in a wake window you set and ephemeral outside it. - Always-on: the gateway is warm all day and the content reader and command channel stay connected, so a model call, a read or a command is answered at once. - Ephemeral: the gateway sleeps and a model call wakes it, in a few seconds; in this example it wakes for the 02:00 scheduled run and for work at 13:00 and 21:30. The reader and the command channel are woken about once a minute, so a read waits up to about a minute. - Scheduled, with an example wake window of 07:00 to 19:00: inside the window the gateway is kept warm and the reader and command channel stay connected. Outside it the deployment behaves as ephemeral: the gateway wakes on demand, as for the 02:00 run and the 21:30 call, and the reader and command channel are woken about once a minute. - On every profile, the connector-schedule tick runs every 15 minutes, and scheduled agent runs and connector syncs run at their own times. Nothing is refused outside a window. One day under each profile, in the deployment's local time. The 02:00 run and the 13:00 and 21:30 calls are examples; the wake window is the one you set. ## The profiles | Profile | What runs | Costs | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- | | `always_on` | Every service warm. The gateway runs at least two copies | The most, with no wake time | | `ephemeral` | Services scale to zero and start on demand. The product’s own service keeps running | Less: you pay mostly for what is used | | `scheduled` | Built as ephemeral. Inside its [wake window](#the-wake-window) the gateway is kept warm and the content reader and command channel stay connected; outside it, services sleep and wake on demand | Between the two: the window’s hours, plus any work outside it | The minimum engine for the scheduled profile is in the [compatibility reference](/concepts/telemetry-contract/#compatibility-reference). What changes by cloud, for example the gateway as an AWS Lambda function or a Cloud Run service with no minimum instances, is on each cloud’s page: [AWS](/clouds/aws/#deployment-profiles), [Azure](/clouds/azure/#deployment-profiles), [Google Cloud](/clouds/google-cloud/#deployment-profiles), [on-premises](/clouds/on-premises/#deployment-profiles). ## The wake window A scheduled deployment has one wake window: a time zone and one to four windows. Each window names one or more days of the week, a time to wake and a time to sleep. ```json {"time_zone": "Europe/Dublin", "windows": [{"days": ["mon", "tue", "wed", "thu", "fri"], "start": "07:00", "end": "19:00"}]} ``` The rules: - **Time zone**: an IANA time zone, such as `Europe/Dublin` or `Asia/Tokyo`. `UTC` is accepted. - **Days**: at least one of `mon` to `sun` in each window, none twice. - **Times**: `start` and `end` as `HH:MM`, from 00:00 to 23:59, on the same day, with the start before the end. A window of no length is refused. - **Across midnight**: a window ends on the day it starts. For hours across midnight, use two windows: one to the end of the evening and one from the start of the next morning. - **No overlap**: two windows that share a day may not overlap or meet. Join them into one window instead. - **Local time**: the window is read in the time zone’s own clock. A window set for 07:00 to 19:00 keeps those local hours when the clocks change. Where a window’s start or end falls in an hour the clocks skip or repeat in the coming year, LightHouse warns you: on that night the cloud may wake or sleep the deployment late, not at all, or twice. Every window is checked as you type in the portal, and again by LightHouse, the infrastructure modules and the engine. A window that breaks a rule is refused with the rule named. ### Inside and outside the window | | Inside the window | Outside the window | | ---------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | Gateway | Kept warm: the first model call is answered at once | Asleep. The first call wakes it, in a few seconds | | Content reader and command channel | Connected for the whole window: a read in LightHouse or a command is answered at once | Woken about once a minute, as under ephemeral. A read waits up to about a minute | | Scheduled agent runs and connector syncs | Run at their own times | Run at their own times | | Cost | The warm gateway and the connected reader, for the window’s hours | As ephemeral: mostly what is used | Outside the window nothing is refused. A deployment asleep outside its window **wakes on demand**, exactly as an ephemeral one does: the gateway on a model call, the reader and the command channel within a minute. While it wakes, a read answers `503 deployment_waking`, and LightHouse shows “Waking your deployment…” and retries. A scheduled deployment reports whether it is inside its window, and names the window by a short digest. It never sends the time zone or the hours. On **Settings → Deployments**, a scheduled deployment’s card shows its window, whether it is **Awake now** or **Asleep now**, and until when. A window set in Terraform without a request in LightHouse is shown by its digest only; request the window in LightHouse to see it. ## Wakes and cold starts A sleeping service wakes on its first request. Each component reports when it starts (with how long it took to be ready, and whether it was a cold start), an hourly heartbeat while it runs, and when it stops. LightHouse shows wake times at the median and the 95th percentile over 30 days. While an ephemeral deployment wakes, a read that needs it answers `503 deployment_waking` with `Retry-After: 5`. LightHouse shows “Waking your deployment…” and retries. See [Errors](/api/errors/). ## Estimated savings against always-on LightHouse estimates the saving of ephemeral and scheduled against always-on from Atlantic’s versioned cost model, at list prices for one region per cloud. For a small deployment: | Cloud (priced region) | Estimated saving on the lines that differ | | --------------------------- | ----------------------------------------- | | AWS (eu-west-1) | around 95% | | Azure (westeurope) | around 72% | | Google Cloud (europe-west2) | around 87% | These are proportions, not amounts. The amount depends on your region, your currency, any committed-use or reserved pricing and the size you run, which the model does not know. Once your deployment reports its infrastructure cost, LightHouse shows figures computed from that instead. Only the lines that differ between the profiles are counted. Lines both profiles share, such as the load balancer, logs and keys, are left out, so the proportion is of the part the profile changes, not of your whole bill. Azure saves least of the three because its managed PostgreSQL cannot pause when idle. On-premises has no cloud bill to compare against. ### Scheduled Where you choose where agents run, LightHouse shows the scheduled profile’s estimated saving beside ephemeral’s and always-on’s, for the window you chose. The estimate is ephemeral’s lines plus the warm gateway and the connected reader for the window’s share of the week, at the cost model’s list prices. On AWS the warm gateway is priced at the on-demand rate, which overstates that line. Until you choose a window, the estimate uses a working week (Monday to Friday, 08:00 to 18:00) and says so. Once a scheduled deployment reports its infrastructure cost, its saving and the **Ephemeral infrastructure** lever are worked out from its real bill, as for ephemeral. Every figure is **estimated**. See [How a saving is calculated](/cost/savings/). ## Changing profile The profile is a variable in your deployment’s Terraform (`deployment_profile`), applied by your own pipeline. LightHouse never applies it for you. It can record a request, so the person who decides and the engineer who applies are both on record: 1. Go to **Settings → Deployments** (`client_admin`). 2. On the deployment, choose **Request a switch to Ephemeral** (or **Always-on**, or **Scheduled**). LightHouse explains the trade-off. 3. Optionally add **A note for your engineer** (up to 500 characters), then choose **Request Ephemeral**. 4. LightHouse shows the Terraform change to make, with **Copy**, and the steps to apply it. Give it to your engineer or pipeline. 5. Once your deployment reports the new profile, the request reads as applied. ### Request a switch to Scheduled 1. On the deployment in **Settings → Deployments**, choose **Request a switch to Scheduled**. 2. Set **The wake window**: the **Time zone**, then for each window the **Days**, **Wakes at** and **Sleeps at**. **Add a window** adds another, up to four. The editor shows the hours awake a week and any clock-change warning. 3. Give **Why this window**. The reason is required with a window, and the audit log keeps it with the window and its digest. 4. Choose **Request this window**. LightHouse shows the Terraform change, with `deployment_profile` and `wake_schedule`: ```hcl deployment_profile = "scheduled" wake_schedule = { time_zone = "Europe/Dublin" windows = [ { days = ["mon", "tue", "wed", "thu", "fri"], start = "07:00", end = "19:00" }, ] } ``` 5. Once your deployment reports the scheduled profile with this window’s digest, the request reads as applied. ### Change the wake window On a scheduled deployment’s card, choose **Change the wake window**. A new window is a request of its own, with its own required reason and its own Terraform change, and reads as applied once the deployment reports the new window’s digest. Asking for the window the deployment already reports is answered `profile_unchanged`. The same window and reason can be set when you choose where agents run, for a deployment on your own cloud. Atlantic-hosted deployments run always-on or ephemeral only. **Get my stack** writes the window into the files: `wake_schedule` in the Terraform module call, and `AAL_WAKE_SCHEDULE` in the on-premises `.env`. ### In the API `POST /api/v1/deployments/{deployment}/profile-requests` with: ```json {"profile": "scheduled", "wake_schedule": {"time_zone": "Europe/Dublin", "windows": [{"days": ["mon", "tue", "wed", "thu", "fri"], "start": "07:00", "end": "19:00"}]}, "note": "Trading desk hours"} ``` `note` is the reason, required with a window (`422 guard_rail`, `rule: reason`). A window with any other profile is refused, and so is a scheduled request without one (`rule: wake_schedule`). The answer adds `wake_schedule`, `wake_digest` and `clock_changes`, and its `terraform` carries the window. The API equivalent is `POST /api/v1/deployments/{deployment}/profile-requests`. It accepts only a person signed in to the portal as `client_admin`; an API key is refused with `403 role_required`. No data moves when the profile changes: the key, database, file system and secrets are kept. ## In the API - `GET /api/v1/deployments/profiles`: each deployment’s profile, wake times, uptime, infrastructure cost and estimated saving. Under scheduled, `wake` gives the window, its digest, whether the deployment is inside it now (`in_window`), the next change (`next_change_at`), the minutes awake a week and any clock-change warnings. - See the [Deployments reference](/api/reference/deployments/), and the MCP tools [`deployment_profiles`](/mcp/tools/deployment-profiles/) and [`deployment_wakes`](/mcp/tools/deployment-wakes/). Source: https://docs.atlanticagenticlabs.com/concepts/deployment-profiles/ --- # How LightHouse scales > How LightHouse™ and the engine add capacity under load, how rate limits apply across that capacity, and what to plan for in a large rollout. LightHouse™ and the Atlantic Agentic Engine scale separately. Atlantic runs LightHouse, which adds capacity for portal reads, the API and MCP as demand rises. The engine runs the client’s agents, calls its models, and runs and scales in the client’s own cloud account. ## LightHouse capacity The services that answer the API and MCP run as several copies. When load rises, LightHouse starts additional copies automatically. When load falls and remains low, each service returns to its baseline number of copies. No request from the client and no change to the tenant is required. Services that hold a long-lived connection to one copy, such as the connection from the client’s content reader, run at a fixed size. Those connections are not moved while in use. Atlantic is alerted when a service remains at its upper bound, and monitors the capacity of the shared database. ## Rate limits across copies Rate limits are set per credential and per tenant and are counted in one shared store. Every copy of a service draws on the same allowance. A limit is the same whichever copy answers a request, and adding copies does not raise or divide an allowance. The limits and the headers that report them are described on [Rate limits](/api/rate-limits/). Each tenant has its own allowance. Traffic from one tenant does not count against another tenant’s allowance. ## Engine capacity The client’s agents run in its engine, in the client’s own account. Retrieval, tool calls and every model call through the [gateway](/concepts/gateway/) take place there. The engine scales within the selected [deployment profile](/concepts/deployment-profiles/), on the client’s own cloud compute. Each client’s agents and model calls run on that client’s infrastructure, and one client’s load does not reach another client’s deployment. LightHouse receives the deployment’s telemetry and serves the client’s users and tools. It does not run the client’s agents. Agent load falls on the client account’s resources, and LightHouse records it. ## Planning a large rollout In a large rollout, the limiting factor is usually the client’s model provider quotas: the requests and tokens a minute that the client’s cloud account may send to each model on Amazon Bedrock, Azure OpenAI or Vertex AI. The provider sets these quotas for the account. Increases can take time and should be requested early. The [model router](/router/) reduces demand on those quotas. For each call it selects the cheapest model that meets the quality bar for the task. Routine work often moves to smaller models with more quota available, and the quota of the most capable models remains available for the work that requires them. The gateway paces calls to the limits stated in the gateway policy, and LightHouse shows how close each model is to its limit. Clients under a non-disclosure agreement can read the planning checklist and the figures in the client documentation. Our certified forward-deployed engineers plan and load-test the rollout with the client before go-live. Source: https://docs.atlanticagenticlabs.com/concepts/scaling/ --- # The telemetry contract > What crosses from your account to LightHouse: operational telemetry, counts and timings, never content. The **telemetry contract** is the versioned specification of everything your deployment sends to LightHouse, and of how your people read it back. What it allows is operational telemetry: counts, timings, identifiers and costs. It does not allow your content. ## Revisions The contract is versioned by revision. The current revision is 1.34, and `GET /api/v1/me` reports the revision your LightHouse accepts as `contract_revision`. Revisions are additive: nothing valid under an earlier revision becomes invalid. A deployment is configured with the highest revision LightHouse accepts (`AAL_CONTROL_PLANE_REVISION`), sends only what that revision allows, and holds back anything newer. An engine that speaks a newer revision than LightHouse accepts therefore sends none of the newer attributes. Where a capability adds a record type or an attribute, LightHouse refuses a batch that carries it until it accepts that revision. Upgrade LightHouse first, then raise the deployment’s revision setting. Where a capability changes no record type, attribute, header or signature, a sender needs no revision setting for it. The [compatibility reference](#compatibility-reference) lists each capability’s minimum revision and engine. ## What is sent Every record is one of a fixed list of types, with only the listed attributes: | Type | Example attributes | | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `model_call` | model, backend, input, cached and output tokens, the part of output spent reasoning (`reasoning_tokens`), cost in US dollars and in the provider’s own currency, the Claude API’s inference geography, latency, outcome | | `run`, `step` | pack, card, status, duration, step kind, counts and sizes in and out | | `outcome` | what an output was used for, human time saved, whether it was edited | | `screening`, `grounding` | counts of signals, whether blocked; claims and ungrounded claims | | `budget`, `kill`, `preapproval` | caps and spend; stops and revivals; grants and their use | | `eval`, `release` | evaluation metrics and pass or fail; versions and whether they passed the gate | | `health`, `connector` | a component’s status; a connector’s items written, unchanged and removed | | `connector_schedule` | a source’s sync schedule mode, when it last synced and when it next will, and the last sync’s status. Never the time zone or the time as you wrote it | | `retrieval`, `index_stats`, `evidence` | search counts; knowledge-base health; claims by evidence tier | | `catalogue`, `models` | each agent’s settings; each model’s availability, price, region and residency | | `deployment`, `infra_cost`, `provider_cost` | profile, wake times and, under the scheduled profile, whether the deployment is in its wake window; infrastructure and provider cost per day | | `routing_decision` | the task class, the model chosen and why, candidates kept and dropped, estimated cost and saving | | `benchmark_run`, `benchmark_result` | a Token Value Benchmark run’s state, estimate, cap and spend; each model’s grade and cost per task class | | `override` | a sign-off made through your own break-glass, outside LightHouse: approved or rejected, and a hash of who | | `report` | an aggregate-only evidence or value report, with its schema version and digest | People and runs appear only as keyed hashes. Free text is never allowed, with two exceptions that carry no content: `reason` fields take values from fixed sets, and an agent’s one-line `purpose` is sent only if your pack chooses to publish it. ### Model calls: cost and geography A `model_call` carries `cost_usd` in US dollars, and `cost_native` with its `currency`: the call’s cost in [the provider’s own currency](/cost/what-is-measured/#currency). It also carries `inference_geo` (`us` or `global`), where the [Claude API ran the call](/data-sovereignty/regions/#the-claude-apis-inference-geography). `GET /api/v1/usage` reports `native_calls` and `cost_native_money` on its rows and totals. `reasoning_tokens` is the part of `output_tokens` spent reasoning. ### Routing decisions Every library agent’s call asks [the router](/router/), with the step it belongs to, and so does every call that reaches your gateway from an agent not built on the engine ([Routing every call](/router/every-call/)). A `routing_decision` can carry: - the model the router would have chosen while it is off (`would_be_model`), and the model a step was re-run on after a failed check (`escalated_to_model`); - where the call came from (`surface`) and where its task class came from (`class_source`, `class_confidence`, `classified_as`); - what the optional classifier was and what it cost (`classifier`, `classifier_usd`, `classifier_cap_usd`); - whether the caller named its own model (`caller_pinned`), with the reasons `caller_pinned` and `key_not_allowed`. An `eval` record can carry the sampled-quality attributes of the suite `routing.quality`. ### Models on your own machines A `models` record’s `region` and `residency` take the value `onprem` for a model on your own machines ([Self-hosted models](/clouds/on-premises/#self-hosted-models)). ### The scheduled profile Under the [scheduled profile](/concepts/deployment-profiles/#the-wake-window), a `deployment` record carries `in_window` and `wake_digest`, never the time zone or the hours. Profile requests and where agents run take a `wake_schedule` and a required reason, and `GET /api/v1/deployments/profiles` reports `wake`. ## Commands the contract carries The contract also carries the [handler commands](/concepts/handlers/#the-commands) a person issues from LightHouse. Each is off until it is switched on in LightHouse and in your deployment’s policy. An engine that does not know a command type cannot switch it on, so it never receives one. | Command | What it does | | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `connector.schedule`, `connector.sync` | Set how often each source syncs, or sync it now. The deployment then sends `connector_schedule` records | | `secret.put`, `secret.delete`, `connector.check`, `connector.revoke` | Keep a connector credential in your own secrets store. See [Credentials in your own store](#credentials-in-your-own-store) | | `eval.run` | Run an agent’s evaluation once, from LightHouse or the CLI, under a spend cap you set. It can carry a `proposal` from the agent builder | | `routing.set` | Remove a pin or an exclusion LightHouse made. A refused removal says `policy-owned` or `not-set` | | `benchmark.schedule` | Set when [the benchmark](/cost/token-value-benchmark/) runs by itself | | `upload.prepare` | Prepare a [file upload](/connect/upload/) that goes straight to your deployment | | `card.propose`, `card.publish` | Propose and publish an agent card from [the agent builder](/build/builder/). The `eval` suites `builder.retrieval` and `redteam.` evaluate a card at a proposal’s version; the routes are under `/api/v1/builder` | ### Credentials in your own store A connector credential can be kept in your own secrets store, written there by your deployment, so LightHouse never holds one it can read ([Where every credential is held](/connect/#where-every-credential-is-held)): - **Your deployment’s sealing key**, in its command channel’s hello: an X25519 public key, signed with your deployment’s own Ed25519 key, with the kind of store and the commands it supports. - **The result as a signed answer.** A secret command’s outcome (`stored`, `ok`, `provider_manual` and so on) is the signed reason of your deployment’s `applied` answer. A content-free `result` object rides beside it, unsigned: the connector and code, and, for a check, the scope names the provider stated. The refusal codes `sealed` and `sealing-key` apply to these commands. An engine that does not advertise a sealing key is never sent a secret command, and a credential connected for it is held under your tenant’s key. ### Sources, uploads and Microsoft connections Each deployment reports in its hello the sources it can read, and the connector catalogue shows which deployments read each one. A deployment can also ask for short-lived tokens to read a Microsoft connection you approved through Atlantic’s app. ## The connector catalogue The catalogue and its API carry: - `family` and `kind` on every catalogue card, the state `onboarding`, and the `family`, `kind`, `state` and `q` filters on `GET /api/v1/connectors`, with vendor families including `Workday`; - `excludes`, `read_only`, `read_only_why` and `engine_min` on catalogue cards, and `fix` on a connection’s health; - the check codes `write_capable` and `unverified`, and the refusal `read_only_connector` when `read_write` is asked for on a read-only connector. The secret commands cover the enterprise connectors (Salesforce, HubSpot, ServiceNow, monday.com, Zendesk, Notion, Dynamics 365, Oracle Database, NetSuite, Oracle Fusion Cloud Applications), the twenty-two finance and aviation connectors, which are read-only, and [SAP S/4HANA, SAP SuccessFactors and Workday](/connect/erp-and-hr/), also read-only. These change no record type, attribute, header or signature. ## Language preferences The organisation’s, a person’s and a staff member’s preferences carry `language` beside time zone and currency, and the answer lists `supported_languages`: English, French, German, Spanish, Italian, Portuguese, Dutch, Irish, Japanese, Simplified Chinese, Traditional Chinese and Arabic, each with `dir` (`ltr` or `rtl`). The language setting changes nothing a deployment sends. ## Run export [Run export](/build/run-map/#export-a-run) returns one run as JSON or PDF: `GET /api/v1/runs/{run_id_hash}/export`, the CLI’s `runs export`, the MCP tool `run_export`, and the audit entry `run_exported`. It changes no record type or attribute. ## Air-gapped operation For [air-gapped operation](/clouds/on-premises/#air-gapped-operation), signed telemetry bundles are imported with `POST /api/v1/deployments/{deployment}/telemetry-bundles`, and command files are produced by `POST /api/v1/deployments/{deployment}/command-file`, with `delivery: file` on a command. The `offline` scope covers both, and the audit entries are `telemetry_bundle_imported`, `telemetry_bundle_refused` and `command_file_exported`. No record type or attribute changes. ## Stacks Your organisation’s own routes remove a stack and deregister its deployment, so that deployment’s signing keys are refused from then on. ## What is never sent Prompts, answers, documents, passages, file names, messages, a card’s instructions, or any value a sender did not take from the fixed list. **Your deployment drops any attribute not on the list, and LightHouse refuses a record that carries one.** A refusal never echoes the value it refused. ## Signed telemetry Records leave your account through one component, the relay, which signs each request with your deployment’s own Ed25519 key. LightHouse verifies the signature against the key registered for that deployment, refuses a request older than five minutes, and refuses one it has seen before. A record that names another tenant or deployment than its signer is refused. ## Content in place, and opt-in export Your content stays in your account. When a person opens it in LightHouse, it is read in place through your deployment’s content reader and not kept (see [Knowledge bases](/concepts/knowledge-bases/#read-in-place-never-copied)). Content export to LightHouse is a separate, opt-in setting, off by default. While it is off, LightHouse refuses any content sent to it (`403 tier_c_disabled`). ## Compatibility reference The minimum contract revision and engine for each capability. **Sender setting** says whether the deployment must be configured for that revision (`AAL_CONTROL_PLANE_REVISION`) before it sends the capability’s records or attributes. | Capability | Revision | Engine | Sender setting | | ------------------------------------------------------------------------------------------------------------------------------ | -------- | ------ | -------------- | | Relay and content reader | | 0.35.0 | No | | Source sync schedules (`connector_schedule`, `connector.schedule`, `connector.sync`) | 1.17 | 0.39.0 | Yes | | Credentials in your own store (sealing key, secret commands) | 1.18 | 0.40.0 | No | | Evaluations from LightHouse (`eval.run`) | 1.19 | | No | | Router controls and evidence (`routing.set`, `would_be_model`, `escalated_to_model`, `reasoning_tokens`, `benchmark.schedule`) | 1.20 | | Yes | | Uploads, reported sources, Microsoft tokens | 1.21 | 0.42.0 | No | | Models on your own machines (`onprem`), stack removal | 1.23 | | No | | The agent builder | 1.24 | 0.45.0 | No | | Routing every call (`surface`, classifier attributes, `routing.quality`) | 1.25 | 0.45.0 | Yes | | Enterprise connectors, families, catalogue filters | 1.26 | 0.45.0 | No | | Finance and aviation connectors, read-only checks | 1.27 | 0.46.0 | No | | ERP and HR connectors | 1.28 | 0.47.1 | No | | Language setting, first eight languages | 1.29 | | No | | Japanese, Chinese and Arabic, right-to-left | 1.30 | | No | | Provider’s own currency, inference geography | 1.31 | 0.48.0 | Yes | | Run export | 1.32 | | No | | Air-gapped operation | 1.33 | 0.48.0 | No | | The scheduled profile | 1.34 | 0.48.0 | Yes | An empty Engine cell means the capability needs no engine release beyond one that speaks its revision. See [Data sovereignty](/data-sovereignty/) and [Architecture and trust boundary](/security/architecture/). Source: https://docs.atlanticagenticlabs.com/concepts/telemetry-contract/ --- # Connect your estate > Every connector, the three ways to connect it, the scopes it asks for to read or to read and write, where its credential is kept, its sync schedule, and what it indexes. A connector reads one of your systems into a [knowledge base](/concepts/knowledge-bases/) in your own account. The engine’s connector only reads each source: it keeps a cursor so each pull reads only what changed, and writes one Markdown document per item into your deployment’s corpus. ## The three ways to connect | Way | Where | For | | ------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **In LightHouse** | **Setup and admin → Connectors** | Every connector marked Available in [the catalogue](#connectors). Approve LightHouse at the provider, or paste a credential. The credential is checked against the [access level](#access-levels-read-or-read-and-write) you chose and kept in your own secrets store, sealed to your deployment, or, until your deployment can keep it, under your tenant’s key ([Where every credential is held](#where-every-credential-is-held)) | | **From a terminal** | `lighthouse-ai connect ` ([The CLI](/cli/#connecting-a-provider)) | Opens the Connect page for you to approve. `--credential-stdin` connects a token you already have, as you, exactly as if you had pasted it on the Connect page. `--reuse-local` offers the `gh`, `glab` or Datadog sign-in already on your machine, and sends it the same way only after you type `yes` | | **In code** | A source card in your deployment’s catalogue | Every connector the engine has. Your engineer, or Atlantic’s certified forward-deployed engineers, add the card and point it at a credential in your own secret store | > **What connecting in LightHouse does, and what your source card still does:** > > Connecting in LightHouse checks the credential, tracks its health and keeps it. Where your deployment keeps it in your own secrets store, a source card reads it by naming the connection (`credential_secret: `; see [Read a kept credential in your deployment](#read-a-kept-credential-in-your-deployment)). You still add the source card itself in code ([In code](/build/code/)). A credential held under your tenant’s key is not passed to your deployment: there, the source reads its own copy from your secret store. There is no separate one-click stack per connector. A source is a card in your catalogue, and its credential is a secret your stack already passes to the engine ([Clouds](/clouds/)). ## Access levels: read, or read and write A connection can read, or read and write. Your `client_admin` chooses the access level for each connection when they connect it, and every connector shows which level each of its connections has: - **`read`**, the default. LightHouse asks for the connector’s read-only scopes on every way of connecting. - **`read_write`**. LightHouse asks for the connector’s write scopes, where it has them. | Connector | `read` (the default) | `read_write` | | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GitHub | `contents:read`, `metadata:read`, `issues:read`, `pull_requests:read` | `contents:write`, `metadata:read`, `issues:read`, `pull_requests:write`, on a fine-grained token. The LightHouse GitHub App reads only, so its approval cannot ask for write | | GitLab | `read_api`, `read_user` | `api`, `read_user`, `write_repository`, on the approval or a token | | Google Drive | `https://www.googleapis.com/auth/drive.readonly` | `https://www.googleapis.com/auth/drive` | | Confluence, Jira | The integration account’s own permissions | Recorded as your administrator’s choice. Atlassian does not state an API token’s scopes, so the account’s own permissions decide what it can write | | Datadog | `monitors_read`, `incident_read`, `notebooks_read` | No write set is asked for. A token whose own scopes write is recorded as read and write when you choose it. The approval asks for read only | | Gmail | `https://www.googleapis.com/auth/gmail.readonly` | Not offered. Asking for it is refused with `422 invalid` | | Salesforce | `api` on your connected app, with a read-only permission set on the integration user | Recorded as your administrator’s choice. The `api` scope does not separate reading from writing: the integration user’s profile decides | | HubSpot | `crm.objects.companies.read`, `crm.objects.contacts.read`, `crm.objects.deals.read`, `tickets` | The matching `.write` scopes | | ServiceNow, monday.com, Zendesk, Notion, Dynamics 365 | The integration user’s, token’s or app’s own permissions (ServiceNow: `snc_read_only`) | Recorded as your administrator’s choice. The provider does not state the credential’s permissions | | Oracle Database, NetSuite, Oracle Fusion Cloud Applications | A read-only user or role (NetSuite: `rest_webservices`) | Not offered: these read only | Each connector’s page lists the exact scopes. Datadog’s outbound telemetry (`metrics_write`, `events_write`) is a separate switch, not an access level; see [Datadog](/connect/datadog/#outbound-lighthouses-telemetry-in-your-datadog). ### See the access level on every connector - **On the connect form**: under **What agents may do with it**, choose **Read only** (the default) or **Read and write**. Each option lists the scopes it asks for. - **On each connection’s card**: a **Read only** or **Can write** badge beside its health, and a note naming the scopes that write. ### Writing goes through approved cards With read and write, agents write to the source only through cards a person approved in LightHouse, as with every change an agent makes outside your deployment ([Approvals](/concepts/approvals/)). ### How LightHouse checks what a credential can do LightHouse asks the provider. Providers expose different information, so the check differs by provider: | Provider | What it is asked | What is recorded | | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | GitHub (a classic token), GitLab, Datadog (an OAuth token) | The scopes the credential carries | Any scope that means write is a write scope | | Google Drive, Gmail | LightHouse asks Google for a token with the scopes of the level you chose | Every scope Google says the token carries must be in that set, or the key is refused (`422 provider_refused`). Drive’s write scope is `.../auth/drive`, which does not contain the word “write”, so LightHouse checks against a fixed set rather than looking for write-like names | | GitHub (a fine-grained token), Datadog (API and application keys) | Who the credential belongs to. The provider does not state its scopes | The level you chose, with `scopes_stated: false`. The health detail says the provider did not state the scopes | | Confluence, Jira | Which account the credential belongs to, and whether that account administers the site | The level you chose, with `scopes_stated: false`. A site administrator’s token is refused, whatever the level: it can read everything regardless of what a space or project allows | | Salesforce, HubSpot, NetSuite, Oracle Database | Your deployment asks: Salesforce states the connected app’s scopes, HubSpot the private app’s scopes, NetSuite the token’s scope, and the database the user’s session privileges | The scopes stated. HubSpot’s `.write` scopes and any database privilege beyond reading count as writing; Salesforce’s `api` scope does not, because the profile decides | | ServiceNow, monday.com, Zendesk, Notion, Dynamics 365, Oracle Fusion Cloud Applications | Your deployment checks that the credential signs in and reads one record | The level you chose, with `scopes_stated: false`: these providers do not state a credential’s permissions | | Fireblocks, Dfns, Kraken, Binance, Stripe, Revolut Business | Your deployment asks the provider what the key may do | Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused as `write_capable`, with the permission named. Read and write is refused for every finance connector | | Coinbase Prime, Kyriba | The provider does not state the key’s permissions, so you confirm it only reads (**View-only confirmed**) | Read-only. Until you say yes, nothing is read and the card reports `unverified` | | Xero, QuickBooks Online, bank statements | Xero states the app’s scopes, and a scope that writes is named; Intuit’s accounting scope is not split, so the connector only reads; a statement drop cannot move money | Read-only | | Amadeus, FlightAware, Cirium, OAG, SITA, Sabre, ECCAIRS 2, Q-Pulse, Intelex, xAPI | Your deployment checks the credential reads, and refuses one whose scope writes | Read-only. A token whose scope writes is reported as `scope_missing`, naming the scopes. Read and write is refused | These checks run where LightHouse sees the credential: an approval, or a token held under your tenant’s key. A token sealed in your browser or by the CLI never reaches LightHouse, so your deployment checks it instead, from your own account, once it has kept it (`connector.check`). The level you chose is recorded, and the scopes the provider states replace the recorded ones when the check answers. If a connection chosen as `read` turns out to carry a write scope, the check marks it `failing` with the same warning as below. See [Check, disconnect and replace](#check-disconnect-and-replace). ### When the credential and your choice disagree Where LightHouse sees the credential and the provider states its scopes, LightHouse never records a level that differs from what the credential can do, and never silently changes your choice. It refuses instead: | Refusal | When | The answer’s `offer` | | ----------------------------- | ---------------------------------------------------------------- | ------------------------------------------------- | | `422 credential_can_write` | You chose `read`, and the provider says the credential can write | `{"access": "read_write", "write_scopes": [...]}` | | `422 credential_cannot_write` | You chose `read_write`, and the credential can only read | `{"access": "read"}` | On the Connect page, the refusal shows a button that sends the same credential again with the offered level: **Record it as read and write**, or **Connect it as read only**. Or make a new token with the scopes you meant. A token can gain scopes after it is connected. When a health check (`POST /api/v1/connections/{cid}/health`) finds that a `read` connection’s token now carries a write scope, it marks the connection `failing` and says so: *“This credential can now write (…), but it was connected as read. Reconnect it as read and write, or narrow the token.”* To change a connection’s level, connect again with the same target and the new level. The new connection replaces the old one. ### The access level in the API, MCP and audit log - **In the API and MCP**: each connection carries `access`, `can_write`, `write_scopes`, `scopes_stated` and `access_note`, in `GET /api/v1/connectors` and in the MCP tools [`connectors`](/mcp/tools/connectors/) and [`connection`](/mcp/tools/connection/). Each catalogue card carries `access_levels`, `write_scopes` and `write_note`. - **In the audit log**: the `connector_connected` entry records `access`, `write_scopes` and `scopes_stated`, and, where the connection replaced another, `previous_access` and `access_changed`. Never the credential. ## Where every credential is held A credential you connect in LightHouse is kept in your own secrets store, written there by your own deployment. LightHouse never holds it in a form it can read. Until your deployment can keep it, LightHouse holds it under your tenant’s key. Each connection’s card says which. | | In your own secrets store | Under your tenant’s key, until your deployment can keep it | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **When** | Your deployment can keep it: an engine with the command channel, a sealing key and a store, and `secret.put` switched on in LightHouse and in your deployment’s policy ([Turn it on](#turn-on-your-own-store)) | Everything else: an engine that does not advertise a sealing key, a deployment with no store or no sealing key, `secret.put` not switched on on both sides, and Datadog’s one-click approval, whose grant is not a credential your deployment keeps | | **Where** | AWS Secrets Manager, Azure Key Vault, Google Secret Manager, or a directory on your own servers, in your account, under `lighthouse/connectors//` | LightHouse’s database, encrypted under a KMS key in Atlantic’s account used for your tenant alone (AES-256-GCM envelope encryption) | | **Who can open it** | Your deployment | LightHouse, with your tenant’s key, to call the provider. Atlantic cannot read it without that key, and disabling the key breaks every connection at once | | **On the card** | *The credential: In your own store, kept by* your deployment, and a line such as *“In your own AWS Secrets Manager, kept by your deployment …”* saying where it was sealed | *The credential: Sealed with your own key*, and *“Held sealed under your key in AAL’s account until your deployment supports your own store.”* | Either way, LightHouse keeps a keyed fingerprint of the credential, its scopes and, where it saw the credential, its expiry. The credential is never shown again, in any answer or audit entry. If your tenant’s key is unavailable when a credential would be held under it, LightHouse keeps nothing and answers `503 secret_store_unavailable`. The Connectors page’s summary says where a new credential will go: *“A new credential goes to your own secrets store, sealed to your deployment’s key before it leaves your browser”*, or that every credential is held sealed under your key until your deployment supports your own store. - **You**: client_admin, in the browser or the CLI - **LightHouse**: your tenant - **Your deployment**: the command channel - **Your secret store**: in your account - **The source**: the provider's system Before 1. Your deployment to LightHouse: **Advertise the sealing key**. its public half, signed with the deployment's own key Connect 2. You: **Choose the access level**. read only (the default) or read and write 3. You: **Seal the credential**. in your browser or the CLI, to your deployment's key 4. You to LightHouse: **Send it sealed**. LightHouse cannot open it 5. LightHouse to Your deployment: **Relay it**. a signed secret.put, over the command channel 6. Your deployment to Your secret store: **Open and keep it**. checked against the connector's fields and your policy 7. Your deployment to LightHouse: **Stored**. only now is the connection made; the audit log records it Use 8. Your deployment to The source: **Read in place**. with the credential from your store; check, sync and index in your account 9. Your deployment to The source: **Write, with read and write only**. only through cards a person approved in LightHouse A credential you paste, or send from the CLI, is sealed on your machine to your deployment's own key, kept in your own secret store, and used where it is. With read only, the connector asks for read scopes; with read and write, agents write only through cards a person approved. ### Where the credential is sealed A credential bound for your own store is sealed to your deployment’s own key before LightHouse relays it. Where that happens depends on how you connect: | How you connect | Sealed by | `sealed_by` | Does LightHouse see the credential? | | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | --------------- | ----------------------------------- | | Paste an access token on the Connect page | Your browser, with WebCrypto | `browser` | No | | `lighthouse-ai connect --credential-stdin` | The CLI, on your machine | `cli` | No | | One-click approval, or a device code from `lighthouse-ai connect` | LightHouse, the moment the provider’s exchange hands it the token. It then drops the token | `lighthouse-ai` | For that instant only | | A token sent unsealed: from a browser whose WebCrypto has no X25519, or a request to the API with `credential` | LightHouse, after checking it at the provider | `lighthouse-ai` | For the check and the seal only | For `sealed_by: lighthouse` the card says so: *“LightHouse received it from the provider’s own exchange, sealed it to your deployment’s own key at once and dropped it: it held the credential for that instant and does not have it now.”* **How it is sealed.** Your deployment holds an X25519 sealing key whose private half never leaves your account. It advertises the public half to LightHouse over its command channel, signed with your deployment’s own Ed25519 key. LightHouse keeps the advertisement only when the signature verifies against a key your deployment registered, and checks it again every time it is used; a changed deployment key drops it. The credential is sealed with HPKE (RFC 9180, base mode: X25519, HKDF-SHA256, AES-256-GCM), bound to your tenant and deployment, the connector and the connection id, so a sealed credential opens nowhere else. **What you trust.** The Connect page checks the advertisement against the keys LightHouse says your deployment registered: the same trust you place in the page’s own JavaScript. The CLI can check it against your deployment’s public key as your own infrastructure printed it (`--deployment-key`, or `LIGHTHOUSE_DEPLOYMENT_KEY`), which detects a substituted sealing key before anything is sealed. See [The CLI](/cli/#connect-a-token-you-already-have). ### A connection exists once its credential is kept 1. You connect. LightHouse answers `202` and sends your deployment a signed `secret.put` carrying the sealed credential, its keyed fingerprint, the access level and the scopes, named by the connection id. 2. The card shows the connection as **Waiting for your deployment**: *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* 3. Your deployment opens the credential in your account, checks it is exactly the fields its connector takes, and writes it to your store. It answers `stored`, or `unchanged` where the same credential, level and scopes are already there. 4. The connection is written, and the audit log records `connector_connected` by your deployment. Only now is anything connected. 5. Your deployment checks the credential at the provider (`connector.check`), and the card shows its answer. If your deployment does not keep it, nothing is connected, the check and any deletion that would have followed are cancelled, and the card shows **Not kept** with the reason in words for a day: | What happened | The page says | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | Refused | *“Your deployment refused it: …. Nothing was kept.”*, with the reason below | | Failed in your store | *“Your store did not keep it (…). Nothing was kept.”*, with the store’s error code, such as `store_unavailable` | | No answer within 15 minutes | *“Your deployment did not answer within 15 minutes, so nothing was kept and the sealed credential has gone. Connect it again.”* | | Refusal | The page’s words | | ---------------- | ---------------------------------------------------------------------------- | | `sealed` | it did not open there: it was sealed for another place or changed on the way | | `sealing-key` | it was sealed to a key your deployment no longer holds | | `params` | it is not the shape this connector’s credential takes | | `bounds` | your deployment’s policy does not allow this connector or access level | | `type-disabled` | secret.put is not switched on in your deployment’s own policy | | `not-configured` | your deployment has no secrets store or sealing key configured | | `role` | your deployment’s policy does not let your role keep credentials | The Connect page waits for the answer. If none has come after three minutes, it says *“Your deployment has not answered yet; the connection shows on this page once it does.”* ### Check, disconnect and replace For a credential in your own store, LightHouse cannot read it, so each of these is a signed command to the deployment that holds it: - **Check it now** sends `connector.check`. LightHouse answers `202` with the command, and the card says *“Asked your deployment to check it. Its answer shows here when it comes.”* Your deployment runs the connector’s own sign-in probe from your account: | Answer | The card | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ok` | `healthy`. The scopes the provider states replace the recorded ones. Write scopes on a connection chosen as `read` mark it `failing` with a warning | | `auth_failed` | `failing`: the provider refused it (expired, revoked or wrong) | | `scope_missing` | `failing`: it signs in but lacks a scope this connection needs, carries a scope that writes on a read-only connector (the scopes are named), or, for Google, the delegation is not granted | | `write_capable` | `failing`: the key can withdraw, transfer, sign or trade, so it is refused and nothing is read. Make a view-only key at the provider, pin it to your deployment’s egress addresses, and connect it again | | `unverified` | `failing`: the provider does not state the key’s permissions and it was not confirmed view-only. Check that it only reads, then connect it again with **View-only confirmed** set to yes | | `absent` | `failing`: nothing is stored under this connection | | `unreachable` | Unchanged: the provider could not be reached, which is not counted as failing | Where `connector.check` is not switched on, **Check it now** is refused with `409 command_unavailable`. - **Disconnect** sends `connector.revoke` and marks the connection disconnected at once. Your deployment revokes the credential at the provider where the credential can revoke itself (a GitLab access token: `revoked`), and deletes it from your store either way. Elsewhere it answers `provider_manual`, and the card says where to revoke it, for example *“Atlassian: id.atlassian.com, Security, API tokens”*. Where `connector.revoke` is not switched on, the card says the credential is still in your store, where, and to delete it there and revoke it at the provider. - **Replace**: connecting again with the same target sends a new `secret.put`. Only once the new credential is kept does LightHouse send `secret.delete` for the old one. Replacing deletes and does not revoke, because the new credential may be the same token sealed again. LightHouse records an expiry only where it saw the credential. A token sealed in your browser or by the CLI has no expiry on its card; your deployment’s check reports `auth_failed` once it lapses. ### Turn on your own store 1. **Run the engine with its command channel**, and give the command channel a sealing key and a store: - `AAL_SEALING_KEY` or `AAL_SEALING_KEY_FILE`. Make one with `python -m aal_engine.sealing new-key --out `, which writes it with mode 0600 and never overwrites. - `AAL_CONNECTOR_SECRETS=:`: `aws:`, `azure:https://.vault.azure.net`, `gcp:` or `file:`. Optionally `AAL_CONNECTOR_SECRETS_PREFIX` (default `lighthouse/connectors`) and, on AWS, `AAL_CONNECTOR_SECRETS_KMS_KEY` to encrypt with your own key. Azure Key Vault and Google Secret Manager write `-` for each `/` in the name. Your deployment advertises its sealing key only when both load. 2. **Allow the four commands in your deployment’s policy:** ```yaml commands: secret.put: {enabled: true, roles: [client_admin], access_levels: [read]} secret.delete: {enabled: true, roles: [client_admin]} connector.check: {enabled: true, roles: [handler, client_admin]} connector.revoke: {enabled: true, roles: [client_admin]} ``` `connectors` narrows which connectors’ credentials may be kept (empty means all). A put is read-only unless you also list `read_write` in `access_levels`. 3. **Switch the same four on in LightHouse**, under **Setup and admin → Commands** (`client_admin`). `GET /api/v1/connectors/sealing` says, for each deployment, whether it is ready and, if not, why: no sealing key advertised yet, or `secret.put` not switched on in LightHouse or in your policy. The files **Get my stack** generates include the command channel, the store and a slot for the sealing key; a person fills the sealing key in your own account after the apply. The command channel’s identity needs to create, read and delete secrets under the prefix only, and to reach the providers it checks. Your scheduled jobs need only to read under the prefix. **Rotating the sealing key.** Put a new key first in `AAL_SEALING_KEY` and keep the old one second, then restart the command channel: it advertises the new key, and the old one only opens. A sealed credential exists only inside a command, which lives at most 15 minutes, so remove the old key after 15 minutes. Nothing stored needs sealing again. ### Read a kept credential in your deployment A source card reads a credential kept in your store by naming its connection, in place of an environment variable: ```yaml source: kind: jira projects: [ENG] label: internal credential_secret: cx-000000000001 # the connection's id (`id` in the API) ``` Your scheduled job reads the record from your store and gives the source its fields. A Google Drive or Gmail source gets a one-hour token minted from the stored key file, never the key itself. A source configured for a different site, instance or Datadog region from the one the credential was sealed with is refused. ### In the API - `GET /api/v1/connectors/sealing` (`client_admin`, a person’s session) returns `tenant`, `ready`, `fingerprint_key`, `connectors`, `info`, `about` and `deployments`: for each, `deployment`, `ready`, `why`, `sealing` (the verified sealing key, or `null`), `deployment_keys` (the Ed25519 keys your deployment registered) and `commands` (whether each of the four is switched on on both sides). It never carries a credential. - `POST /api/v1/connectors/{connector}/token` takes a sealed credential: `{"sealed", "fingerprint", "connection", "target"?, "access"?, "deployment"?, "sealed_by"?}`, where `connection` is the id it was sealed for (`cx-` and 12 lower-case letters or digits) and `sealed_by` is `browser` or `cli`. It answers `202` with the waiting connection: `pending: true`, `state`, `reason`, `sealed_by`, `deployment`, `secret_store`, `custody`, `command`, `check_command` and `replaced`. Refusals: `409 sealing_unavailable` (the deployment cannot keep it), `409 sealing_key_changed` (seal it again to the current key), `409 conflict` (the connection id is taken) and `422 invalid`, naming the attribute. `{"credential", ...}` is still accepted: `202` where your deployment keeps it, `201` under your tenant’s key otherwise. - An approval’s callback and a device-code approval answer `202` the same way where your deployment keeps the credential. - Each connection carries `sealed_by`, `deployment` and `custody`. `GET /api/v1/connectors` adds `pending` (connections waiting for, or refused by, your deployment) and `own_store`. - `POST /api/v1/connections/{cid}/health` answers `202` with `command` for a credential in your own store. `DELETE /api/v1/connections/{cid}` answers `revocation` (the command, or `null`) and `note`. - The audit log records `connector_put_requested` when the credential is sent and `connector_connected`, by your deployment, when it is kept. The sealed credential never appears in a read or an audit entry, and is replaced by `[redacted]` in the stored command once the command is final. ### For a source set up in code A source card can also read its credential from an environment variable that your platform fills from your secret store. On AWS, the stack takes a Secrets Manager or Systems Manager reference for each one (`app_secrets` on the services, `secrets` on scheduled jobs), or the engine resolves `AAL_SECRET_ARNS` itself at start and stops if a reference cannot be read. On your own servers, secrets are files beside the Compose stack. See [Where everything lives](/data-sovereignty/where-everything-lives/). ## Connectors Every connector, grouped by family: vendors with several products first (Google, Microsoft, Atlassian, Amazon Web Services, Salesforce, Oracle, Amadeus, Adobe, SAP), then the rest by what they hold. Search by name or by what you need read: *email*, *tickets*, *warehouse*, *crypto*, *baggage*, *safety* each find what holds it. The filters and the search are kept in the page’s address, so a link shows the same view. LightHouse’s **Connectors** page has the same families, filters and search. Each card says whether it is **Available**, **Coming** or **Needs onboarding**: - **Available**: connect it in LightHouse or in code today. Salesforce, HubSpot, ServiceNow, monday.com, Zendesk, Notion, Dynamics 365, Oracle Database, NetSuite and Oracle Fusion Cloud Applications are read by the engine, as are the [digital assets](/connect/digital-assets/), [banking and payments](/connect/banking-and-payments/), [accounting and treasury](/connect/accounting-and-treasury/), [flight data](/connect/flight-data/) and [aviation safety](/connect/aviation-safety/) connectors. Until one of your deployments reports reading one, its card in LightHouse asks for an engine that reads it ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)). - **Coming**: listed so you can see it is planned and ask for it. No date is promised, and LightHouse refuses a request to connect it with `409 connector_coming`. - **Needs onboarding**: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. Every connector reads only. Those that hold money (finance connectors refuse read and write outright) refuse a key that can withdraw, transfer, sign, trade or approve payments; airline systems keep passenger personal data in your deployment, with travel document numbers and health SSRs left out by default; safety systems leave reporter identities out by default. Each card says which applies. ### Google - Google DriveDocuments\[Available] Available Documents and folders you name, for knowledge bases. [Read the Google Drive guide](/connect/google-drive/) - GmailMail\[Available] Available One labelled mailbox, for agents that answer correspondence. [Read the Gmail guide](/connect/gmail/) - ApigeeAPI gateway\[Coming] Coming API proxies, products and analytics, for platform agents. **Sign-in:** A Google service account with the Apigee read-only role. ### Microsoft - SharePoint and OneDriveDocuments\[Available] Available Sites, document libraries and OneDrives you name, for knowledge bases. [Read the SharePoint and OneDrive guide](/connect/sharepoint/) - Azure Blob StorageStorage\[Coming] Coming Containers and prefixes you name, read in place. - Dynamics 365CRM\[Available] Available with engine 0.46.0 or later Accounts, opportunities and cases from Dataverse, for commercial and service agents. **Sign-in:** Your own Entra app by certificate, as for SharePoint, made an application user of the environment with a read-only security role. [Read the Dynamics 365 guide](/connect/dynamics/) - Microsoft TeamsChat\[Available] Available Channel messages and their replies in teams you name, for knowledge bases. [Read the Microsoft Teams guide](/connect/teams/) ### Atlassian - ConfluenceDocuments\[Available] Available Spaces and pages, for knowledge bases. [Read the Confluence guide](/connect/confluence/) - JiraWork management\[Available] Available Projects, issues and comments, for knowledge bases and for triage agents. [Read the Jira guide](/connect/jira/) ### Amazon Web Services - Amazon S3Storage\[Available] Available Buckets and prefixes you name, read in place. [Read the Amazon S3 guide](/connect/s3/) ### Salesforce - SalesforceCRM\[Available] Available with engine 0.46.0 or later Accounts, opportunities, cases and published Knowledge articles, for commercial and service agents. **Sign-in:** Your own connected app by certificate (the OAuth 2.0 JWT bearer flow): no client secret and no password. Atlantic's connected app comes later. [Read the Salesforce guide](/connect/salesforce/) ### Oracle - Oracle DatabaseData\[Available] Available with engine 0.46.0 or later Tables and views you name, read in place through your own read-only user. **Sign-in:** A database user holding SELECT on the named objects only, reached from your deployment (python-oracledb, thin mode); the database states the user's privileges and any that writes is flagged. [Read the Oracle Database guide](/connect/oracle-db/) - NetSuiteERP\[Available] Available with engine 0.46.0 or later Customers, transactions, items and support cases by SuiteQL, for finance and service agents. **Sign-in:** OAuth 2.0 client credentials (machine to machine) with the certificate you uploaded to NetSuite; never a password or a token-based-authentication pair. [Read the NetSuite guide](/connect/netsuite/) - Oracle Fusion Cloud ApplicationsERP\[Available] Available with engine 0.46.0 or later REST resources you name in ERP, HCM and SCM, for finance, people and supply agents. **Sign-in:** A JWT assertion signed with your certificate for a read-only integration user, on your one pod; Fusion states no roles to the user. [Read the Oracle Fusion Cloud Applications guide](/connect/oracle-fusion/) - OCI Object StorageStorage\[Coming] Coming Buckets and prefixes you name in Oracle Cloud Infrastructure, read in place. **Sign-in:** A dynamic group or an API signing key with read on the bucket only. - Oracle Service CloudService desk\[Coming] Coming Incidents and knowledge answers from Oracle B2C Service. **Sign-in:** A read-only integration account on your site. ### Amadeus - AmadeusSchedules and flight status\[Available] Available with engine 0.46.0 or later Flight status for the flights you name, airline and airport reference data, and flight orders, read in your deployment. **Sign-in:** The API key and secret your Amadeus account manager issued (client credentials), on the test or production host you choose. Self-service keys closed on 17 July 2026; enterprise keys reach the same endpoints. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the Amadeus guide](/connect/flight-data/#amadeus) - Amadeus Altéa ReservationsReservations\[Needs onboarding] Needs onboarding PNRs read in place: itinerary, status, remarks and service requests. **Sign-in:** Amadeus's partner APIs: our certified forward-deployed engineers map the source from your licensed reference, then it reads only. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Amadeus Altéa Departure ControlDeparture control\[Needs onboarding] Needs onboarding Flight and passenger lists: load, acceptance and boarding status. **Sign-in:** Amadeus's partner APIs: our certified forward-deployed engineers map the source from your licensed reference, then it reads only. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Amadeus Altéa Inventory and SchedulesSchedules and flight status\[Needs onboarding] Needs onboarding Your schedule and inventory by flight and date. **Sign-in:** Amadeus's partner APIs: our certified forward-deployed engineers map the source from your licensed reference, then it reads only. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Amadeus NDC ordersReservations\[Needs onboarding] Needs onboarding NDC orders by id and by change. **Sign-in:** Amadeus's partner APIs: our certified forward-deployed engineers map the source from your licensed reference, then it reads only. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. ### Adobe - Adobe AnalyticsAnalytics\[Coming] Coming Report suites and their metrics, for analytics agents. **Sign-in:** An Adobe Developer Console project by OAuth server-to-server, read-only. - Adobe TargetExperimentation\[Coming] Coming Activities and their results, for experimentation agents. **Sign-in:** An Adobe Developer Console project by OAuth server-to-server, read-only. ### SAP - SAP ConcurExpenses\[Coming] Coming Expense reports and their status, for finance agents. **Sign-in:** A company-level app by your approval, with read scopes only. - SAP S/4HANAERP\[Available] Available with engine 0.47.1 or later Sales and purchase orders, supplier invoices, material documents, products, journal entries, cost centres and organisations, for finance and supply agents. **Sign-in:** A communication arrangement in your S/4HANA with read-only OData services: an OAuth 2.0 client (client credentials) or a communication user (HTTP Basic), on your one API host. Only that host, and the token host where there is one, are contacted. Read-only. Business partners who are people, employees, payroll postings, bank details and tax ids are left out; nothing is ever created, changed or approved. Left out by default: Individuals' records: business partners who are people, employees, contacts, addresses; Payroll and employee cost postings; Bank details and tax ids. [Read the SAP S/4HANA guide](/connect/erp-and-hr/#sap-s4hana) - SAP SuccessFactorsHR\[Available] Available with engine 0.47.1 or later Departments, locations, job codes, positions and job requisitions, for workforce planning and recruiting agents. Employee records and pay are not read. **Sign-in:** An OAuth 2.0 client (client credentials) registered in your SuccessFactors tenant, on your data centre's API host, with read on the organisation and recruiting objects only. SAML bearer is not supported. Read-only. Employee records, pay and benefits, health and diversity data and performance records are not read; nothing is ever created, changed or approved. Left out by default: Employee records: names, national ids, dates of birth, home addresses; Pay and benefits: compensation, payroll, bank details, tax ids; Health, disability and diversity data; Performance and disciplinary records. [Read the SAP SuccessFactors guide](/connect/erp-and-hr/#sap-successfactors) ### Workday - WorkdayHR\[Available] Available with engine 0.47.1 or later Supervisory and cost-centre organisations, job profiles, locations, job requisitions and the reports you name, for workforce planning agents. Workers and pay are not read. **Sign-in:** An API Client for Integrations with a refresh token, on your tenant's host, limited to the organisation and recruiting functional areas and the reports you share with it. Report columns that name personal data are dropped, counted. Read-only. Employee records, pay and benefits, health and diversity data and performance records are not read; nothing is ever created, changed or approved. Left out by default: Employee records: names, national ids, dates of birth, home addresses; Pay and benefits: compensation, payroll, bank details, tax ids; Health, disability and diversity data; Performance and disciplinary records. [Read the Workday guide](/connect/erp-and-hr/#workday) ### Code - GitHubCode\[Available] Available Issues, pull requests, their comments and the Markdown documents in named repositories, for knowledge bases and for coding and review agents. [Read the GitHub guide](/connect/github/) - GitLabCode\[Available] Available Markdown files, issues, merge requests, wikis and pipeline results from named projects, on GitLab.com or your own instance. [Read the GitLab guide](/connect/gitlab/) - SnykCode quality and security\[Coming] Coming Projects and their issues, for coding and review agents. **Sign-in:** A service account token with a read-only role. - CodeSceneCode quality and security\[Coming] Coming Code health and hotspots, for coding and review agents. **Sign-in:** A read-only API token. ### CRM - HubSpotCRM\[Available] Available with engine 0.46.0 or later Companies, contacts, deals and tickets, for commercial and service agents. HubSpot publishes no knowledge-base API, so articles are not read. **Sign-in:** A private app's access token, with HubSpot's read scopes; HubSpot states the token's scopes, and your deployment checks them. [Read the HubSpot guide](/connect/hubspot/) ### Service desk - ServiceNowService desk\[Available] Available with engine 0.46.0 or later Incidents, changes, CMDB configuration items and published Knowledge articles, for operations agents. **Sign-in:** An OAuth client by the client-credentials grant, or a read-only integration user (snc_read_only), on your one instance. [Read the ServiceNow guide](/connect/servicenow/) - ZendeskService desk\[Available] Available with engine 0.46.0 or later Tickets with their comments, and Help Centre articles, for service agents. **Sign-in:** An agent's email address and an API token, on your one subdomain; Zendesk does not state a token's scope, so the agent's role decides. [Read the Zendesk guide](/connect/zendesk/) ### Work management - monday.comWork management\[Available] Available with engine 0.46.0 or later Items, column values and updates on the boards you name, for delivery agents. **Sign-in:** An API token, ideally an integration account's added only to the boards named; monday.com does not state a token's permissions. [Read the monday.com guide](/connect/monday/) - NotionWork management\[Available] Available with engine 0.46.0 or later Pages and database rows shared with your integration, for knowledge bases. **Sign-in:** An internal integration's secret. Only pages and databases someone shares with the integration are read; Notion does not state its capabilities. [Read the Notion guide](/connect/notion/) ### Chat - SlackChat\[Available] Available Public channels the LightHouse app is added to, with their threads, for knowledge bases. [Read the Slack guide](/connect/slack/) ### Observability - DatadogObservability\[Available] Available Monitors, incidents and postmortem notebooks, for operations agents. [Read the Datadog guide](/connect/datadog/) - SplunkObservability\[Coming] Coming Saved searches and their results, and notable events, for operations agents. **Sign-in:** A token for a role that may search the named indexes only. - DynatraceObservability\[Coming] Coming Problems, entities and metrics, for operations agents. **Sign-in:** An access token with read scopes only. - PagerDutyObservability\[Coming] Coming Incidents, services and on-call schedules, for operations agents. **Sign-in:** A read-only REST API key. ### Data - PostgreSQLData\[Coming] Coming Tables and views you name, read in place through your own reader. [Read the PostgreSQL guide](/connect/postgres/) - SnowflakeData\[Coming] Coming Tables and views you name, read in place. [Read the Snowflake guide](/connect/snowflake/) - DatabricksData\[Coming] Coming Tables and views you name, read in place. **Sign-in:** A service principal with SELECT on the named tables only. ### Files and feeds - File uploadFiles and feeds\[Available] Available Documents you upload yourself, for a knowledge base with no system behind it. [Read the File upload guide](/connect/upload/) - RSS and Atom feedsFiles and feeds\[Available] Configured in your deployment Feeds you name: a status page, a regulator's bulletin, a supplier's notices. ### Digital assets - FireblocksCustody\[Available] Available with engine 0.46.0 or later Vault accounts, asset balances and transactions, for treasury and reconciliation agents. **Sign-in:** An API user with the Viewer role, its requests signed with your own key in your deployment. Fireblocks does not tell a key its own role: an administrator's key is refused, and you confirm the rest is a Viewer. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Fireblocks guide](/connect/digital-assets/#fireblocks) - DfnsCustody\[Available] Available with engine 0.46.0 or later Wallets, balances and transfers, for treasury and reconciliation agents. **Sign-in:** A service account with a read-only role (Wallets:Read, Wallets:Transfers:Read). Dfns states its permissions, and one that can create transfers or transactions, sign or export keys is refused, named. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Dfns guide](/connect/digital-assets/#dfns) - Coinbase PrimeTrading venue\[Available] Available with engine 0.46.0 or later Portfolios, balances, orders, fills and transactions, for reconciliation and reporting. **Sign-in:** An API key with the Read permission only. Prime does not state a key's permissions, so you confirm it is read-only. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Coinbase Prime guide](/connect/digital-assets/#coinbase-prime) - KrakenTrading venue\[Available] Available with engine 0.46.0 or later Balances, ledger entries and trade history, for reconciliation and reporting. **Sign-in:** An API key with Query Funds, Query Ledger Entries and Query Closed Orders & Trades only, and an IP allowlist. Kraken states the key's permissions; one that can withdraw or trade is refused, named. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Kraken guide](/connect/digital-assets/#kraken) - BinanceTrading venue\[Available] Available with engine 0.46.0 or later Spot and margin balances, trades, deposits and withdrawals, for reconciliation and reporting. **Sign-in:** An API key with Enable Reading only (Ed25519 recommended), restricted to your deployment's addresses. Binance states the key's restrictions; one with withdrawals, transfers or trading enabled is refused, named. Futures are not read: Binance requires a trading permission for them. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Binance guide](/connect/digital-assets/#binance) - BitGoCustody\[Coming] Coming Wallets, balances and transfers, read for reconciliation. **Sign-in:** A long-lived access token with view-only permission and no spending limit. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - CopperCustody\[Coming] Coming Portfolios, balances and movements, read for reconciliation. **Sign-in:** An API key with read-only permission. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - ![](/_astro/okx.BwWhi1Ni.png)OKXTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key with the Read permission only. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - BybitTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** A read-only API key. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - BitstampTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key with read permissions only. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - GeminiTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key with the Auditor role. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - DeribitTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key whose scopes only read (account, trade and wallet read). Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - BullishTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key with read-only permissions. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - Crypto.com ExchangeTrading venue\[Coming] Coming Balances, orders, fills and transfers, read for reconciliation and reporting. **Sign-in:** An API key with neither trading nor withdrawal enabled. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. ### Banking and payments - Bank statementsBank\[Available] Available with engine 0.46.0 or later camt.053, camt.052, MT940 and MT950 statements from any bank, and MT535 statements of holdings from any custodian, State Street included, read from your SFTP drop. **Sign-in:** An SFTP drop your bank or custodian already delivers to: a key for the drop account, with the server's host key pinned. A drop in a bucket is read by your deployment's own role, set up by your engineer. Read-only by nature: a statement file cannot move money, trade, instruct or approve. [Read the Bank statements guide](/connect/banking-and-payments/#bank-statements) - StripePayments\[Available] Available with engine 0.46.0 or later Your balance and every balance transaction, for finance and support agents. **Sign-in:** A restricted key (rk\_) with Read on Balance only, restricted to your deployment's addresses. A secret key (sk\_) is refused: it can move money. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Stripe guide](/connect/banking-and-payments/#stripe) - Standard CharteredBank\[Needs onboarding] Needs onboarding Balances and statements from your Standard Chartered accounts. **Sign-in:** The bank's API by mutual TLS, set up with the bank. Meanwhile, Bank statements reads the camt.053 and MT940 files it already delivers. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Corpay Cross-BorderPayments\[Needs onboarding] Needs onboarding Balances, contracts and payment status, read for treasury. **Sign-in:** Corpay's partner API, set up with Corpay. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Wise BusinessPayments\[Coming] Coming Balances and statements, read for reconciliation. **Sign-in:** A read-only API token. Meanwhile, Wise's camt.053 and MT940 exports work through Bank statements. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - CybersourcePayments\[Coming] Coming Transactions and settlement reports, read for finance agents. **Sign-in:** A REST API key with reporting access only. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. - PayPalPayments\[Coming] Coming Transactions and balances, read for finance agents. **Sign-in:** A REST app limited to the transaction search and balances features. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. ### Revolut - Revolut BusinessBank\[Available] Available with engine 0.46.0 or later Accounts, balances, transactions, counterparties, expenses, FX rates and cards (never card numbers), for cash and reconciliation agents. **Sign-in:** Your own Business API certificate, consented with the READ scope only. Where Revolut states the consent's scope, WRITE, PAY and READ_SENSITIVE_CARD_DATA are refused, named. Read-only: a consent with WRITE, PAY or sensitive card data is refused. [Read the Revolut Business guide](/connect/banking-and-payments/#revolut) ### Xero - XeroAccounting\[Available] Available with engine 0.46.0 or later Organisations, chart of accounts, contacts, invoices and bills, bank transactions, payments, journals and reports, for finance agents. **Sign-in:** Your own Xero app with read scopes only, by its consent's refresh token (rotated and written back to your own store at once) or as a custom connection. Read-only. A granted scope that writes is named by the check, and nothing is ever written. [Read the Xero guide](/connect/accounting-and-treasury/#xero) ### Intuit - QuickBooks OnlineAccounting\[Available] Available with engine 0.46.0 or later Company, accounts, customers, vendors, invoices, bills, payments, journal entries and reports, for finance agents. **Sign-in:** Your own Intuit app and its consent. Intuit's accounting scope is not split into read and write; this connector only reads. Read-only. Nothing is ever written. [Read the QuickBooks Online guide](/connect/accounting-and-treasury/#quickbooks) ### Kyriba - KyribaTreasury\[Available] Available with engine 0.46.0 or later Bank accounts, balances, cash positions and forecasts, cash flows, payment status and third parties, for treasury agents. **Sign-in:** An API client by client credentials, with read permissions only (no payment initiation, transfer or approval). Kyriba does not state an API client's permissions, so you confirm it. Read-only. A key that can withdraw, transfer, sign, trade or approve payments is refused. [Read the Kyriba guide](/connect/accounting-and-treasury/#kyriba) ### Aviation - FlightAware AeroAPISchedules and flight status\[Available] Available with engine 0.46.0 or later Your operator's and airports' flights: schedule, gates, delays, diversions and cancellations, for operations agents. **Sign-in:** An AeroAPI key. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the FlightAware AeroAPI guide](/connect/flight-data/#flightaware) - Cirium FlightStatsSchedules and flight status\[Available] Available with engine 0.46.0 or later Flight status by airport and by flight, for operations and disruption agents. **Sign-in:** An application id and key. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the Cirium FlightStats guide](/connect/flight-data/#cirium) - OAG Flight InfoSchedules and flight status\[Available] Available with engine 0.46.0 or later Flight instances by departure airport and date, for operations and disruption agents. **Sign-in:** An OAG subscription key. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the OAG Flight Info guide](/connect/flight-data/#oag) - SITA Flight StatusSchedules and flight status\[Available] Available with engine 0.46.0 or later Flight status at your airports, kept current from SITA's change feed, for operations agents. **Sign-in:** An API key from developer.aero, and OAuth client credentials where SITA issued them. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the SITA Flight Status guide](/connect/flight-data/#sita-flights) - SITA BagJourneyBaggage\[Available] Available with engine 0.46.0 or later Bags per flight with their loading status, read in your deployment, for customer and ground agents. **Sign-in:** The BagJourney API key from developer.aero. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the SITA BagJourney guide](/connect/flight-data/#sita-bags) - ![](/_astro/sabre.BwCnXmzW.png)SabreReservations\[Available] Available with engine 0.46.0 or later Bookings by confirmation id, read in your deployment, travel documents left out. **Sign-in:** Sabre's client credentials: the EPR (V1:user:group:domain) and its password, on the certification or production host you choose. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). [Read the Sabre guide](/connect/flight-data/#sabre) - SITA WorldTracerBaggage\[Needs onboarding] Needs onboarding Delayed, damaged and pilfered bag files and their tracing history, for customer agents. **Sign-in:** SITA's API under your airline's agreement, mapped by our certified forward-deployed engineers. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - ![](/_astro/sabre.BwCnXmzW.png)Sabre airline-hostedReservations\[Needs onboarding] Needs onboarding Reservations and departure lists from SabreSonic and Digital Connect. **Sign-in:** Sabre's airline APIs under your agreement, mapped by our certified forward-deployed engineers. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - ![](/_astro/atpco.BxqA8xW2.png)ATPCOFares\[Coming] Coming Fares and rules, for pricing and revenue agents. **Sign-in:** ATPCO's data feeds under your own subscription. - TravelportTravel content\[Coming] Coming Schedules, availability and bookings, read in your deployment. **Sign-in:** Travelport's APIs by client credentials. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. - AMOSMaintenance\[Needs onboarding] Needs onboarding Work orders, task cards, defects and component history, for maintenance and CAMO agents. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Ramco AviationMaintenance\[Needs onboarding] Needs onboarding Work orders, task cards, defects and component history, for maintenance and CAMO agents. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - TRAXMaintenance\[Needs onboarding] Needs onboarding Work orders, task cards, defects and component history, for maintenance and CAMO agents. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - PlusgradeAncillaries and upgrades\[Needs onboarding] Needs onboarding Upgrade bids, their status and outcomes, and revenue reporting. **Sign-in:** Plusgrade's partner API, set up with Plusgrade. Read-only. Passenger personal data stays in your deployment; travel document numbers, dates of birth and health SSRs are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. ### Aviation safety and compliance - ECCAIRS 2Occurrence reporting\[Available] Available with engine 0.46.0 or later Your organisation's occurrence reports from EASA's E2, for safety agents. **Sign-in:** The E2 API client id and secret EASA issued (client credentials, as EASA's 2026 change requires); EASA allow-lists your deployment's address. Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the ECCAIRS 2 guide](/connect/aviation-safety/#eccairs) - Ideagen Q-PulseQuality and audit\[Available] Available with engine 0.46.0 or later Occurrences with their data fields, for quality and safety agents. **Sign-in:** An integration user of Q-Pulse's web services, over https, on the database you name. Q-Pulse signs in by a SOAP envelope, so your deployment checks it at the first sync. Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the Ideagen Q-Pulse guide](/connect/aviation-safety/#qpulse) - IntelexQuality and audit\[Available] Available with engine 0.46.0 or later Incidents, audits, findings and actions from the objects you name, for quality agents. **Sign-in:** An integration user's API key, on your Intelex address. Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the Intelex guide](/connect/aviation-safety/#intelex) - ![](/_astro/adl.XRNMaUb9.png)xAPI learning recordsTraining records\[Available] Available with engine 0.46.0 or later Training statements from your Learning Record Store, for training agents. **Sign-in:** A read-only key and secret for any Learning Record Store (xAPI 1.0.3 or 2.0). Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the xAPI learning records guide](/connect/aviation-safety/#xapi) - Flight data monitoring exportsFlight data monitoring\[Available] Available with engine 0.46.0 or later Event and exceedance exports from your FDM or FOQA tool, row by row, from a bucket prefix or an SFTP drop. **Sign-in:** No credential: your deployment reads the export location your engineer names, as its own identity or a role. Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the Flight data monitoring exports guide](/connect/aviation-safety/#fdm) - Training exportsTraining records\[Available] Available with engine 0.46.0 or later Training records exported by your LMS, row by row, from a bucket prefix or a drop folder. **Sign-in:** No credential: your deployment reads the export location your engineer names. Read-only. Reporters' names and everyone's contact details are left out by default. Left out by default: Travel document numbers; Dates of birth; Health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set); Reporters' names; Everyone's email addresses, phone numbers and contact details. [Read the Training exports guide](/connect/aviation-safety/#training-csv) - CentrikSafety management\[Needs onboarding] Needs onboarding Safety reports, occurrences, audits, findings, corrective actions, risks and documents. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Web ManualsDocuments and manuals\[Needs onboarding] Needs onboarding Operations manuals and their revisions. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Ideagen CorusonSafety management\[Needs onboarding] Needs onboarding Hazards, occurrences, investigations, risks and actions. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - ![](/_astro/aqd-dark.C36RZxaM.png)AQDQuality and audit\[Needs onboarding] Needs onboarding Occurrences, audits, findings and actions. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Vistair SafetyNetSafety management\[Needs onboarding] Needs onboarding Safety reports, investigations, risks and actions. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - Comply365Documents and manuals\[Needs onboarding] Needs onboarding Controlled documents, revisions and read-and-sign status. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - ![](/_astro/aims.CO8gQmry.png)AIMSCrew and operations\[Needs onboarding] Needs onboarding Rosters, pairings, duties and qualifications. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. - JeppesenCrew and operations\[Needs onboarding] Needs onboarding Crew pairing and rostering; FliteDeck chart and airport metadata. **Sign-in:** The system's API, mapped from the vendor's reference by our certified forward-deployed engineers; then it reads only. Read-only. Reporters' names and everyone's contact details are left out by default. Needs onboarding: the provider shares its API with partners; ask us and our certified forward-deployed engineers set it up. ### Customer experience - ContentfulCMS\[Coming] Coming Published entries and assets, for content and customer agents. **Sign-in:** A Content Delivery API token (published content only). - SegmentCustomer data\[Coming] Coming Sources, tracking plans and audiences, read for analytics agents. **Sign-in:** A Public API token with read-only access. - OptimizelyExperimentation\[Coming] Coming Experiments, flags and results, for experimentation agents. **Sign-in:** A read-only personal access token. - AmplitudeAnalytics\[Coming] Coming Charts, cohorts and event definitions, for analytics agents. **Sign-in:** An API key and secret key, read through the export and dashboard APIs. - IterableMessaging\[Coming] Coming Campaigns, templates and their metrics, for marketing agents. **Sign-in:** A server-side API key with read-only permissions. - AirshipMessaging\[Coming] Coming Push campaigns and their reports, for marketing agents. **Sign-in:** A bearer token with read-only access. - BrazeMessaging\[Coming] Coming Campaigns, Canvases and their analytics, for marketing agents. **Sign-in:** A REST API key with read permissions only. - MedalliaCustomer feedback\[Coming] Coming Survey responses and feedback themes, for customer agents. **Sign-in:** An API client by client credentials, read-only. - Genesys CloudContact centre\[Coming] Coming Interactions, queues and their statistics, for contact centre agents. **Sign-in:** An OAuth client by client credentials with a read-only role. - TwilioMessaging\[Coming] Coming Message and call records, for contact centre agents. **Sign-in:** A restricted API key with read permissions only. ### Integration and edge - AkamaiEdge and CDN\[Coming] Coming Properties, configurations and traffic reports, for operations agents. **Sign-in:** An API client with read-only access. - KongAPI gateway\[Coming] Coming Services, routes and plugins, for platform agents. **Sign-in:** A Konnect personal or system token with read-only roles. - Confluent Cloud and KafkaEvent streaming\[Coming] Coming Topics you name, read as they arrive, and their schemas. **Sign-in:** A service account with read on the named topics only. ### Identity - OktaIdentity\[Coming] Coming Groups, applications and sign-in events, for security agents. **Sign-in:** An OAuth service app with read-only scopes. - Ping IdentityIdentity\[Coming] Coming Groups, applications and audit events, for security agents. **Sign-in:** A worker application with a read-only role. - Auth0Identity\[Coming] Coming Applications, connections and logs, for security agents. **Sign-in:** A Management API client with read scopes only. SharePoint and OneDrive, Microsoft Teams and Slack each offer two ways in: approving Atlantic’s own app, and your own app’s credential. Until Atlantic’s Microsoft app or Slack app is registered, the approval on those cards says it needs Atlantic’s app, and your own app’s credential works meanwhile. ### What your deployment can read Each deployment tells LightHouse which sources it can read, in its command channel’s hello: the engine’s built-in sources and any your engineers registered. The Connectors page lists them under each deployment, and a card for a source that none of your deployments reads says so. A deployment whose engine does not report its sources is shown with the sources that engine version is known to read. A connector LightHouse does not yet offer refuses every connect request with `409 connector_coming`. A connector you build yourself registers under the engine’s `aal_engine.connectors` entry point, so your code stays in your repository. ## Sync schedules Each connection’s card shows how often its source syncs, when it last synced and when it next will, and a `client_admin` can change it there. Every source starts **off**: nothing syncs on a schedule until a person turns it on. | Mode | On the card | Runs | | --------------- | ----------------------- | ----------------------------------------------------------------------------------------- | | `off` | Off | Never on a schedule | | `every_15m` | Every 15 minutes | At :00, :15, :30 and :45, UTC | | `hourly` | Hourly | On the hour, UTC | | `working_hours` | Hourly in working hours | On the hour from 08:00 to 17:00, Monday to Friday, in the time zone you give (`tz`) | | `daily` | Daily | Once a day at the time you give (`at`, 24-hour `HH:MM`), in the time zone you give (`tz`) | `tz` is an IANA time zone, such as `Europe/Dublin`. A clock change moves the UTC time, not the time of day you chose. ### Set a schedule 1. Go to **Setup and admin → Connectors** and find the connection’s card. 2. Under **How often**, choose a mode. For **Daily**, set **At**; for **Daily** or **Hourly in working hours**, set **Time zone**. 3. Choose **Save schedule**. **Sync now** asks for one sync, whatever the schedule, `off` included. Your deployment runs it at its scheduler’s next tick, then indexes what it read. From a terminal, `lighthouse-ai kb ingest --source ` does the same: it is `lighthouse-ai connections sync` by another name, run as you. `--wait` follows the schedule record until your deployment reports the sync finished. See [The CLI](/cli/). A schedule and a sync reach your deployment as signed [handler commands](/concepts/handlers/), `connector.schedule` and `connector.sync`. Like every command type, each is off until your `client_admin` switches it on in LightHouse (**Setup and admin → Commands**) and your deployment’s own policy allows it. Your policy can also narrow the modes that may be chosen, for example to keep `every_15m` away from a source that rate-limits: ```yaml commands: connector.schedule: {enabled: true, roles: [handler, client_admin], modes: ["off", hourly, working_hours, daily]} connector.sync: {enabled: true, roles: [client_admin]} ``` A mode your policy leaves out is refused by your deployment with the reason `bounds`. ### What the card shows The schedule, the last sync and the next sync on the card are what your deployment reports, in `connector_schedule` records ([the telemetry contract](/concepts/telemetry-contract/)). A change you asked for shows as *Asked for: …* until your deployment reports it running, so the card never shows a request as done. Your deployment’s scheduler runs every 15 minutes, at an interval set once in its infrastructure as code. At each tick the engine decides which sources are due. Changing a schedule therefore never changes your infrastructure. Schedules need the engine configured for the contract revision that carries them ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)), with its command channel and its scheduler running. Both are in the files **Get my stack** generates. Until your deployment reports a source, the card says so and a schedule request is refused with `409 schedule_unavailable`. ### In the API - `PUT /api/v1/connections/{cid}/schedule` with `{"mode", "at"?, "tz"?, "card"?, "deployment"?, "reason"?}` sets the schedule. `client_admin`, a person’s session only. - `POST /api/v1/connections/{cid}/sync` with `{"card"?, "deployment"?, "reason"?}` asks for a sync now. `client_admin`, a person’s session only. Both answer `202` with the connection, the `command` created and `unchanged`. Asking again for the schedule already asked for, while that request stands, sends nothing and answers `unchanged: true`; so does asking for a sync while one is on its way. Both honour an `Idempotency-Key` header. Where your deployment reports more than one source for the connection, name it in `card` (`:`); LightHouse never guesses between two (`422 invalid`, `attribute: card`). A command type your tenant has not switched on is refused with `403 commands_disabled`. Each connection carries `next_sync_at` and a `schedule` object: `mode`, `words`, `at`, `tz`, `card`, `deployment`, `reported`, `last_sync_at`, `next_sync_at`, `last_status`, `sources`, `requested` (the change asked for, with its command’s status), `pending`, `sync` and `syncing`. The MCP tools [`connectors`](/mcp/tools/connectors/) and [`connection`](/mcp/tools/connection/) show the same, and only read: a schedule or a sync is set by a person in LightHouse. Each request is audited as `connector_schedule_set` or `connector_sync_requested`. ## Check a connection - **In LightHouse**: each connector’s card shows its state (`healthy`, `expiring` within 14 days, `failing`, `disconnected`), its access level, its sync schedule and, from your deployment’s telemetry over the last 7 days, the pulls, items written and failures. `POST /api/v1/connections/{cid}/health` re-checks the credential with the provider: LightHouse does it for a credential under your tenant’s key, and your deployment does it (`connector.check`, answered `202`) for one in your own store. - **In your deployment**: each pull’s result is the run’s note, `written N, unchanged N, quarantined N, removed N`, and a `connector` record to LightHouse. - **The knowledge base**: **Agents → Knowledge** shows documents by source, the last successful ingest and failures by class. ## Requesting a connector Ask Atlantic: [atlanticagenticlabs.com](https://atlanticagenticlabs.com/#contact). Source: https://docs.atlanticagenticlabs.com/connect/ --- # GitHub > Connect GitHub to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built.** The engine reads GitHub repositories (GitHub.com or GitHub Enterprise Server), and GitHub connects from LightHouse. ## Connect in LightHouse You need the `client_admin` role. Go to **Setup and admin → Connectors → GitHub** and enter what to read: the repositories (`owner/name`, comma-separated) and, optionally, the organisation. Under **What agents may do with it**, choose **Read only** (the default) or **Read and write**. See [Access levels](/connect/#access-levels-read-or-read-and-write). ### One-click approval 1. Choose **Approve in GitHub**. GitHub shows the LightHouse GitHub App’s install screen. 2. Choose the repositories, or the organisation, and install. 3. GitHub returns you to LightHouse, which checks the grant and shows the connection. The approval is valid for 15 minutes. If Atlantic’s GitHub App is not yet registered for your LightHouse, the card says so and offers the token route instead. The LightHouse GitHub App reads only: its permissions are fixed when it is registered. To connect GitHub as read and write, use an access token. Asking the approval for read and write is refused with `409 route_unavailable`. ### Access token 1. Create a fine-grained personal access token at [github.com/settings/personal-access-tokens/new](https://github.com/settings/personal-access-tokens/new), limited to the repositories you want, with only the permissions below for the access level you chose. 2. Paste it into the card and choose **Connect**. LightHouse calls `GET https://api.github.com/user` with it. GitHub states a classic token’s scopes, and LightHouse holds them against the level you chose: a token that can write, connected as read, is refused with `422 credential_can_write`, and one that can only read, connected as read and write, with `422 credential_cannot_write`. GitHub does not state a fine-grained token’s permissions, so LightHouse records the level you chose, and the health detail says so: *“GitHub answered. GitHub does not state a fine-grained token’s permissions, so LightHouse records the access level you chose for it.”* Those checks are LightHouse’s, for a token it sees. Where your deployment keeps credentials in your own store, the Connect page seals the token in your browser and LightHouse never sees it. Your deployment keeps it, then calls `GET https://api.github.com/user` from your account (`connector.check`). A write scope on a connection chosen as read then marks the connection `failing`, rather than being refused. See [Where every credential is held](/connect/#where-every-credential-is-held). ### From a terminal `lighthouse-ai connect github` opens LightHouse’s Connect page in your browser (`--no-browser` prints its address), where you approve as above. To connect a token you already have, pipe it in: ```bash gh auth token | lighthouse-ai connect github --credential-stdin --access read_write --target repos=example-org/handbook ``` The token is sent as if you had pasted it on the Connect page, as you, and the CLI seals it on your machine where your deployment keeps credentials in your own store. `lighthouse-ai connect github --reuse-local` offers the `gh` sign-in already on your machine and sends it the same way, after you type `yes` at a terminal. It never runs under `--yes`, `--no-input` or in a pipe. See [The CLI](/cli/#connecting-a-provider). ## Connect in code Add a source card to your deployment’s catalogue, and give the engine the token from your own secret store as `GITHUB_TOKEN`, or, for a connection kept in your own store, name it with `credential_secret: ` ([Read a kept credential](/connect/#read-a-kept-credential-in-your-deployment)): ```yaml - id: github-docs purpose: Read our service repositories' issues and docs into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: platform-lead@example.com budget_usd: 0 effect: internal source: kind: github repos: [example-org/payments-service, example-org/handbook] label: standard # a document class in your pack's label scheme doc_paths: [docs/] # optional: only Markdown under these paths requires: reads: [issues, pull requests and Markdown files in the two repositories] reason: the support agents answer from the service docs ``` | Setting | Default | Notes | | ---------------------------- | ------------------------ | -------------------------------------------------------------------------------------- | | `repos` | (required) | `owner/name`. An organisation is never read by default | | `base_url` | `https://api.github.com` | GitHub Enterprise Server: `https:///api/v3` | | `credential_env` | `GITHUB_TOKEN` | The environment variable holding the token. `""` reads public repositories without one | | `issues`, `comments`, `docs` | `true` | Turn off what you do not want read | | `doc_paths` | all | Limit Markdown to these paths | The source runs on its card’s schedule. See [In code](/build/code/) and [Connect your estate](/connect/#where-every-credential-is-held). ## Permissions | Permission | Read only (the default) | Read and write | Why | | ------------- | ----------------------- | -------------- | ------------------------------------------------------------------------------- | | Metadata | read | read | The repository and its default branch | | Contents | read | write | Read: the Markdown files on the default branch. Write: push a branch | | Issues | read | read | Issues and their comments | | Pull requests | read | write | Read: pull requests, which GitHub lists with issues. Write: open a pull request | Agents write with it only through cards a person approved in LightHouse. The engine’s connector reads only, whatever the access level. The engine calls only these endpoints, all `GET`: - `/repos/{repo}/issues?state=all&sort=updated` and each issue’s comments - `/repos/{repo}` and `/repos/{repo}/git/trees/{branch}?recursive=1` - `/repos/{repo}/contents/{path}` for each Markdown file ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: sealed to your deployment and written by it under `lighthouse/connectors/github/`, as the field `token`. LightHouse never holds it in a form it can read. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: held encrypted in LightHouse under a KMS key used for your tenant alone, and never shown again. - **A source set up in code**: in your own secret store, passed to the engine as `GITHUB_TOKEN`. Rotate it there; the engine reads it when the source’s job starts. Where LightHouse saw the token (an approval, or a token held under your tenant’s key), it tracks the expiry and warns 14 days before it lapses. Connecting again with the same target replaces the old connection. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed | Item | What is kept | | ------------------------ | --------------------------------------------------------------------- | | Issues and pull requests | Title, body and comments, with the repository, kind, state and labels | | Markdown files (`*.md`) | Each file on the default branch, optionally only under `doc_paths` | **Never read:** other files (code included), wikis, and Actions or CI results. **How often:** on the card’s schedule. Each pull reads issues updated since the last one, and only Markdown files whose content changed. A Markdown file deleted from the branch is removed from the corpus. A repository tree too large for GitHub to return whole fails the pull rather than miss files. ## Check it worked - The source’s run note: `written 12, unchanged 0, quarantined 0, removed 0`. A `quarantined` count means documents whose label your scheme does not know; they are kept unreadable. - On the GitHub card in LightHouse: the reads, items written and failures over the last 7 days, from your deployment’s telemetry. This matches when the card’s source keeps its default name, `github`. - **Agents → Knowledge**: documents from `github` in the knowledge base. ## Removing the connection - **In LightHouse**: **Disconnect** on the card (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the connection’s record and fingerprint for the audit trail. - In your own store, Disconnect sends your deployment `connector.revoke`. A GitHub token cannot revoke itself, so your deployment deletes it from your store and answers `provider_manual`, and the card names where to revoke it: *GitHub: Settings, Developer settings, tokens; or uninstall the GitHub App from the organisation*. - Under your tenant’s key, LightHouse revokes the grant at GitHub where it can and deletes the encrypted credential. - **In your deployment**: remove the source card and delete the token from your secret store. The documents it wrote stay in the corpus until you delete them; removing a card does not. Source: https://docs.atlanticagenticlabs.com/connect/github/ --- # GitLab > Connect GitLab to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built.** The engine reads GitLab projects and groups, on GitLab.com or your own instance, and GitLab connects from LightHouse. ## Connect in LightHouse You need the `client_admin` role. Go to **Setup and admin → Connectors → GitLab** and enter the instance (`https://gitlab.com` or your own, HTTPS on port 443, host only), and the projects or groups to read. Under **What agents may do with it**, choose **Read only** (the default) or **Read and write**. See [Access levels](/connect/#access-levels-read-or-read-and-write). ### One-click approval 1. Choose **Approve in GitLab**. Your instance shows the LightHouse OAuth application’s approval screen (authorisation code with PKCE), asking for the scopes of the level you chose. 2. Approve. GitLab returns you to LightHouse, which checks the grant and shows the connection. The approval is valid for 15 minutes. If Atlantic’s OAuth application is not yet registered for your LightHouse, the card says so and offers the token route. ### Access token 1. Create a personal, group or project access token at **User settings → Access tokens** ([gitlab.com/-/user_settings/personal_access_tokens](https://gitlab.com/-/user_settings/personal_access_tokens) on GitLab.com) with only the scopes below for the level you chose. 2. Paste it into the card and choose **Connect**. LightHouse calls `/api/v4/user` and `/api/v4/personal_access_tokens/self` to read the token’s scopes and expiry, and holds the scopes against the level you chose: a token with a write scope, connected as read, is refused with `422 credential_can_write`, and one with no write scope, connected as read and write, with `422 credential_cannot_write`. Those checks are LightHouse’s, for a token it sees. Where your deployment keeps credentials in your own store, the Connect page seals the token in your browser and LightHouse never sees it. Your deployment keeps it, then calls `/api/v4/personal_access_tokens/self` from your account (`connector.check`) and reports the token’s scopes. A write scope on a connection chosen as read then marks the connection `failing`, rather than being refused. See [Where every credential is held](/connect/#where-every-credential-is-held). ### From a terminal `lighthouse-ai connect gitlab` opens LightHouse’s Connect page in your browser (`--no-browser` prints its address), where you approve as above. To connect a token you already have, pipe it to `lighthouse-ai connect gitlab --credential-stdin`, adding `--access read_write` and `--target` as needed. Where your deployment keeps credentials in your own store, the CLI seals the token on your machine. `lighthouse-ai connect gitlab --reuse-local` offers the `glab` sign-in already on your machine and sends it the same way, after you type `yes` at a terminal. It never runs under `--yes`, `--no-input` or in a pipe. See [The CLI](/cli/#connecting-a-provider). ## Connect in code Add a source card to your deployment’s catalogue, and give the engine the token from your own secret store as `GITLAB_TOKEN`, or, for a connection kept in your own store, name it with `credential_secret: ` ([Read a kept credential](/connect/#read-a-kept-credential-in-your-deployment)): ```yaml - id: gitlab-platform purpose: Read the platform group's issues, merge requests, pipelines and docs. executor: python target: aal_engine.ingest.connector:run_card overseer: platform-lead@example.com budget_usd: 0 effect: internal source: kind: gitlab groups: [example-org/platform] # subgroups included, archived projects left out instance_url: https://gitlab.example.com label: standard requires: reads: [issues, merge requests, failed pipelines, Markdown and wiki pages] reason: the operations agents answer from the platform's own records ``` | Setting | Default | Notes | | ------------------------------------------------------------- | -------------------- | ------------------------------------------ | | `projects`, `groups` | (one is required) | Paths such as `group/project` | | `instance_url` | `https://gitlab.com` | Your own instance | | `credential_env` | `GITLAB_TOKEN` | `""` reads public projects without a token | | `issues`, `merge_requests`, `docs`, `wikis`, `ci`, `comments` | `true` | Turn off what you do not want read | | `doc_paths` | all | Limit Markdown to these paths | See [In code](/build/code/). ## Scopes **Read only** (the default): | Scope | Why | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `read_api` | Issues, merge requests, notes, pipelines, the repository tree and files, wikis. The engine needs only this one, and LightHouse asks for it | | `read_user` | Asked for by LightHouse’s approval, to identify the account that approved | **Read and write**: | Scope | Why | | ------------------ | ----------------------------------------------------------------------------------------------------------------------- | | `api` | Merge requests and issues. It also covers every other write in GitLab, so LightHouse asks for it only at read and write | | `read_user` | To identify the account that approved | | `write_repository` | Push a branch over Git | Agents write with it only through cards a person approved in LightHouse. The engine’s connector reads only, whatever the access level. The engine calls, all `GET` under `/api/v4`: `/groups/{g}/projects`; `/projects/{p}/issues` and `/merge_requests` with their notes; `/projects/{p}/pipelines`, and the jobs of failed or cancelled ones; `/projects/{p}/repository/tree` and `/repository/files/{path}/raw`; `/projects/{p}/wikis`. ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: sealed to your deployment and written by it under `lighthouse/connectors/gitlab/`, as the fields `token` and `instance_url`. LightHouse never holds it in a form it can read. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: held encrypted in LightHouse under a KMS key used for your tenant alone, and never shown again. - **A source set up in code**: in your own secret store, passed to the engine as `GITLAB_TOKEN`. Rotate it there. Where LightHouse saw the token (an approval, or a token held under your tenant’s key), it tracks the expiry and warns 14 days before it lapses. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed | Item | What is kept | | -------------- | ------------------------------------------------------------------------- | | Issues | Title, description and comments (system notes left out), state and labels | | Merge requests | The same, with source and target branch | | Pipelines | Status and ref; the jobs of failed or cancelled pipelines | | Markdown files | Each `.md` file on the default branch, optionally under `doc_paths` | | Wiki pages | Each page’s content | **Never read:** code and other non-Markdown files. **How often:** on the card’s schedule. Each pull reads what was updated since the last; files and wiki pages are rewritten only when their content changes, and removed from the corpus when deleted at GitLab. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - The GitLab card in LightHouse: reads, items written and failures over the last 7 days. - **Agents → Knowledge**: documents from `gitlab`. ## Removing the connection - **In LightHouse**: **Disconnect** (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the record for the audit trail. - In your own store, Disconnect sends your deployment `connector.revoke`. A GitLab access token can revoke itself, so your deployment revokes it at your instance (`revoked`) and deletes it from your store. If the revocation fails, it answers `provider_manual` and the card names where to revoke it: *GitLab: the token’s page under Access tokens*. - Under your tenant’s key, LightHouse revokes the OAuth grant at your instance where it can and deletes the encrypted credential. - **In your deployment**: remove the card and the token. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/gitlab/ --- # Datadog > Connect Datadog to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built.** The engine reads Datadog monitors, incidents and postmortems, and Datadog connects from LightHouse. ## Connect in LightHouse You need the `client_admin` role. Go to **Setup and admin → Connectors → Datadog** and choose your site: `us1`, `us3`, `us5`, `eu1`, `ap1` or `us1-fed`. Under **What agents may do with it**, choose **Read only** (the default) or **Read and write**. See [Access levels](/connect/#access-levels-read-or-read-and-write). ### One-click approval 1. Choose **Approve in Datadog**. Datadog shows its OAuth approval for LightHouse on your site (authorisation code with PKCE). 2. Approve. Datadog returns you to LightHouse, which checks the grant. If Atlantic’s Datadog application is not yet registered for your LightHouse, the card says so and offers the key route. Datadog’s approval asks for read access only. Asking it for read and write is refused with `409 route_unavailable`; use the keys instead. The grant Datadog’s approval gives is not a credential your deployment keeps, so it is always held under your tenant’s key, even where your deployment keeps other credentials in your own store. Use the keys to keep Datadog’s credential in your own store. ### API and application keys 1. Create an application key with only the scopes below at **Organization settings → Application keys** ([app.datadoghq.com/organization-settings/application-keys](https://app.datadoghq.com/organization-settings/application-keys) on US1). You also need an API key. 2. Paste both into the card and choose **Connect**. LightHouse checks the pair with `GET /api/v1/validate`. Datadog does not state a key pair’s scopes, so LightHouse records the access level you chose, and the health detail says so: *“Datadog answered. Datadog does not state a key pair’s scopes, so LightHouse records the access level you chose for it.”* That check is LightHouse’s, for keys it sees. Where your deployment keeps credentials in your own store, the Connect page seals the pair in your browser, with your site, and LightHouse never sees it. Your deployment keeps it, then calls `GET https://api./api/v1/validate` and reads one page of monitors with the application key, from your account (`connector.check`). See [Where every credential is held](/connect/#where-every-credential-is-held). ### From a terminal `lighthouse-ai connect datadog` opens LightHouse’s Connect page in your browser (`--no-browser` prints its address), where you approve as above. `lighthouse-ai connect datadog --credential-stdin` connects a key pair you pipe in, as two lines: the API key, then the application key. Where your deployment keeps credentials in your own store, the CLI seals them on your machine. `--reuse-local` offers the `DD_API_KEY` and `DD_APP_KEY` already in your environment and sends them the same way, after you type `yes` at a terminal. It never runs under `--yes`, `--no-input` or in a pipe. See [The CLI](/cli/#connecting-a-provider). ## Connect in code Give the engine the two keys from your own secret store as `DD_API_KEY` and `DD_APP_KEY`, and add a source card: ```yaml - id: datadog-ops purpose: Read monitors, incidents and postmortems for the operations agents. executor: python target: aal_engine.ingest.connector:run_card overseer: sre-lead@example.com budget_usd: 0 effect: internal source: kind: datadog site: datadoghq.eu # the API host suffix: datadoghq.com, us3.datadoghq.com, datadoghq.eu, ... kinds: [monitors, incidents, postmortems] label: standard requires: reads: [monitors, incidents and postmortem notebooks] reason: the operations agents answer from what was seen and learned ``` `site` here is the API host suffix (for example `datadoghq.com` or `datadoghq.eu`), not LightHouse’s site code. `api_key_env` and `app_key_env` change the variable names. ## Scopes | Scope | Why | | ---------------- | -------------------- | | `monitors_read` | Monitors | | `incident_read` | Incidents | | `notebooks_read` | Postmortem notebooks | These three are what LightHouse asks for, and all the engine reads. It does not read dashboards, logs, APM or metrics. LightHouse asks Datadog for read scopes only, at either access level. A credential whose own stated scopes write is recorded as read and write when you choose that level, and refused with `422 credential_can_write` when you chose read. Agents write with it only through cards a person approved in LightHouse. With outbound telemetry chosen (below), LightHouse also asks for `metrics_write` and `events_write`. These two do not count as write access: they are the outbound switch, not an access level. The engine calls, all `GET`: `/api/v1/monitor`, `/api/v2/incidents`, and `/api/v1/notebooks?type=postmortem`. ## Where the credential is held - **A LightHouse connection made with keys, in your own secrets store**, where your deployment can keep it: sealed to your deployment and written by it under `lighthouse/connectors/datadog/`, as the fields `api_key`, `app_key` and `site`. LightHouse never holds it in a form it can read. A source card reads it with `credential_secret: `, and a source configured for another site is refused. - **A LightHouse connection under your tenant’s key**: the approval’s grant always, and keys until your deployment can keep them. Held encrypted in LightHouse under a KMS key used for your tenant alone, and never shown again. - **A source set up in code**: in your own secret store, passed to the engine as `DD_API_KEY` and `DD_APP_KEY`. Rotate them there. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed | Item | What is kept | | ----------- | --------------------------------------------------------------- | | Monitors | Message, query, type, state, tags and priority | | Incidents | State, severity, customer impact and the incident’s text fields | | Postmortems | The Markdown cells of postmortem notebooks; graphs are left out | **Never read:** dashboards, logs, traces and metrics. **How often:** on the card’s schedule, reading what was modified since the last pull. A deleted monitor is removed from the corpus; incidents and postmortems are kept. ## Outbound: LightHouse’s telemetry in your Datadog Optionally, LightHouse can send its own operational telemetry about your agents to your Datadog: metrics and events, nothing from your content. You choose it when connecting, or later with `PUT /api/v1/connections/{cid}/outbound`. LightHouse records the choice and asks for the two write scopes; the sending itself is \[Coming]. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - The Datadog card in LightHouse: reads, items written and failures over the last 7 days. - **Agents → Knowledge**: documents from `datadog`. ## Removing the connection - **In LightHouse**: **Disconnect** keeps the record for the audit trail. - In your own store, Disconnect sends your deployment `connector.revoke`. Datadog keys cannot revoke themselves, so your deployment deletes them from your store and answers `provider_manual`, and the card names where to revoke them: *Datadog: Organization Settings, API keys and Application keys*. - Under your tenant’s key, LightHouse deletes the encrypted credential. Datadog has no revocation LightHouse can call: revoke the application key, or remove the integration, in Datadog. - **In your deployment**: remove the card and the keys. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/datadog/ --- # SharePoint and OneDrive > Connect SharePoint and OneDrive to LightHouse: Microsoft's admin consent or your own app by certificate, the permissions to read or to read and write, where the credential is held, and what is indexed. **Built in the engine.** The engine reads the document libraries of the SharePoint sites you name, and the OneDrive of the people you name, through Microsoft Graph. ## Two ways to connect | Way | Who does what | What is held, and where | | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Approve in Microsoft** | A Microsoft Entra administrator consents for your organisation to Atlantic’s Microsoft app, on Microsoft’s own screen | Nothing secret. Your deployment asks LightHouse for an hour’s Graph token for your own tenant each time it reads. Atlantic holds its app’s certificate, never a token for you, and your documents never pass through LightHouse | | **Your own app, by certificate** | You register an app in your own tenant with a certificate credential, and paste its tenant ID, client ID and the certificate | The certificate, sealed in your browser to your deployment’s key and kept in your own secrets store. Your deployment signs its own requests to Microsoft | A client secret is never accepted, for either way: a certificate cannot be copied from a log or a screenshot the way a password can, and Microsoft recommends one for an app that runs unattended. Until Atlantic’s Microsoft app is registered, the **Approve in Microsoft** button on the card says it needs Atlantic’s Microsoft app, and your own app works meanwhile. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. ### Approve in Microsoft 1. Go to **Setup and admin → Connectors**. On the **SharePoint and OneDrive** card, choose **Connect**. 2. Fill in **Sites** (below), and leave **What agents may do with it** at **Read only**: Atlantic’s app is registered to read only. 3. Choose **Approve in Microsoft**. Microsoft’s sign-in opens. Sign in as a Microsoft Entra administrator of your organisation (a Global Administrator, Privileged Role Administrator or Cloud Application Administrator) and accept the permissions it lists: **Sites.Read.All** and **Files.Read.All**, as application permissions. 4. Microsoft returns you to LightHouse. The organisation recorded is the one Microsoft names in your sign-in, not one typed into the address. ### Your own app, by certificate Before you start, in the [Microsoft Entra admin centre](https://entra.microsoft.com/), under **App registrations**: 1. Register an app, single tenant. 2. Under **API permissions**, add the Microsoft Graph application permissions **Sites.Read.All** and **Files.Read.All**, and grant admin consent. For agents that save documents, use **Sites.ReadWrite.All** and **Files.ReadWrite.All** instead. 3. Under **Certificates and secrets**, upload a certificate (an RSA key, 2048 bits or more). Keep the private key and the certificate together in one PEM file. Then: 1. On the **SharePoint and OneDrive** card, choose **Connect**. 2. Fill in **Directory (tenant) ID** and **Application (client) ID**, both GUIDs from the app’s overview, and **Sites**. 3. Choose **Read only** or **Read and write**, to match the permissions you granted. 4. Under **Paste an access token**, paste the PEM: the private key and then the certificate. 5. Choose **Connect**. Where your deployment keeps credentials in your own store, the page seals the PEM in your browser and LightHouse never sees it. The page says *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* Once it is kept, your deployment checks it from your account (`connector.check`): it signs an assertion with the certificate, asks Microsoft for a token for your tenant, and reports the application permissions the token carries. A token that carries none of the permissions above is reported as missing a scope. ### Access levels Every connection is **Read only** or **Read and write**, shown on the card with a plain *Can write* marker where it can, and recorded in the audit log. Where Microsoft says the token carries a permission that writes (`Sites.ReadWrite.All`, `Files.ReadWrite.All`) and the connection was chosen as read, the check flags it as failing. Agents write only through cards a person approved in LightHouse. See [Access levels](/connect/#access-levels-read-or-read-and-write). ### If it is refused | The page says | Why | What to do | | ------------------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------- | | *needs Atlantic’s Microsoft app* | Atlantic’s app is not registered yet | Use your own app by certificate | | *Microsoft did not say which organisation consented* | The sign-in was not completed by an administrator | Sign in as an Entra administrator and accept | | *the app holds none of Sites.Read.All, Files.Read.All* | The permissions were not granted, or not consented | Grant them and admin consent in the Entra admin centre | | *the certificate is the PEM of the app’s private key and its certificate* | The pasted text is not both | Paste the private key and the certificate together | | *client_id is your app’s id, a GUID* | The client ID is missing or not a GUID | Copy the Application (client) ID from the app’s overview | ## Connect in code ```yaml - id: sharepoint-engineering purpose: Read the engineering site's documents into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: platform-lead@example.com budget_usd: 0 effect: internal source: kind: sharepoint sites: ["example-org.sharepoint.com:/sites/engineering"] libraries: [Documents] # optional: by name; every library otherwise drives: [] # optional: drive ids, read whole users: [] # optional: people whose OneDrive is read max_mb: 50 # larger files are skipped and counted label: standard credential_secret: requires: reads: [the engineering site's document libraries] reason: the engineering agents answer from the team's documents ``` A site is `.sharepoint.com:/sites/` (or `/teams/`), or its Graph site ID. Name sites, drives or people: a whole tenant is never the default. `credential_secret` names the connection whose credential your deployment keeps. Without it, the source reads the credential’s fields as JSON from the variable `credential_env` names (`SHAREPOINT_CREDENTIAL` by default): `tenant_id`, `client_id` and `certificate`. ## Permissions Application permissions on Microsoft Graph, read only: **Sites.Read.All** for site libraries, and **Files.Read.All** for OneDrive. For read and write, **Sites.ReadWrite.All** and **Files.ReadWrite.All**. The engine calls, all `GET`, to `graph.microsoft.com`: the site, its drives, `/drives/{id}/root/delta` for what changed, and each file’s pre-authenticated download link, fetched from your SharePoint host with no Authorization header and never kept. ## Where the credential is held - **Approve in Microsoft**: your own store holds your tenant ID and that the connection uses Atlantic’s app, under `lighthouse/connectors/sharepoint/`. Nothing in it is secret. Each read, your deployment asks LightHouse for an hour’s token for your tenant, signed with your deployment’s own key; LightHouse mints it with Atlantic’s app for that tenant and that connection only, and keeps nothing. - **Your own app**: the fields `tenant_id`, `client_id` and `certificate`, sealed to your deployment and kept in your own store. LightHouse never holds them in a form it can read. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Files** in the named libraries and OneDrives: text, Markdown, CSV, PDF, Word (`.docx`), PowerPoint (`.pptx`) and Excel (`.xlsx`). Each keeps its site, library and path. - **Skipped and counted:** any other format, a file over `max_mb`, and a document that will not open. A skip never stops the rest of the library being read. - **How often:** on the card’s schedule. Each pull follows each drive’s delta from the last one, so an unchanged file is never fetched again. - **Deletions:** a file deleted, or no longer readable, leaves the corpus. If Microsoft no longer honours a drive’s delta, the drive is read again whole and anything no longer there is removed. A library you take out of the configuration has its files removed; a site the credential cannot see at the moment keeps its files. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `sharepoint`. - On the card: the connection’s health, and the reads, items written and failures over the last 7 days. **Check it now** asks your deployment to check the credential again. ## Removing it - **In LightHouse**: on the card, choose **Disconnect**. Your deployment deletes what it kept and the card names where to finish at Microsoft. - **At Microsoft**: for Atlantic’s app, delete it under **Enterprise applications** in the Entra admin centre, which withdraws the consent. For your own app, delete its certificate under **App registrations → Certificates and secrets**. - **In your deployment**: remove the source card. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/sharepoint/ --- # Google Drive > Connect Google Drive to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built in the engine.** The engine reads the Google Drive folders and shared drives you name. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. Google has no approval screen that LightHouse can send you to (the access is granted in your own Google Cloud and Workspace consoles), so Google Drive connects with a service-account key only. ### Before you start 1. In your own Google Cloud project, create a service account, and create a JSON key for it. The card’s **Open Google Drive’s token page** link opens [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials). 2. Share the folders or shared drives with the service account’s address (`…@….iam.gserviceaccount.com`), or, to read a personal Drive, grant the service account domain-wide delegation for `https://www.googleapis.com/auth/drive.readonly` in your Google Workspace admin console. For read and write, grant `https://www.googleapis.com/auth/drive` instead. ### Connect 1. Go to **Setup and admin → Connectors**. Under **Documents and knowledge**, on the **Google Drive** card, choose **Connect**. The page is headed **Connect Google Drive**. 2. Under **Three ways to connect it**, fill in: - **Folders**: folder ids, separated by commas. - **Shared drives**: shared drive ids, separated by commas. Each is read whole. Name folders, shared drives, or both. - **Read as** (optional): the person the service account acts as, for example `ops@example.com`. Needed to read a personal Drive, which a service account reaches only by acting as its owner. - **What agents may do with it**: **Read only** (the default) or **Read and write**. See [Access levels](/connect/#access-levels-read-or-read-and-write). 3. Under **3. Paste an access token** (the only route offered), paste the whole JSON key file into **Service-account key file**. Paste it as it is, with its line breaks. 4. Choose **Connect**. What happens next depends on [where the credential is held](/connect/#where-every-credential-is-held): - **Where your deployment keeps credentials in your own store**, the page seals the key file in your browser, with the **Read as** person, and LightHouse never sees it. The page says *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* Once your deployment has kept it, the page says the connection is connected and where the key is, and your deployment checks it from your account: a one-hour token for `https://www.googleapis.com/auth/drive.readonly`, then `GET /drive/v3/about`. LightHouse cannot run the checks below on a key it never sees. - **Otherwise**, the button reads **Checking it…** while LightHouse asks Google for a token. On success the page says *“Google Drive: … is connected, read only, healthy.”*, naming the service account, followed by a note that the key is held sealed under your key until your deployment supports your own store. The card’s health detail reads *“Google Drive answered, and the key mints a read-only token.”*, or *“… a read and write token.”* for read and write. What LightHouse checks, in order, for a key it sees: 1. The file is a service-account key (`"type": "service_account"`) with a `client_email` and a `private_key`, and its `token_uri`, if present, is Google’s own (`https://oauth2.googleapis.com/token`). A key is sent to Google and nowhere else. 2. LightHouse signs a request for a one-hour token for the scope of the level you chose, acting as the **Read as** person if you named one, and Google issues it: `https://www.googleapis.com/auth/drive.readonly` for read only, `https://www.googleapis.com/auth/drive` for read and write. 3. **Every** scope Google says the token carries must be the one asked for. A key whose token carries anything more is refused, not narrowed. Agents write with it only through cards a person approved in LightHouse. A service-account key does not expire, so the connection never shows as expiring. ### If it is refused The reason appears in red under the form. | The page says | Why | What to do | | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | *Google Drive: the credential is the service-account key file, as JSON* | What was pasted is not JSON | Paste the whole downloaded file | | *Google Drive: that JSON is not a service-account key (its type is not service_account) …* | An OAuth client file, or another JSON file, was pasted | Download a key from the service account itself | | *Google Drive: the service-account key has no client_email* (or *private_key*) | The file is incomplete | Download a new key | | *Google Drive: that key’s token_uri is not Google’s own …* | The file names another token address | Use an unmodified key from Google | | *Google Drive: that service-account key’s private_key could not be read* | The private key is damaged, often by pasting it on one line | Paste the file again with its line breaks | | *Google Drive: `user` is an email address in your domain* | **Read as** is not an email address | Enter an address such as `ops@example.com`, or leave it empty | | *Google Drive: the approval was refused* | Google refused to issue the token: for example, the domain-wide delegation does not grant the scope of the level you chose to this service account’s client ID, or the **Read as** person is not in your domain | Check the delegation in your Google Workspace admin console | | *Google Drive: Google says that key’s token carries …, which is more than reading …* | You chose read only, and the token has a scope beyond `https://www.googleapis.com/auth/drive.readonly` | Choose **Read and write** if agents are to write with it, or grant the service account `https://www.googleapis.com/auth/drive.readonly` and nothing else | | *Google Drive: Google says that key’s token carries …, which is more than the access you chose …* | You chose read and write, and the token has a scope beyond `https://www.googleapis.com/auth/drive` | Grant the service account `https://www.googleapis.com/auth/drive` and nothing else | | *Google Drive could not be reached*, or *Google Drive answered an error; try again shortly* | Google did not answer, or answered with a server error (`503 provider_unavailable`) | Try again shortly | Where the key would be held under your tenant’s key and that key is unavailable, LightHouse stores nothing and answers `503 secret_store_unavailable`; try again, and tell Atlantic if it persists. Where your deployment does not keep it, the page shows **Not kept** with the reason in words; see [A connection exists once its credential is kept](/connect/#a-connection-exists-once-its-credential-is-kept). The API equivalent is `POST /api/v1/connectors/gdrive/token`, from a person’s portal session only. See [Post Token](/api/reference/read/#post-token) in the reference. > **Reading this connection in your deployment:** > > A connection kept in your own store is read by a source card that names it with `credential_secret: `, set up in code (below): your deployment mints a one-hour token from the stored key file, and the source never sees the key. A connection held under your tenant’s key is not passed to your deployment: the source reads Google Drive with an access token your deployment mints itself. ## From a terminal `lighthouse-ai connect gdrive --credential-stdin` connects a key file you pipe in, for example `lighthouse-ai connect gdrive --credential-stdin --target folders= < key.json`, adding `--access read_write` for read and write. It runs as you, exactly as if you had pasted the key on the Connect page, and the CLI seals the key file on your machine where your deployment keeps credentials in your own store. See [The CLI](/cli/#connecting-a-provider). ## Connect in code The engine takes an OAuth **access token** with the `drive.readonly` scope, from the environment variable `GDRIVE_TOKEN`. It holds no refresh token: minting a fresh access token is your platform’s job, for example a service account with domain-wide delegation, or workload identity federation. ```yaml - id: drive-policies purpose: Read the policy folders into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops@example.com budget_usd: 0 effect: internal source: kind: gdrive folders: [] drives: [] # shared drive IDs, if any label: standard requires: reads: [Docs, Sheets, Slides and text files in the policy folders] reason: the HR agents answer from the current policies ``` Name folders, shared drives, or both; at least one is required. ## Scopes | Scope | Level | Why | | ------------------------------------------------ | ----------------------- | ---------------------------------------------------------------- | | `https://www.googleapis.com/auth/drive.readonly` | Read only (the default) | List, export and download files | | `https://www.googleapis.com/auth/drive` | Read and write | Create and change files. The engine’s connector still only reads | The engine calls, all `GET` on `www.googleapis.com`: `/drive/v3/files` (including shared drives), `/drive/v3/changes` and its start token, `/drive/v3/files/{id}/export` and `/drive/v3/files/{id}?alt=media`. ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: the key file is sealed to your deployment and written by it under `lighthouse/connectors/gdrive/`, as the fields `service_account` and, where you named a **Read as** person, `subject`. LightHouse never holds it in a form it can read. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: the service-account key is held encrypted in LightHouse under a KMS key used for your tenant alone, and is never shown again. - **A source set up in code**: in your own account. Whatever mints the access token (a service-account key in your secret store, or federation) stays there; the engine sees only a short-lived token in `GDRIVE_TOKEN`. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed | File | How it is read | | ---------------------------- | --------------------------------- | | Google Docs and Slides | Exported as plain text | | Google Sheets | Exported as CSV (the first sheet) | | Text, Markdown and CSV files | Downloaded as they are | **Never read:** anything else, including PDFs, images and archives. They are skipped and counted in the log. **How often:** on the card’s schedule. Each pull reads Drive’s change feed since the last one. A file deleted, trashed or moved out of the folders is removed from the corpus. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `gdrive`. - On the Google Drive card in LightHouse: the connection’s health, and the reads, items written and failures over the last 7 days from your deployment’s telemetry. `POST /api/v1/connections/{cid}/health` (**Check it now**) checks the key with Google again: LightHouse checks a key under your tenant’s key, and your deployment checks one in your own store (`connector.check`). ## Removing it - **In LightHouse**: on the Google Drive card, choose **Disconnect**, then **Yes, disconnect** (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the connection’s record and fingerprint for the audit trail. In your own store, Disconnect sends your deployment `connector.revoke`: it deletes the key from your store and answers `provider_manual`, and the card names where to revoke it, *Google Cloud: IAM, Service accounts, Keys*. Under your tenant’s key, LightHouse deletes the encrypted key. - **At Google**: LightHouse cannot revoke a service-account key. Delete the key, or withdraw its delegation or the federation grant, in your own Google Cloud and Workspace consoles. - **In your deployment**: remove the source card and its secret. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/google-drive/ --- # Gmail > Connect Gmail to LightHouse: the ways to connect, the read-only scope, where the credential is held, and what is indexed. **Built in the engine.** The engine reads one labelled mailbox: the messages carrying a label you name, in a mailbox you name. A whole mailbox is never the default and cannot be asked for. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. Google has no approval screen that LightHouse can send you to (the access is granted in your own Google Cloud and Workspace consoles), so Gmail connects with a service-account key only. ### Before you start 1. In your own Google Cloud project, create a service account, and create a JSON key for it. The card’s **Open Gmail’s token page** link opens [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials). 2. In your Google Workspace admin console, grant the service account’s client ID domain-wide delegation for `https://www.googleapis.com/auth/gmail.readonly` and no other scope. ### Connect 1. Go to **Setup and admin → Connectors**. Under **Documents and knowledge**, on the **Gmail** card, choose **Connect**. The page is headed **Connect Gmail**. 2. Under **Three ways to connect it**, fill in: - **Mailbox label**: the one label whose messages are read, for example `agents/inbox`. A whole mailbox is never read. - **Read as** (required): the mailbox owner’s address, for example `ops@example.com`. A service account reads a mailbox by acting as its owner, and there is no default. 3. Under **3. Paste an access token** (the only route offered), paste the whole JSON key file into **Service-account key file**. Paste it as it is, with its line breaks. 4. Choose **Connect**. What happens next depends on [where the credential is held](/connect/#where-every-credential-is-held): - **Where your deployment keeps credentials in your own store**, the page seals the key file in your browser, with the **Read as** person, and LightHouse never sees it. The page says *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* Once your deployment has kept it, the page says the connection is connected and where the key is, and your deployment checks it from your account: a one-hour token for `https://www.googleapis.com/auth/gmail.readonly`, acting as the **Read as** person, then `GET /gmail/v1/users/me/profile`. LightHouse cannot run the checks below on a key it never sees. - **Otherwise**, the button reads **Checking it…** while LightHouse asks Google for a token. On success the page says *“Gmail: … is connected, read only, healthy.”*, naming the service account, followed by a note that the key is held sealed under your key until your deployment supports your own store. The card’s health detail reads *“Gmail answered, and the key mints a read-only token.”* What LightHouse checks, in order, for a key it sees: 1. The file is a service-account key (`"type": "service_account"`) with a `client_email` and a `private_key`, and its `token_uri`, if present, is Google’s own (`https://oauth2.googleapis.com/token`). A key is sent to Google and nowhere else. 2. LightHouse signs a request for a one-hour token for `https://www.googleapis.com/auth/gmail.readonly` alone acting as the **Read as** person, and Google issues it. 3. **Every** scope Google says the token carries must be `https://www.googleapis.com/auth/gmail.readonly`. A key whose token carries anything more is refused, not narrowed. A service-account key does not expire, so the connection never shows as expiring. Gmail is offered read only. Unlike most connectors, it has no **Read and write** level: a request for `access: read_write` is refused with `422 invalid`. See [Access levels](/connect/#access-levels-read-or-read-and-write). ### If it is refused The reason appears in red under the form. | The page says | Why | What to do | | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | *Gmail: the credential is the service-account key file, as JSON* | What was pasted is not JSON | Paste the whole downloaded file | | *Gmail: that JSON is not a service-account key (its type is not service_account) …* | An OAuth client file, or another JSON file, was pasted | Download a key from the service account itself | | *Gmail: the service-account key has no client_email* (or *private_key*) | The file is incomplete | Download a new key | | *Gmail: that key’s token_uri is not Google’s own …* | The file names another token address | Use an unmodified key from Google | | *Gmail: that service-account key’s private_key could not be read* | The private key is damaged, often by pasting it on one line | Paste the file again with its line breaks | | *Gmail: name the mailbox to read as `user` …* | **Read as** is empty | Enter the mailbox owner’s address | | *Gmail: `user` is an email address in your domain* | **Read as** is not an email address | Enter an address such as `ops@example.com` | | *Gmail: the approval was refused* | Google refused to issue the token: for example, the domain-wide delegation does not grant `https://www.googleapis.com/auth/gmail.readonly` to this service account’s client ID, or the **Read as** person is not in your domain | Check the delegation in your Google Workspace admin console | | *Gmail: Google says that key’s token carries …, which is more than reading …* | The token has a scope beyond `https://www.googleapis.com/auth/gmail.readonly` | Grant the service account `https://www.googleapis.com/auth/gmail.readonly` and nothing else | | *Gmail could not be reached*, or *Gmail answered an error; try again shortly* | Google did not answer, or answered with a server error (`503 provider_unavailable`) | Try again shortly | Where the key would be held under your tenant’s key and that key is unavailable, LightHouse stores nothing and answers `503 secret_store_unavailable`; try again, and tell Atlantic if it persists. Where your deployment does not keep it, the page shows **Not kept** with the reason in words; see [A connection exists once its credential is kept](/connect/#a-connection-exists-once-its-credential-is-kept). The API equivalent is `POST /api/v1/connectors/gmail/token`, from a person’s portal session only. See [Post Token](/api/reference/read/#post-token) in the reference. > **Reading this connection in your deployment:** > > A connection kept in your own store is read by a source card that names it with `credential_secret: `, set up in code (below): your deployment mints a one-hour token from the stored key file, and the source never sees the key. A connection held under your tenant’s key is not passed to your deployment: the source reads Gmail with an access token your deployment mints itself. ## From a terminal `lighthouse-ai connect gmail --credential-stdin` connects a key file you pipe in, for example `lighthouse-ai connect gmail --credential-stdin --target mailbox_label=agents/inbox --target user=ops@example.com < key.json`. It runs as you, exactly as if you had pasted the key on the Connect page, and the CLI seals the key file on your machine where your deployment keeps credentials in your own store. See [The CLI](/cli/#connecting-a-provider). ## Connect in code The engine takes an OAuth **access token** with the `gmail.readonly` scope, from the environment variable `GMAIL_TOKEN`. It holds no refresh token: minting a fresh access token is your platform’s job, for example a service account with domain-wide delegation, or workload identity federation. Because access tokens expire within an hour, a leaked run directory holds no long-lived credential. ```yaml - id: ops-correspondence purpose: Read the labelled operations mailbox into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops@example.com budget_usd: 0 effect: internal source: kind: gmail mailbox_label: ops-inbox # required; a whole mailbox is never read label: confidential requires: reads: [messages carrying the ops-inbox label, with their headers and bodies] reason: the operations agents answer correspondence from what was said before ``` ## Scopes | Scope | Why | | ------------------------------------------------ | ---------------------------------------------- | | `https://www.googleapis.com/auth/gmail.readonly` | List and read the labelled messages. Read only | Whichever way you connect, the scope is the same one and no other is accepted. A service-account key whose delegation grants anything broader is refused when you connect it: Google is asked what the minted token carries, and **every** scope it answers with has to be this one. ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: the key file is sealed to your deployment and written by it under `lighthouse/connectors/gmail/`, as the fields `service_account` and `subject`. LightHouse never holds it in a form it can read. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: the service-account key is held encrypted in LightHouse under a KMS key used for your tenant alone, and is never shown again. - **A source set up in code**: in your own account. Whatever mints the access token (a service-account key in your secret store, or federation) stays there; the engine sees only a short-lived token in `GMAIL_TOKEN`. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Messages** carrying the label you named, as plain text (the plain-text part, or the HTML part with its tags removed), with their subject, correspondents and date. - **Never read:** anything outside that label, and attachments. A document that matters belongs in a folder or drive the engine reads. - **How often:** on the card’s schedule. Each pull reads the mailbox’s history feed since the last one. - **Removals:** a message that loses the label, or is deleted, is removed from the corpus, so agents stop citing mail your team refiled. Gmail keeps history for about a week; if the stored position has expired, the next pull lists the label again in full and removes what is no longer there. ## Agents that draft replies The Gmail connector cannot send mail: it only issues reads, and nothing in it calls a send endpoint. The one tool it offers that writes, `aal__gmail__create_draft`, creates a Gmail **draft** and nothing more. A draft reaches outside the run, so it is an external effect: - the agent’s card must list the tool among its `effect_tools`; - the tool policy must allow that agent the tool *with approval*; - the call is refused unless it carries a named person’s approval from the orchestrator; - at autonomy 0 the policy forbids it outright. A person then reviews and sends the draft from Gmail. See [Approvals](/concepts/approvals/). ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `gmail`. ## Removing it - **In LightHouse**: on the Gmail card, choose **Disconnect**, then **Yes, disconnect** (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the connection’s record and fingerprint for the audit trail. In your own store, Disconnect sends your deployment `connector.revoke`: it deletes the key from your store and answers `provider_manual`, and the card names where to revoke it, *Google Cloud: IAM, Service accounts, Keys; and the domain-wide delegation in the Admin console*. Under your tenant’s key, LightHouse deletes the encrypted key. - **At Google**: LightHouse cannot revoke a service-account key. Delete the key, or withdraw its domain-wide delegation, in your own Google Cloud and Workspace consoles. - **In your deployment**: remove the source card and its secret. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/gmail/ --- # Amazon S3 > Connect Amazon S3 to LightHouse: a role your deployment assumes, the permissions it reads with, why nothing secret is stored, and what is indexed. **Built in the engine.** The engine reads the objects under a bucket and prefix you name, in place, by role assumption in your own AWS account. **Nothing secret is stored.** Your deployment’s own AWS identity assumes a role you create, and the role’s trust policy is the permission. No access key is pasted, sealed or kept anywhere: a role’s ARN and an external ID are identifiers. ## Before you start Create a role in the account that holds the bucket, trusted by your deployment’s role (the scheduled jobs’ role in the stack **Get my stack** generated): ```json { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam:::role/example-org-prod-jobs" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "example-org-documents" } } }] } ``` and give it read access to the prefix and nothing else: ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::example-org-documents", "Condition": { "StringLike": { "s3:prefix": ["published/*"] } } }, { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-org-documents/published/*" } ] } ``` Where the bucket uses a customer managed KMS key, also allow `kms:Decrypt` on it. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. 1. Go to **Setup and admin → Connectors**. On the **Amazon S3** card, choose **Connect**. 2. Fill in **Bucket**, **Prefix** (optional), **Region** and **External ID** (where the trust policy names one). 3. Under **Paste an access token**, give the role’s ARN, `arn:aws:iam:::role/`. 4. Choose **Connect**. Amazon S3 connections are **Read only**, shown on the card and in the audit log. LightHouse cannot reach your account and does not try: your deployment checks the connection (`connector.check`) by assuming the role and listing one key under the prefix. ## Connect in code ```yaml - id: s3-manuals purpose: Read the published manuals into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: maintenance-lead@example.com budget_usd: 0 effect: internal source: kind: s3 bucket: example-org-documents prefix: published/ region: eu-west-1 role_arn: arn:aws:iam:::role/aal-knowledge-reader external_id: example-org-documents label: standard requires: reads: [s3:example-org-documents/published/*] reason: the maintenance agents answer from the published manuals ``` Without `role_arn`, the deployment’s own identity reads the bucket, for a bucket in the same account. With `credential_secret: `, the role, external ID and bucket come from the LightHouse connection, and a source configured for another bucket is refused. ## Permissions `s3:ListBucket` on the prefix and `s3:GetObject` on its objects, through `sts:AssumeRole`. The engine only reads. ## What is indexed - **Objects** under the prefix: text, Markdown, CSV, PDF, Word (`.docx`), PowerPoint (`.pptx`) and Excel (`.xlsx`). - **Skipped and counted:** any other format, an object over 50 MB, and a document that will not open. - **How often:** on the card’s schedule. An object whose ETag has not changed is never fetched again. - **Deletions:** an object deleted from the bucket, or moved out of the prefix, leaves the corpus. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `s3`. ## Removing it On the card, choose **Disconnect**; then remove the trust policy’s statement, or the role, in IAM. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/s3/ --- # Confluence > Connect Confluence to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built in the engine.** The engine reads Confluence pages from the spaces you name, on Atlassian Cloud or your own server. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. Atlassian has no approval screen that LightHouse can send you to, so Confluence connects with an API token only. A self-hosted Data Center site cannot be connected in LightHouse; connect it in code (below). ### Before you start 1. Create, or choose, an **integration account** in your Atlassian site that has access to the spaces you name and nothing else: read access to read, or edit access where agents publish. Do not use a site administrator: LightHouse refuses an administrator’s token where it checks the token itself (below). 2. Signed in as that account, create an API token at [id.atlassian.com/manage-profile/security/api-tokens](https://id.atlassian.com/manage-profile/security/api-tokens). Copy it. ### Connect 1. Go to **Setup and admin → Connectors**. Under **Documents and knowledge**, on the **Confluence** card, choose **Connect**. The page is headed **Connect Confluence**. 2. Under **Three ways to connect it**, fill in: - **Your Atlassian site**: your Atlassian Cloud address, for example `https://example.atlassian.net`. - **Spaces**: the space keys to read, separated by commas, for example `ENG, OPS`. - **What agents may do with it**: **Read only** (the default) or **Read and write**. 3. Under **3. Paste an access token** (the only route offered), enter the **Account email address** of the integration account and the **API token**. 4. Choose **Connect**. What happens next depends on [where the credential is held](/connect/#where-every-credential-is-held): - **Where your deployment keeps credentials in your own store**, the page seals the email and token in your browser, with your site, and LightHouse never sees them. The page says *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* Once your deployment has kept it, the page says the connection is connected and where the credential is, and your deployment checks it at Confluence from your account (`GET /wiki/rest/api/user/current`). LightHouse cannot run the administrator check below on a token it never sees. - **Otherwise**, the button reads **Checking it…** while LightHouse calls your site as that account. On success the page says *“Confluence: … is connected, read only, healthy.”* (or *and can write*), naming the account and your site, followed by a note that the credential is held sealed under your key until your deployment supports your own store. The new connection appears on the Confluence card when you reload. What LightHouse checks, in order, for a token it sees: 1. The site address is `https://.atlassian.net`, on port 443. Nothing is sent anywhere else. 2. The email address and token are accepted by your site (`GET /wiki/rest/api/user/current`). 3. The account is not in an administrator group (`site-admins`, `org-admins`, `administrators`, `system-administrators`, `jira-administrators` or `confluence-administrators`). If Atlassian will not list the account’s groups, the connection is still made, and its health detail says that this check could not run. Atlassian API tokens carry no scopes, so the account’s own permissions decide what can be read and written. LightHouse cannot check the access level against the token, so it records the level your administrator chose (`scopes_stated: false`). For read and write, give the integration account edit access to the spaces agents write to, and choose **Read and write**. Agents write with it only through cards a person approved in LightHouse. See [Access levels](/connect/#access-levels-read-or-read-and-write). The card’s health detail says so: *“Confluence answered. Atlassian does not state an API token’s scopes, so LightHouse reads with this account’s own permissions; give it access to the spaces and projects you name here and nothing else.”* ### If it is refused The reason appears in red under the form. | The page says | Why | What to do | | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | *Confluence: that account administers the site (it is in …)* | The token belongs to an administrator | Make the token on an account that is not a site administrator, with access to only the spaces you name | | *Atlassian: base_url is your Atlassian Cloud site, * | The address is not an Atlassian Cloud site, or is missing | Use your `.atlassian.net` address. For Data Center, connect in code | | *Atlassian: the credential is two lines, your account’s email address and then the API token* | One of the two fields is empty | Fill in both | | *Confluence: that credential was not accepted* | Atlassian answered 401 or 403: the email and token do not match, or the token was revoked | Check the email is the token owner’s; make a new token | | *Confluence could not be reached*, or *Confluence answered an error; try again shortly* | Atlassian did not answer, or answered with a server error (`503 provider_unavailable`) | Try again shortly | | *field is not in the shape this connector takes* | A field has characters it does not accept | Spaces are letters, digits, `_` and `-`, separated by commas | Where the credential would be held under your tenant’s key and that key is unavailable, LightHouse stores nothing and answers `503 secret_store_unavailable`; try again, and tell Atlantic if it persists. Where your deployment does not keep it, the page shows **Not kept** with the reason in words; see [A connection exists once its credential is kept](/connect/#a-connection-exists-once-its-credential-is-kept). The API equivalent is `POST /api/v1/connectors/confluence/token`, from a person’s portal session only. See [Post Token](/api/reference/read/#post-token) in the reference. > **Reading this connection in your deployment:** > > A connection kept in your own store is read by a source card that names it with `credential_secret: `, set up in code (below). A connection held under your tenant’s key is not passed to your deployment: the source reads Confluence with its own copy of the credential from your secret store. ## From a terminal `lighthouse-ai connect confluence --credential-stdin` connects an API token you pipe in, as two lines: the account’s email address, then the token. Add `--target base_url=https://example.atlassian.net --target spaces=ENG,OPS` and, for read and write, `--access read_write`. It runs as you, exactly as if you had pasted the token on the Connect page, and the CLI seals the token on your machine where your deployment keeps credentials in your own store. See [The CLI](/cli/#connecting-a-provider). ## Connect in code Set three environment variables from your own secret store: | Variable | Value | | --------------------- | -------------------------------------------------------------------------- | | `CONFLUENCE_BASE_URL` | Your site’s wiki address, for example `https://example.atlassian.net/wiki` | | `CONF_EMAIL` | The account’s email address | | `CONF_TOKEN` | An Atlassian API token for that account | Then add a source card to your catalogue: ```yaml - id: confluence-eng purpose: Read the engineering spaces' pages into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: platform-lead@example.com budget_usd: 0 effect: internal source: kind: confluence spaces: [ENG, OPS] label: standard limit: 500 # pages per pull reconcile_hours: 6 # how often deletions are looked for requires: reads: [pages in the ENG and OPS spaces, with their versions] reason: the engineering agents answer from the run books and designs ``` To check the credential by hand: `python -m aal_engine.connectors.confluence search 'space = ENG' 5` lists five pages. ## Permissions The engine signs in with the account’s email and API token (HTTP Basic) and only reads. Give the account read access to the spaces you name, and nothing else: what it can read is what the engine can read. LightHouse’s card lists the scopes `read:page:confluence` and `read:space:confluence` for a scoped token. The engine calls, all `GET`: `/rest/api/search` with a CQL query over your spaces’ pages, ordered by last modified, `/rest/api/content/{id}` for each page’s body, version, space and ancestors, and, to find deletions, `/rest/api/content` by space key for page ids only. ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: sealed to your deployment and written by it under `lighthouse/connectors/confluence/`, as the fields `email`, `token` and `site`. LightHouse never holds it in a form it can read. A source card reads it with `credential_secret: `. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: held encrypted in LightHouse under a KMS key used for your tenant alone, and never shown again. - **A source set up in code**: in your own secret store, passed to the engine as `CONF_EMAIL` and `CONF_TOKEN`. Rotate the token at [id.atlassian.com](https://id.atlassian.com/manage-profile/security/api-tokens) and update the secret. An API token’s expiry is set at Atlassian, not reported to LightHouse. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Pages** (`type = page`) in the named spaces, as plain text from their export view; images become `[image]`. Each keeps its space, version and ancestor path. - **Never read:** blog posts, comments and attachments. - **How often:** on the card’s schedule. Each pull reads up to `limit` pages modified since the last pull’s day. - **Deletions:** a page deleted in Confluence, or archived when only current pages are read, leaves the corpus. Every six hours (`reconcile_hours: 6`, which you can change on the source card) the engine lists the page ids in each space, without their bodies, and removes every page it holds that is no longer there. A space the credential cannot see at that moment keeps its pages until it can be read again; a space you take out of `spaces` has its pages removed. The run note counts them as `removed N`. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `confluence`. - On the Confluence card in LightHouse: the connection’s health detail, and the reads, items written and failures over the last 7 days from your deployment’s telemetry. `POST /api/v1/connections/{cid}/health` (**Check it now**) checks the credential with Atlassian again: LightHouse checks a credential under your tenant’s key, and your deployment checks one in your own store (`connector.check`). ## Removing it - **In LightHouse**: on the Confluence card, choose **Disconnect**, then **Yes, disconnect** (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the connection’s record and fingerprint for the audit trail. In your own store, Disconnect sends your deployment `connector.revoke`: it deletes the credential from your store and answers `provider_manual`, and the card names where to revoke it, *Atlassian: id.atlassian.com, Security, API tokens*. Under your tenant’s key, LightHouse deletes the encrypted credential. - **At Atlassian**: LightHouse cannot revoke an API token; there is no API for it. Revoke the token at [id.atlassian.com](https://id.atlassian.com/manage-profile/security/api-tokens). - **In your deployment**: remove the source card and the secrets. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/confluence/ --- # Jira > Connect Jira to LightHouse: the ways to connect, the scopes to read or to read and write, where the credential is held, and what is indexed. **Built in the engine.** The engine reads Jira issues and their comments from the projects you name. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. Atlassian has no approval screen that LightHouse can send you to, so Jira connects with an API token only. A self-hosted Data Center site cannot be connected in LightHouse; connect it in code (below). ### Before you start 1. Create, or choose, an **integration account** in your Atlassian site that has access to the projects you name and nothing else: browse access to read, or the permissions agents need to comment on and update issues. Do not use a site administrator: LightHouse refuses an administrator’s token where it checks the token itself (below). 2. Signed in as that account, create an API token at [id.atlassian.com/manage-profile/security/api-tokens](https://id.atlassian.com/manage-profile/security/api-tokens). Copy it. ### Connect 1. Go to **Setup and admin → Connectors**. Under **Documents and knowledge**, on the **Jira** card, choose **Connect**. The page is headed **Connect Jira**. 2. Under **Three ways to connect it**, fill in: - **Your Atlassian site**: your Atlassian Cloud address, for example `https://example.atlassian.net`. - **Projects**: the project keys to read, separated by commas, for example `SUP, OPS`. - **What agents may do with it**: **Read only** (the default) or **Read and write**. 3. Under **3. Paste an access token** (the only route offered), enter the **Account email address** of the integration account and the **API token**. 4. Choose **Connect**. What happens next depends on [where the credential is held](/connect/#where-every-credential-is-held): - **Where your deployment keeps credentials in your own store**, the page seals the email and token in your browser, with your site, and LightHouse never sees them. The page says *“Waiting for your deployment … to keep it in your own store. Nothing is connected until it says so.”* Once your deployment has kept it, the page says the connection is connected and where the credential is, and your deployment checks it at Jira from your account (`GET /rest/api/3/myself`). LightHouse cannot run the administrator check below on a token it never sees. - **Otherwise**, the button reads **Checking it…** while LightHouse calls your site as that account. On success the page says *“Jira: … is connected, read only, healthy.”* (or *and can write*), naming the account and your site, followed by a note that the credential is held sealed under your key until your deployment supports your own store. The new connection appears on the Jira card when you reload. What LightHouse checks, in order, for a token it sees: 1. The site address is `https://.atlassian.net`, on port 443. Nothing is sent anywhere else. 2. The email address and token are accepted by your site (`GET /rest/api/3/myself`). 3. The account is not in an administrator group (`site-admins`, `org-admins`, `administrators`, `system-administrators`, `jira-administrators` or `confluence-administrators`). If Atlassian will not list the account’s groups, the connection is still made, and its health detail says that this check could not run. Atlassian API tokens carry no scopes, so the account’s own permissions decide what can be read and written. LightHouse cannot check the access level against the token, so it records the level your administrator chose (`scopes_stated: false`). For read and write, give the integration account the permissions agents need to comment on and update issues, and choose **Read and write**. Agents write with it only through cards a person approved in LightHouse. See [Access levels](/connect/#access-levels-read-or-read-and-write). The card’s health detail says so: *“Jira answered. Atlassian does not state an API token’s scopes, so LightHouse reads with this account’s own permissions; give it access to the spaces and projects you name here and nothing else.”* ### If it is refused The reason appears in red under the form. | The page says | Why | What to do | | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | *Jira: that account administers the site (it is in …)* | The token belongs to an administrator | Make the token on an account that is not a site administrator, with access to only the projects you name | | *Atlassian: base_url is your Atlassian Cloud site, * | The address is not an Atlassian Cloud site, or is missing | Use your `.atlassian.net` address. For Data Center, connect in code | | *Atlassian: the credential is two lines, your account’s email address and then the API token* | One of the two fields is empty | Fill in both | | *Jira: that credential was not accepted* | Atlassian answered 401 or 403: the email and token do not match, or the token was revoked | Check the email is the token owner’s; make a new token | | *Jira could not be reached*, or *Jira answered an error; try again shortly* | Atlassian did not answer, or answered with a server error (`503 provider_unavailable`) | Try again shortly | | *field is not in the shape this connector takes* | A field has characters it does not accept | Projects are letters, digits, `_` and `-`, separated by commas | Where the credential would be held under your tenant’s key and that key is unavailable, LightHouse stores nothing and answers `503 secret_store_unavailable`; try again, and tell Atlantic if it persists. Where your deployment does not keep it, the page shows **Not kept** with the reason in words; see [A connection exists once its credential is kept](/connect/#a-connection-exists-once-its-credential-is-kept). The API equivalent is `POST /api/v1/connectors/jira/token`, from a person’s portal session only. See [Post Token](/api/reference/read/#post-token) in the reference. > **Reading this connection in your deployment:** > > A connection kept in your own store is read by a source card that names it with `credential_secret: `, set up in code (below). A connection held under your tenant’s key is not passed to your deployment: the source reads Jira with its own copy of the credential from your secret store. ## From a terminal `lighthouse-ai connect jira --credential-stdin` connects an API token you pipe in, as two lines: the account’s email address, then the token. Add `--target base_url=https://example.atlassian.net --target projects=SUP,OPS` and, for read and write, `--access read_write`. It runs as you, exactly as if you had pasted the token on the Connect page, and the CLI seals the token on your machine where your deployment keeps credentials in your own store. See [The CLI](/cli/#connecting-a-provider). ## Connect in code Set three environment variables from your own secret store: | Variable | Value | | --------------- | ------------------------------------------------------------------- | | `JIRA_BASE_URL` | Your site, for example `https://example.atlassian.net` (HTTPS only) | | `JIRA_EMAIL` | The account’s email address | | `JIRA_TOKEN` | An Atlassian API token for that account | Then add a source card: ```yaml - id: jira-support purpose: Read the support projects' issues for the triage agents. executor: python target: aal_engine.ingest.connector:run_card overseer: support-lead@example.com budget_usd: 0 effect: internal source: kind: jira projects: [SUP, OPS] label: standard requires: reads: [issues and comments in SUP and OPS] reason: the triage agents find earlier cases like the new one ``` `site_env`, `email_env` and `credential_env` change the variable names. ## Permissions The engine signs in with the account’s email and API token (HTTP Basic) and only reads. Give the account browse access to the projects you name, and nothing else. LightHouse’s card lists the scope `read:jira-work` for a scoped token. The engine calls, all `GET`: `/rest/api/3/search/jql` (summary, description, comments, status, type, project and labels, paged; and, to find deletions, the keys alone) and `/rest/api/3/issue/{key}/comment`. ## Where the credential is held - **A LightHouse connection, in your own secrets store**, where your deployment can keep it: sealed to your deployment and written by it under `lighthouse/connectors/jira/`, as the fields `email`, `token` and `site`. LightHouse never holds it in a form it can read. A source card reads it with `credential_secret: `. - **A LightHouse connection, under your tenant’s key**, until your deployment can keep it: held encrypted in LightHouse under a KMS key used for your tenant alone, and never shown again. - **A source set up in code**: in your own secret store, passed to the engine as `JIRA_EMAIL` and `JIRA_TOKEN`. Rotate the token at [id.atlassian.com](https://id.atlassian.com/manage-profile/security/api-tokens) and update the secret. An API token’s expiry is set at Atlassian, not reported to LightHouse. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Issues**: the description and every comment in one document, with the project, type, status and labels. - **Never read:** attachments, work logs and history. - **How often:** on the card’s schedule, reading issues updated since the last pull (widened by a day, so nothing on the boundary is missed). - **Deletions:** a deleted issue, or one moved to a project you do not name (its key changes), leaves the corpus. Every six hours (`reconcile_hours: 6`, which you can change on the source card) the engine lists the issue keys in your projects, with no other field, and removes every issue it holds that is no longer there. A project you take out of `projects` has its issues removed. If Jira refuses the listing, the pull fails and nothing is removed. The run note counts them as `removed N`. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `jira`. - On the Jira card in LightHouse: the connection’s health detail, and the reads, items written and failures over the last 7 days from your deployment’s telemetry. `POST /api/v1/connections/{cid}/health` (**Check it now**) checks the credential with Atlassian again: LightHouse checks a credential under your tenant’s key, and your deployment checks one in your own store (`connector.check`). ## Removing it - **In LightHouse**: on the Jira card, choose **Disconnect**, then **Yes, disconnect** (`DELETE /api/v1/connections/{cid}`). LightHouse keeps the connection’s record and fingerprint for the audit trail. In your own store, Disconnect sends your deployment `connector.revoke`: it deletes the credential from your store and answers `provider_manual`, and the card names where to revoke it, *Atlassian: id.atlassian.com, Security, API tokens*. Under your tenant’s key, LightHouse deletes the encrypted credential. - **At Atlassian**: LightHouse cannot revoke an API token; there is no API for it. Revoke the token at [id.atlassian.com](https://id.atlassian.com/manage-profile/security/api-tokens). - **In your deployment**: remove the source card and the secrets. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/jira/ --- # Salesforce > Connect Salesforce to LightHouse: your own connected app by certificate (the OAuth 2.0 JWT bearer flow), the scopes it asks for, where the credential is held, and what is indexed. The engine reads accounts, opportunities, cases with their comments, and published Knowledge articles from your org into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## Ways to connect | Way | What you do | | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Connect your own connected app by certificate** | Make a connected app in your org with a digital certificate and the `api` scope, pre-authorise the integration user, and paste the app’s consumer key and the PEM of the certificate’s private key. Your deployment signs a two-minute assertion with the key (the OAuth 2.0 JWT bearer flow): no client secret and no password exist anywhere | | **Approve in Salesforce** | Listed, not yet available: it needs Atlantic’s own connected app, which is not registered yet. The card says so | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Salesforce** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `instance_url` (your My Domain, `https://.my.salesforce.com`; a sandbox is `https://.sandbox.my.salesforce.com`), `username` (the integration user) and `objects`. 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste two parts: the connected app’s consumer key on the first line, then the PEM of the private key. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: salesforce-knowledge purpose: Read Salesforce into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: salesforce objects: [accounts, opportunities, cases, knowledge] knowledge_fields: [Body__c] # optional: the article's rich-text fields label: internal credential_secret: requires: reads: [salesforce:accounts, opportunities, cases and published articles] reason: the commercial agents answer from the account and case history ``` ## Scopes and permissions - **The connected app’s scope**: `api`. Salesforce has no read-only OAuth scope: `api` lets the user’s own permissions decide. - **Read-only is the integration user’s profile.** Give the user a read-only permission set over Account, Opportunity, Case and your Knowledge object, and nothing that creates or edits. Choose **Read and write** only if your agents write through approved cards, and give the user edit rights on what those cards change. - **The health check**: your deployment signs in at your My Domain and reads one account id. Salesforce states the connected app’s scopes, and the card shows them. The `api` scope is not counted as writing, because the profile decides; the card says so. - **One host**: the token is asked for at your My Domain and every read goes there. An answer that names another instance is refused before anything is read. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect salesforce --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/salesforce/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Accounts, opportunities and cases**: the fields that identify and describe them, with a case’s comments in its document. **Knowledge**: published (`Online`) articles only, one document per article, replaced when a new version is published. - **How often, and what is read each time**: on the card’s schedule. Each pull asks for records whose `SystemModstamp` is after the cursor (one per object), in order, and pages by `nextRecordsUrl`. - **Deletions**: every six hours the ids are listed (ids only) and a record that has gone, or an article that was archived, is removed. - **Rate limits**: reads count against your org’s daily API allowance; batches of up to 2,000 records keep the calls few. A refused or failed page fails the pull, which tries again on the next run and never advances the cursor past what it did not read. - **Never read**: attachments and files, and objects you do not name. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `salesforce`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Remove the certificate from the connected app, or the user’s pre-authorisation, in Salesforce Setup. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/salesforce/ --- # ServiceNow > Connect ServiceNow to LightHouse: an OAuth client or a read-only integration user, the roles it needs, where the credential is held, and what is indexed. The engine reads incidents, change requests, CMDB configuration items and published Knowledge articles from your instance into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## Ways to connect | Way | What you do | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **An OAuth client** | Register an OAuth client for the client-credentials grant on your instance, and paste its client id and secret (two lines). Your instance must allow the client-credentials grant | | **An integration user** | Make a user with `snc_read_only` and the read roles of the tables named, and paste its user name and password (two lines) | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **ServiceNow** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `instance_url` (`https://.service-now.com`), `sign_in` (an OAuth client or an integration user), `objects` and, optionally, `cmdb_class`. 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste two lines: the client id and secret, or the user name and password. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: servicenow-knowledge purpose: Read ServiceNow into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: servicenow objects: [incidents, changes, cmdb, knowledge] cmdb_class: cmdb_ci_server # optional: one CMDB class; cmdb_ci otherwise label: internal credential_secret: requires: reads: [servicenow:incidents, changes, servers and published articles] reason: the operations agents answer from the incident and change history ``` ## Roles - **Read only**: `snc_read_only`, with the read roles of `incident`, `change_request`, your CMDB class and `kb_knowledge`. - **Read and write**: the user’s roles decide what it can write, for agents that write through approved cards. - **The health check**: your deployment signs in and reads one incident id. ServiceNow does not state a credential’s roles to it, so the access level is your administrator’s choice and the card says the provider did not state it. - **One host**: your instance, named when you connect and sealed with the credential. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect servicenow --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/servicenow/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Incidents, changes, configuration items and Knowledge articles**: the fields that describe them (references by name), and an article’s text. Only published articles. - **How often, and what is read each time**: on the card’s schedule. Each pull reads records whose `sys_updated_on` is after the cursor, in order, paged. The query starts a day before the cursor, because ServiceNow reads the date in the user’s own time zone, and anything not newer is dropped. - **Deletions**: every six hours the `sys_id`s are listed and a record that has gone is removed. - **Rate limits**: requests are paced; a `429` waits as long as the instance asks. - **Never read**: attachments, journal fields other than those named, and tables you do not name. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `servicenow`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Remove the OAuth client in **System OAuth → Application Registry**, or make the integration user inactive. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/servicenow/ --- # Slack > Connect Slack to LightHouse as a knowledge source: Atlantic's Slack app or your own bot token, the scopes it reads with, where the credential is held, and what is indexed. **Built in the engine.** The engine reads the public channels your Slack app has been added to, with their threads, into a knowledge base. Only **public channels the app has been added to** are read. A person adds the app to a channel, and that is the decision to let the agents read it. Private channels, direct messages and group messages are never read: the scopes asked for cannot reach them. ## Two ways to connect | Way | What you do | | ------------------------- | ------------------------------------------------------------------------------------------------------- | | **Approve in Slack** | A workspace administrator installs Atlantic’s Slack app on Slack’s own screen | | **Paste an access token** | Paste the bot token (`xoxb-`) of your own Slack app, which may be the app your agents already answer in | Until Atlantic’s Slack app is registered, the **Approve in Slack** button says it needs Atlantic’s Slack app, and your own app’s bot token works meanwhile. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. 1. Go to **Setup and admin → Connectors**. On the **Slack** card, choose **Connect**. 2. Choose **Approve in Slack** and install the app; or, under **Paste an access token**, paste your own app’s bot token. 3. In Slack, add the app to each public channel to be read (`/invite @LightHouse`, or the channel’s **Integrations** tab). Slack connections are **Read only**, shown on the card and in the audit log. The token is checked with `auth.test`, and the scopes Slack states must include `channels:read` and `channels:history`. Where your deployment keeps credentials in your own store, a pasted token is sealed in your browser and LightHouse never sees it. ## Connect in code ```yaml - id: slack-ops purpose: Read the operations channels into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: slack channels: [ops-incidents] # optional: by name; every channel the app is in otherwise history_days: 365 # how far back the corpus reaches label: standard credential_secret: requires: reads: [the public channels the app has been added to] reason: the operations agents answer from what the team has already said ``` Without `credential_secret`, the bot token is read from the variable `credential_env` names (`SLACK_TOKEN` by default). ## Scopes Bot scopes: `channels:read` (which public channels the app is in), `channels:history` (their messages and threads), `users:read` and `team:read`. The engine calls, all to `slack.com`: `auth.test`, `conversations.list` (public channels only), `conversations.history` and `conversations.replies`. ## Where the credential is held - **A LightHouse connection**: the bot token, sealed to your deployment and kept in your own secrets store under `lighthouse/connectors/slack/`; or, until your deployment can keep it, held encrypted under your tenant’s key. - **A source set up in code**: in your own secret store, passed as `SLACK_TOKEN`. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Threads**: a channel message and its replies, in order, as one document, with the channel and who wrote it. - **Never read:** private channels, direct and group messages, files, and joins and other channel events. - **How often:** on the card’s schedule. Each pull reads the last seven days of every channel, which catches new messages and replies to recent threads. - **Deletions and older changes:** Slack does not send LightHouse events, and none are needed. Every six hours the engine lists the whole `history_days` window and holds it to what it has: a thread that has gone is removed, one whose replies changed is read again, and one older than the window leaves the corpus. A channel the app has left, that was archived, or that you take out of `channels` has its threads removed. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `slack`. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the token from your store; remove the app in your workspace’s app management to revoke it at Slack. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/slack/ --- # Microsoft Teams > Connect Microsoft Teams to LightHouse: Microsoft's admin consent or your own app by certificate, the permissions it reads with, where the credential is held, and what is indexed. **Built in the engine.** The engine reads the channel messages of the teams you name, with their replies, through Microsoft Graph. ## Two ways to connect Teams connects the same two ways as [SharePoint and OneDrive](/connect/sharepoint/#two-ways-to-connect), and shares Atlantic’s Microsoft app with it: - **Approve in Microsoft**: a Microsoft Entra administrator consents for your organisation to Atlantic’s Microsoft app. Your deployment asks LightHouse for an hour’s Graph token for your own tenant each time it reads; Atlantic holds its app’s certificate, never a token for you, and your messages never pass through LightHouse. Until Atlantic’s Microsoft app is registered, the button says it needs Atlantic’s Microsoft app. - **Your own app, by certificate**: an app registration in your own tenant with a certificate credential (never a client secret). Paste its tenant ID, client ID and the PEM of its private key and certificate; the page seals it in your browser to your deployment’s key. Channel messages are a Microsoft **protected API**: an app reads them only once Microsoft has approved it for that use. Atlantic’s app goes through that approval; for your own app, request it from Microsoft before you connect. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person. 1. Go to **Setup and admin → Connectors**. On the **Microsoft Teams** card, choose **Connect**. 2. Fill in **Teams**: the team IDs to read (a team’s ID is in **Get link to team** in Teams, as `groupId`). 3. Choose **Approve in Microsoft**, and sign in as an Entra administrator; or, for your own app, fill in **Directory (tenant) ID** and **Application (client) ID** and paste the PEM. 4. Choose **Connect**. Teams connections are **Read only**: LightHouse offers no write access for Teams. The level is on the card and in the audit log. Your deployment checks the credential from your account (`connector.check`) and reports the application permissions its token carries; one without **ChannelMessage.Read.All** is reported as missing a scope. ## Connect in code ```yaml - id: teams-operations purpose: Read the operations team's channels into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: teams teams: [0f3e1b6c-2a4d-4e5f-8a9b-1c2d3e4f5a6b] channels: [General, Incidents] # optional: by name; every channel otherwise label: standard credential_secret: requires: reads: [the operations team's channel messages and replies] reason: the operations agents answer from what the team has already said ``` ## Permissions Application permissions on Microsoft Graph: **ChannelMessage.Read.All**, **Channel.ReadBasic.All** and **Team.ReadBasic.All**. The engine calls, all `GET`, to `graph.microsoft.com`: the team, its channels, `/teams/{id}/channels/{id}/messages/delta` for what changed, and each thread’s replies. ## Where the credential is held As for [SharePoint and OneDrive](/connect/sharepoint/#where-the-credential-is-held): with Atlantic’s app, nothing secret, and an hour’s token minted by LightHouse for your tenant on your deployment’s signed request; with your own app, the certificate sealed to your deployment and kept in your own store, under `lighthouse/connectors/teams/`. ## What is indexed - **Threads**: a channel’s first message and its replies, in order, as one document, with the team, channel and sender. A reply is never indexed without its question. - **Never read:** chats, meeting chats, files shared in channels (connect [SharePoint](/connect/sharepoint/) for those) and system messages. - **How often:** on the card’s schedule, following each channel’s delta from the last pull. A thread is read again when it is edited or a reply is added. - **Deletions:** a message deleted in Teams leaves the corpus. A channel you take out of the configuration has its threads removed; a team the credential cannot see at the moment keeps them. ## Check it worked - The source’s run note: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `teams`. ## Removing it On the card, choose **Disconnect**; then remove Atlantic’s app under **Enterprise applications** in the Entra admin centre, or delete your own app’s certificate. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/teams/ --- # PostgreSQL > Connect PostgreSQL to LightHouse: the ways to connect, the read-only scopes, where the credential is held, and what is indexed. > **Coming:** > > The engine does not read PostgreSQL yet. LightHouse lists it in the connector catalogue as coming, and refuses a request to connect it with `409 connector_coming`. When it is built, this page will give the three ways to connect it, the exact read-only permissions it asks for, where its credential is held, what it indexes and how to check it worked, as the built connectors’ pages do. ## Until then - **Exports from PostgreSQL**, written to a folder as text, Markdown or PDF, can reach a knowledge base through the [folder connector](/connect/upload/). - **Your own connector** can register under the engine’s `aal_engine.connectors` entry point, in your own repository. See [In code](/build/code/). - To ask for it, contact Atlantic: [atlanticagenticlabs.com](https://atlanticagenticlabs.com/#contact). Source: https://docs.atlanticagenticlabs.com/connect/postgres/ --- # Snowflake > Connect Snowflake to LightHouse: the ways to connect, the read-only scopes, where the credential is held, and what is indexed. > **Coming:** > > The engine does not read Snowflake yet. LightHouse lists it in the connector catalogue as coming, and refuses a request to connect it with `409 connector_coming`. When it is built, this page will give the three ways to connect it, the exact read-only permissions it asks for, where its credential is held, what it indexes and how to check it worked, as the built connectors’ pages do. ## Until then - **Exports from Snowflake**, written to a folder as text, Markdown or PDF, can reach a knowledge base through the [folder connector](/connect/upload/). - **Your own connector** can register under the engine’s `aal_engine.connectors` entry point, in your own repository. See [In code](/build/code/). - To ask for it, contact Atlantic: [atlanticagenticlabs.com](https://atlanticagenticlabs.com/#contact). Source: https://docs.atlanticagenticlabs.com/connect/snowflake/ --- # HubSpot > Connect HubSpot to LightHouse: a private app's access token, the read scopes HubSpot states, where the credential is held, and what is indexed. The engine reads companies, contacts, deals and tickets from your HubSpot account into a knowledge base. HubSpot publishes no API for knowledge-base articles, so articles are not read. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | **Paste a private app’s access token** | Make a private app in HubSpot (**Settings → Integrations → Private apps**) with the read scopes below, and paste its access token (`pat-`) | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **HubSpot** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `objects` (companies, contacts, deals, tickets) and, if you want links back to HubSpot, `portal_id`. 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste the private app’s access token. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: hubspot-knowledge purpose: Read HubSpot into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: hubspot objects: [companies, deals, tickets] properties: # optional: the properties read, per object tickets: [subject, content, hs_pipeline_stage] portal_id: 1234567 # optional: links each record to HubSpot label: internal credential_secret: requires: reads: [hubspot:companies, deals and tickets] reason: the service agents answer from the account and ticket history ``` ## Scopes - **Read only**: `crm.objects.companies.read`, `crm.objects.contacts.read`, `crm.objects.deals.read` and `tickets`, for the objects you name. - **Read and write**: the matching `.write` scopes, for agents that write through approved cards. - **The health check**: HubSpot states a private app’s scopes (its token-information endpoint), and your deployment reports them. Any `.write` scope on a connection chosen as **Read only** marks it failing with a warning to narrow the token. - **One host**: every call goes to `api.hubapi.com`. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect hubspot --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/hubspot/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Companies, contacts, deals and tickets**: the properties named, with sensible ones by default. A contact is read for the business record only: not every property your portal holds about a person. - **How often, and what is read each time**: on the card’s schedule. Each pull searches for records whose `hs_lastmodifieddate` is after the cursor, in order. HubSpot’s search answers at most 10,000 results to one query, so a large first pull starts again from the newest change it has read and carries on. - **Deletions**: every six hours the ids are listed and an archived record is removed. - **Rate limits**: the search API’s per-second limit is respected by pacing, and a `429` waits as long as HubSpot asks. - **Never read**: the knowledge base (HubSpot has no API for it), emails, files and engagements. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `hubspot`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Rotate or delete the token on the private app’s **Auth** tab in HubSpot. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/hubspot/ --- # monday.com > Connect monday.com to LightHouse: an API token, the boards it reads, where the credential is held, and what is indexed. The engine reads the items, column values and updates on the boards you name into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | **Paste an API token** | Paste an API token, ideally an integration account’s that has been added only to the boards named, and name the boards by id | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **monday.com** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `boards` (board ids, separated by commas). 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste the API token. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: monday-knowledge purpose: Read monday.com into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: monday boards: ["1234567890"] # board ids, named; never a whole account updates: 20 # the latest updates read with each item label: internal credential_secret: requires: reads: [monday:the delivery board's items and their updates] reason: the delivery agents answer from the project's own tracker ``` ## Permissions - monday.com does not state a token’s permissions: a token carries its user’s own. That is why the boards are named, and why an integration account that sees only those boards is the right one to make it on. - **Read and write** is recorded as your administrator’s choice, for agents that write through approved cards. - **The health check**: your deployment asks who the token belongs to. The card says monday.com did not state the permissions. - **One host**: `api.monday.com`. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect monday --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/monday/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Items** on the boards named: their group, column values and latest updates, one document per item. - **How often, and what is read each time**: on the card’s schedule. monday.com filters items by column, not by when they changed, so each named board is read whole on every pull (100 items a page), and only items whose `updated_at` is after the cursor are written. An unchanged board writes nothing. - **Deletions**: a whole read is also the deletion check: an item no longer on the board is removed on the same pull. - **Rate limits**: monday.com’s complexity budget. A query over budget waits the seconds monday.com names (up to a minute, three times) and asks again; it fails rather than write part of a board. - **Never read**: boards you do not name, files, and docs. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `monday`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Regenerate the token in monday.com (**Developers → My access tokens**). Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/monday/ --- # Zendesk > Connect Zendesk to LightHouse: an agent's API token, what it reads, where the credential is held, and what is indexed. The engine reads tickets with their comments, and Help Centre articles, from your Zendesk into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Paste an agent’s email and API token** | Make an API token in **Admin Center → Apps and integrations → APIs → Zendesk API**, and paste the agent’s email address and the token (two lines). Name your subdomain | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Zendesk** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `subdomain` (the `` of `.zendesk.com`) and `objects` (tickets, articles). 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste two lines: the agent’s email address, then the API token. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: zendesk-knowledge purpose: Read Zendesk into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: zendesk objects: [tickets, articles] comments: true # a ticket's comments and internal notes label: internal credential_secret: requires: reads: [zendesk:tickets with their comments, and published articles] reason: the service agents answer from past tickets and the help centre ``` ## Permissions - Zendesk states no scope for an API token: it acts as its agent. Make it on an agent whose groups are the ones the source should read. - **Read and write** is recorded as your administrator’s choice, for agents that write through approved cards. - **The health check**: your deployment asks who the token belongs to; Zendesk answers an anonymous user to a token it did not accept, so a missing id fails the check. The card says Zendesk did not state the permissions. - **One host**: `https://.zendesk.com`, sealed with the credential. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect zendesk --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/zendesk/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Tickets**, with their comments and internal notes, each marked as which. **Articles** from the Help Centre, as text; drafts are not read. - **How often, and what is read each time**: on the card’s schedule. Tickets changed after the cursor come from Zendesk’s search export, which an agent may use (the incremental export is for administrators only). The search is indexed a little after a change, so the query starts five minutes before the cursor and anything not newer is dropped. Articles come newest first, stopping at the first that is not newer. - **Deletions**: every six hours the ids are listed and a deleted ticket or archived article is removed. - **Rate limits**: requests are paced; a `429` waits as long as Zendesk asks. - **Never read**: attachments, users’ profiles and other Zendesk products. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `zendesk`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Delete the token in **Admin Center → Apps and integrations → APIs → Zendesk API**. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/zendesk/ --- # Notion > Connect Notion to LightHouse: an internal integration's secret, the pages shared with it, where the credential is held, and what is indexed. The engine reads the pages and database rows shared with your integration into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Paste an internal integration’s secret** | Make an internal integration in your workspace with **Read content** only, share the pages and databases it may read with it, and paste its secret (`ntn_`) | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Notion** (search for it, or filter by its family), and choose **Connect**. 2. Fill in optionally `databases` (ids, to read only those databases’ rows). 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste the integration’s secret. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: notion-knowledge purpose: Read Notion into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: notion databases: [] # optional: only these databases' rows label: internal credential_secret: requires: reads: [notion:the pages and databases shared with the integration] reason: the agents answer from the team's own wiki ``` ## Capabilities - **Read only**: the integration’s **Read content** capability. Only what someone shares with the integration is read: sharing a page with it is the decision to let the agents read it. - **Read and write**: give the integration **Update content** and **Insert content**, for agents that write through approved cards. - **The health check**: your deployment asks Notion for the integration’s own bot user. Notion does not state an integration’s capabilities, so the card says the sharing decides. - **One host**: `api.notion.com`. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect notion --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/notion/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Pages** shared with the integration, with their text to three levels of nesting, and **database rows** with their properties. A child page is a document of its own. - **How often, and what is read each time**: on the card’s schedule. Each pull searches for pages newest first, stopping at the first whose `last_edited_time` is not after the cursor. - **Deletions**: every six hours every shared page’s id is listed; a page moved to the trash, archived or no longer shared is removed. - **Rate limits**: Notion allows about three requests a second. The source paces itself to that, and a `429` waits as long as Notion asks. - **Never read**: pages not shared with the integration, comments and files. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `notion`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Delete the integration in Notion (**Settings → Connections → Develop or manage integrations**), or stop sharing pages with it. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/notion/ --- # Dynamics 365 > Connect Microsoft Dynamics 365 to LightHouse: your own Entra app by certificate as a Dataverse application user, what it reads, where the credential is held, and what is indexed. The engine reads accounts, opportunities and cases from a Dataverse environment into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Connect your own Microsoft app by certificate** | The same kind of app as SharePoint’s own-app route: an app registration in your Entra tenant with a certificate. In the Power Platform admin centre, make it an **application user** of the environment with a read-only security role over these three tables. Paste the PEM of the key and its certificate | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Dynamics 365** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `tenant_id`, `client_id`, `environment_url` (`https://.crm.dynamics.com`) and `objects`. 3. Under **What agents may do with it**, keep **Read only** unless your agents are to write through approved cards. 4. Paste the PEM of your app’s private key and its certificate. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: dynamics-knowledge purpose: Read Dynamics 365 into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: dynamics objects: [accounts, opportunities, cases] label: internal credential_secret: requires: reads: [dynamics:accounts, opportunities and cases] reason: the service agents answer from the account and case history ``` ## Permissions - **The token** is for your environment alone (`/.default`), minted from an assertion your deployment signs with the certificate. No client secret is accepted. - **Read only is the application user’s security role.** Dataverse states no permissions in the token, so the access level is your administrator’s choice and the card says so. - **The health check**: your deployment mints the token and calls `WhoAmI`, which answers only once the app is an application user of the environment. - **One host**: your environment’s address, sealed with the credential. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect dynamics --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/dynamics/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Accounts, opportunities and cases**: the columns that describe them, with lookups by their names. - **How often, and what is read each time**: on the card’s schedule. Each pull reads rows whose `modifiedon` is after the cursor, in order, 500 a page. - **Deletions**: every six hours the ids are listed and a row that has gone is removed. - **Rate limits**: Dataverse’s service protection limits; a `429` waits as long as Dataverse asks. - **Never read**: notes, attachments, activities and tables you do not name. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `dynamics`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Deactivate the application user in the Power Platform admin centre, and remove the certificate under **App registrations** in Entra. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/dynamics/ --- # Oracle Database > Connect Oracle Database to LightHouse: your own read-only database user, the privileges it holds, where the credential is held, and what is indexed. The engine reads the tables and views you name, in place, from your own database, through a read-only user, into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Give a read-only database user** | Make a user with `CREATE SESSION` and `SELECT` on the named tables and views, and nothing else. Paste three lines: the connect string (`host:port/service_name`), the user and its password | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Oracle Database** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `tables`. 3. The connection is **Read only**: this connector offers no other level. 4. Paste three lines: the connect string, the user, then its password. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: oracle-db-knowledge purpose: Read Oracle Database into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: oracle-db tables: - table: SUPPORT.KNOWN_ISSUES key: ISSUE_ID updated: LAST_UPDATED # optional: read whole on every pull without it title: SUMMARY # optional columns: [SUMMARY, FLEET, WORKAROUND, STATUS] # optional: every column otherwise label: internal credential_secret: requires: reads: [oracle-db:SUPPORT.KNOWN_ISSUES] reason: the engineering agents answer from the known-issues register ``` ## Privileges - **Read only, always**: `CREATE SESSION` and `SELECT` on the named objects. Read and write is not offered. - **Only `SELECT` is ever run**, in a read-only transaction. Every name is checked and quoted, and every value is a bind variable. - **The health check**: your deployment connects and asks the database for the session’s privileges. They are the card’s scopes, and any privilege beyond reading is flagged: a connection whose user could change the database is marked failing. - **Where it connects**: from your deployment, in your network, with python-oracledb in thin mode (the engine’s `oracle` extra; no Oracle Instant Client). ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect oracle-db --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/oracle-db/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Rows** of the tables and views named, one document per row, with the columns named. - **How often, and what is read each time**: on the card’s schedule. With an `updated` column, each pull reads rows later than the cursor (less a five-minute margin for long transactions), in order. Without one, the table is read whole on every pull and only rows that changed are written. - **Deletions**: every six hours the keys are listed and a row that has gone is removed. A table the user can no longer see keeps its rows until it can be listed again. - **Large values**: a LOB is read as text up to a cap; binary values are never written. - **Never read**: tables and views you do not name. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `oracle-db`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Lock or drop the user, as the database’s administrator (`ALTER USER ACCOUNT LOCK`). Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/oracle-db/ --- # NetSuite > Connect NetSuite to LightHouse: OAuth 2.0 client credentials (machine to machine) with your certificate, the scope it asks for, where the credential is held, and what is indexed. The engine reads customers, transactions, items and support cases from your NetSuite account, by SuiteQL, into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Connect by OAuth 2.0 certificate (M2M)** | Make an integration record with the client-credentials grant, generate a certificate and upload it under **Setup → Integration → OAuth 2.0 Client Credentials (M2M) Setup**, mapped to a role that only views. Paste three lines: the client id, the certificate id NetSuite gave, then the PEM of the certificate’s private key. Never a password, and never a token-based-authentication secret pair | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **NetSuite** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `account_id` (such as `1234567`, or `1234567_SB1` for a sandbox) and `objects`. 3. The connection is **Read only**: this connector offers no other level. 4. Paste three lines: the client id, the certificate id, then the PEM of the private key. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: netsuite-knowledge purpose: Read NetSuite into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: netsuite objects: [customers, transactions, items, cases] label: internal credential_secret: requires: reads: [netsuite:customers, transactions, items and support cases] reason: the finance agents answer from the ledger and the case history ``` ## Scope - **Read only, always**: the `rest_webservices` scope, with a mapped role that has view permission on the records named and nothing that creates or edits. Read and write is not offered. - **The health check**: your deployment signs a five-minute assertion with the key, gets an hour’s token and reads one customer id. NetSuite states the token’s scope, and the card shows it. - **One host**: `.suitetalk.api.netsuite.com`, made from the sealed account id. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect netsuite --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/netsuite/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Customers, transactions, items and support cases**: the business record’s columns. A customer’s email and phone are not read. - **How often, and what is read each time**: on the card’s schedule. Each pull reads records whose `lastmodifieddate` is after the cursor. NetSuite gives that date in the account’s time zone with no offset, so the query starts a day before the cursor and anything not newer is dropped. A first pull past SuiteQL’s 100,000-row paging limit starts again from the newest time it read. - **Deletions**: every six hours the ids are listed and a record that has gone is removed. - **Rate limits**: NetSuite’s concurrency limits; requests are sequential and a `429` waits as long as NetSuite asks. - **Never read**: records you do not name, files and saved searches. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `netsuite`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke the certificate’s mapping in **OAuth 2.0 Client Credentials (M2M) Setup** in NetSuite. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/netsuite/ --- # Oracle Fusion Cloud Applications > Connect Oracle Fusion Cloud Applications (ERP, HCM, SCM) to LightHouse: a JWT assertion with your certificate for a read-only integration user, where the credential is held, and what is indexed. The engine reads the REST resources you name in Fusion ERP, HCM and SCM into a knowledge base. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The records are not transmitted, and LightHouse does not open the credential. ## The way to connect | Way | What you do | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Connect by JWT assertion with your certificate** | Upload your certificate in the Security Console under **API Authentication** as an inbound certificate with a trusted issuer name. Make an integration user with the view duties of the resources named. Paste the PEM of the private key and its certificate | ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Go to **Setup and admin → Connectors**, find **Oracle Fusion Cloud Applications** (search for it, or filter by its family), and choose **Connect**. 2. Fill in `pod_url` (`https://.fa..oraclecloud.com`), `issuer`, `username` and `resources`. 3. The connection is **Read only**: this connector offers no other level. 4. Paste the PEM of the private key and its certificate. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it at the provider. The card shows the result. ## Connect in code ```yaml - id: oracle-fusion-knowledge purpose: Read Oracle Fusion Cloud Applications into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops-lead@example.com budget_usd: 0 effect: internal source: kind: oracle-fusion resources: - path: fscmRestApi/resources/11.13.18.05/invoices key: InvoiceId updated: LastUpdateDate # the default title: InvoiceNumber # optional fields: [InvoiceNumber, Supplier, InvoiceAmount, InvoiceCurrency, Description] label: internal credential_secret: requires: reads: [oracle-fusion:payables invoices] reason: the finance agents answer from the invoice history ``` ## Permissions - **Read only, always**: the integration user’s view duties for the resources named. Read and write is not offered. - **The assertion is the bearer token**: Fusion’s inbound JWT authentication takes the signed assertion itself, valid ten minutes and signed again before it lapses. No password, no client secret, no token exchange. - **The health check**: your deployment reads one record. Fusion does not state a user’s roles to it, so the card says the check read one resource and the roles were not stated. - **One host**: your pod, sealed with the credential. A resource path is held to `fscmRestApi`, `hcmRestApi` or `crmRestApi`. ## Where the credential is held LightHouse never opens this credential. It is sealed in your browser, or by `lighthouse-ai connect oracle-fusion --credential-stdin`, to your deployment’s own key, and your deployment keeps it in your own secrets store under `lighthouse/connectors/oracle-fusion/`. A request that sends it to LightHouse unsealed is refused with `422 sealing_required`. LightHouse keeps the connection’s fingerprint, the access level, the scopes the provider states and when it was checked: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## What is indexed - **Records** of the resources named, with the fields named. - **How often, and what is read each time**: on the card’s schedule. Each pull reads records whose `LastUpdateDate` (or the field named) is after the cursor, in order, paged while Fusion says there is more. - **Deletions**: every six hours the keys are listed and a record that has gone is removed. - **Rate limits**: requests are paced; a `429` waits as long as Fusion asks. - **Never read**: resources you do not name, and attachments. ## Check it worked - The source’s run note in your deployment: `written N, unchanged N, quarantined N, removed N`. - **Agents → Knowledge**: documents from `oracle-fusion`. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts only; the records are not transmitted. ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Delete the inbound certificate in the Security Console, and make the integration user inactive. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/oracle-fusion/ --- # Digital assets > Connect Fireblocks, Dfns, Coinbase Prime, Kraken or Binance to LightHouse, read-only: the view-only key to make, the fields to name, and what the health codes mean. The engine reads balances, transfers and trade history from your custody provider or exchange into a knowledge base, for treasury and reconciliation agents. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. Balances and transactions are not transmitted, and LightHouse does not open the credential. ## Read-only, always These connectors only read. LightHouse never holds a credential that can move money, so **read and write is refused** for every one of them: make a view-only key and connect it as **Read**. Your deployment asks the provider what the key may do before every read. A key that can withdraw, transfer, sign, trade or approve payments is refused, naming the permission, and nothing is read with it. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Make a view-only key at the provider, as the section for your provider below describes. Pin it to your deployment’s egress addresses where the provider offers an allowlist. 2. Go to **Setup and admin → Connectors**, find the provider (search for it, or filter by **Digital assets**), and choose **Connect**. 3. Name the fields listed for the provider, and leave the access level at **Read**. 4. Paste the key. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it, checks what it may do at the provider, and the card shows the result. ## What the health codes mean | Code | The card says | What to do | | --------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `write_capable` | The key can withdraw, transfer, sign or trade: refused, nothing is read | Make a view-only key at the provider (no withdraw, transfer, sign or trade permission), pin it to your deployment’s egress addresses, and connect it again | | `unverified` | The provider does not state the key’s permissions and it was not confirmed view-only | Check at the provider that the key only reads, then connect it again with **View-only confirmed** set to yes | | `auth_failed` | The provider refused the key | It may have expired or been revoked. Make a new one and connect it again | Coinbase Prime does not state a key’s permissions, so it always needs **View-only confirmed**. Fireblocks does not tell a key its own role: an administrator’s key is refused, and you confirm the rest is a Viewer. []() ## Fireblocks - **Reads**: vault accounts, asset balances (total, available, pending, frozen, locked) and transactions. - **Make**: an API user with the **Viewer** role. - **Paste**: the API user’s key on the first line, then the PEM of the private key of its CSR. Requests are signed in your deployment. - **Name**: **Workspace region** (US, EU, EU2 or the sandbox) and **View-only confirmed**. []() ## Dfns - **Reads**: wallets, balances and transfers. - **Make**: a service account with a read-only role (`Wallets:Read`, `Wallets:Transfers:Read`). - **Paste**: the service account’s token. - **Name**: **Region**, and optionally **Service account ID**. Dfns states the account’s permissions; one that can create transfers or transactions, or sign or export keys, is refused, named. []() ## Coinbase Prime - **Reads**: portfolios, balances, orders, fills and transactions. - **Make**: an API key with the **Read** permission only. - **Paste**: three lines: the access key, the passphrase, then the signing key. - **Name**: **View-only confirmed**, once you have checked the key. []() ## Kraken - **Reads**: balances, ledger entries and trade history. - **Make**: an API key with **Query Funds**, **Query Ledger Entries** and **Query Closed Orders & Trades** only, and an IP allowlist. - **Paste**: two lines: the API key, then its private key. - **Name**: nothing beyond **View-only confirmed**; Kraken states the key’s permissions, and one that can withdraw or trade is refused, named. []() ## Binance - **Reads**: spot and margin balances, trades, deposits and withdrawals. Futures are not read: Binance requires a trading permission for them. - **Make**: an API key with **Enable Reading** only (Ed25519 recommended), restricted to your deployment’s addresses. - **Paste**: the API key on the first line, then its HMAC secret, or the PEM of its Ed25519 private key. - **Name**: **Environment** (production, or the spot testnet; the testnet does not state a key’s restrictions, so it needs **View-only confirmed**). Binance states the key’s restrictions; one with withdrawals, transfers or trading enabled is refused, named. ## Where the credential is held LightHouse never opens these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, when it was checked and the check’s code: never the key, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Delete the key at the provider too. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/digital-assets/ --- # Banking and payments > Connect bank statement files, Revolut Business or Stripe to LightHouse, read-only: what to paste, the fields to name, and what the health codes mean. The engine reads bank statements, Revolut Business accounts and Stripe balances into a knowledge base, for cash, finance and reconciliation agents. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The transactions are not transmitted, and LightHouse does not open the credential. ## Read-only, always These connectors only read, and **read and write is refused**: connect them as **Read**. Where the provider states a key’s permissions, a key that can withdraw, transfer, sign, trade or approve payments is refused as `write_capable`, naming the permission, and nothing is read with it. Where it does not, the key is `unverified` until you confirm it only reads. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Make the credential at the provider, as the section below describes. 2. Go to **Setup and admin → Connectors**, find the provider (search for it, or filter by family), and choose **Connect**. 3. Name the fields listed, and leave the access level at **Read**. 4. Paste the credential. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it. The card shows the result. ## What the health codes mean | Code | The card says | What to do | | --------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- | | `write_capable` | The key can withdraw, transfer, sign or trade: refused, nothing is read | Make a view-only key at the provider, pin it to your deployment’s egress addresses, and connect it again | | `unverified` | The provider does not state the key’s permissions and it was not confirmed view-only | Check that it only reads, then connect it again with **View-only confirmed** set to yes | | `auth_failed` | The provider refused it | It may have expired or been revoked. Make a new one and connect it again | []() ## Bank statements - **Reads**: camt.053, camt.052, MT940 and MT950 statements from any bank, and MT535 statements of holdings from any custodian, from your SFTP drop. A statement file cannot move money, trade, instruct or approve, so there is no permission to check. - **Paste**: two lines: the server’s host key fingerprint (`SHA256:...`), then the PEM of the drop account’s private key. The host key is pinned. - **Name**: **SFTP drop**, where your bank or custodian delivers the files. - **A drop in a bucket** is read by your deployment’s own role, set up by your engineer. []() ## Revolut Business - **Reads**: accounts, balances, transactions, counterparties, expenses, FX rates and cards (never card numbers). - **Make**: your own Business API certificate. Upload its public key in Revolut Business (**Settings, APIs**) and consent with the **READ** scope only. - **Paste**: the client ID, then the one-off authorisation code (or a refresh token), then the PEM of the certificate’s private key. - **Name**: **Redirect domain** (the domain you gave Revolut with the certificate), **What you paste second**, **Environment** (production or sandbox) and **View-only confirmed**. - Where Revolut states the consent’s scope, `WRITE`, `PAY` and `READ_SENSITIVE_CARD_DATA` are refused, named. If Revolut ends the consent, connect again. []() ## Stripe - **Reads**: your balance and every balance transaction. - **Make**: a restricted key (`rk_`) with **Read** on **Balance** only, restricted to your deployment’s addresses. A secret key (`sk_`) is refused: it can move money. - **Paste**: the restricted key. - **Name**: **View-only confirmed**; Stripe does not state a restricted key’s permissions. ## Where the credential is held LightHouse never opens these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, when it was checked and the check’s code: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke it at the provider too. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/banking-and-payments/ --- # Accounting and treasury > Connect Xero, QuickBooks Online or Kyriba to LightHouse, read-only: your own app or API client, the fields to name, and what the health codes mean. The engine reads your accounting and treasury systems into a knowledge base, for finance and treasury agents, using your own app or API client. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The ledgers are not transmitted, and LightHouse does not open the credential. ## Read-only, always These connectors only read, and **read and write is refused**: connect them as **Read**. Where the provider states a credential’s permissions, one that can write is refused, named. Where it does not, you confirm it only reads. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Make the app or API client at the provider, as the section below describes. 2. Go to **Setup and admin → Connectors**, find the provider (search for it, or filter by family), and choose **Connect**. 3. Name the fields listed, and leave the access level at **Read**. 4. Paste the credential. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it. The card shows the result. ## What the health codes mean | Code | The card says | What to do | | --------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- | | `write_capable` | The key can withdraw, transfer, sign or trade: refused, nothing is read | Make a view-only key at the provider, pin it to your deployment’s egress addresses, and connect it again | | `unverified` | The provider does not state the key’s permissions and it was not confirmed view-only | Check that it only reads, then connect it again with **View-only confirmed** set to yes | | `scope_missing` | A granted scope writes, or a needed one is missing (Xero names it) | Make the app with the read scopes listed, and connect it again | | `auth_failed` | The provider refused it | It may have expired or been revoked. Make a new one and connect it again | []() ## Xero - **Reads**: organisations, chart of accounts, contacts, invoices and bills, bank transactions, payments, manual journals, and the profit and loss, balance sheet and aged receivables and payables reports. - **Make**: your own Xero app with read scopes only: `accounting.settings.read`, `accounting.contacts.read`, `accounting.invoices.read`, `accounting.payments.read`, `accounting.banktransactions.read`, `accounting.manualjournals.read`, `accounting.reports.profitandloss.read`, `accounting.reports.balancesheet.read` and `accounting.reports.aged.read`. Either consent it, or make it a custom connection. - **Paste**: the app’s client ID and client secret, and, for an app you consented to, its refresh token on a third line. The refresh token is rotated and written back to your own store at once. - A scope that writes is named by the check, and nothing is ever written. []() ## QuickBooks Online - **Reads**: company, accounts, customers, vendors, invoices, bills, payments, journal entries and reports. - **Make**: your own Intuit app and its consent. Intuit’s accounting scope (`com.intuit.quickbooks.accounting`) is not split into read and write; this connector only reads, and nothing is ever written. - **Paste**: three lines: the client ID, the client secret, then the consent’s refresh token. Intuit rotates it; your deployment writes the new one back to your own store. - **Name**: **Company ID** (the realm ID, digits) and **Environment** (production or an Intuit sandbox company). []() ## Kyriba - **Reads**: bank accounts, balances, cash positions and forecasts, cash flows, payment status and third parties. - **Make**: an API client by client credentials, with read permissions only: no payment initiation, transfer or approval. - **Paste**: two lines: the API client’s ID, then its secret. - **Name**: **Kyriba sign-in address**, **Kyriba API address** and **View-only confirmed**. Kyriba does not state an API client’s permissions, so you confirm it. ## Where the credential is held LightHouse never opens these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, when it was checked and the check’s code: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke the app or client at the provider too. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/accounting-and-treasury/ --- # Flight data and bookings > Connect Amadeus, FlightAware, Cirium, OAG, SITA or Sabre to LightHouse, read-only: what to paste, the fields to name, and which passenger data is left out by default. The engine reads flight status, schedules, baggage and bookings from your data providers into a knowledge base, for operations, disruption, customer and ground agents. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. Flight and passenger records are not transmitted, and LightHouse does not open the credential. ## Read-only, and what is left out Aviation connectors never book, change, cancel or file anything, so **read and write is refused**: connect them as **Read**. Passenger personal data stays in your deployment. By default these are left out: - travel document numbers; - dates of birth; - health and disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Get the key from the provider, as the section below describes. 2. Go to **Setup and admin → Connectors**, find the provider (search for it, or filter by **Aviation** or **Amadeus**), and choose **Connect**. 3. Name the fields listed, and leave the access level at **Read**. 4. Paste the key. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it. The card shows the result. ## What the health codes mean | Code | The card says | What to do | | --------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | `scope_missing` | The token signs in, but a scope it carries writes (the scopes are named) | Make a credential with read scopes only, and connect it again | | `auth_failed` | The provider refused it | It may have expired or been revoked. Make a new one and connect it again | []() ## Amadeus - **Reads**: flight status for the flights you name, airline and airport reference data, and flight orders by id. - **Make**: the API key and secret your Amadeus account manager issued (client credentials). Self-service keys closed on 17 July 2026; enterprise keys reach the same endpoints. - **Paste**: two lines: the API key, then its secret. - **Name**: **Environment**, Amadeus’s test host or production. - Altéa reservations, departure control, inventory and schedules, and NDC orders are [Needs onboarding](/connect/#connectors): our certified forward-deployed engineers map them from your licensed reference. []() ## FlightAware AeroAPI - **Reads**: your operator’s and airports’ flights: schedule, gates, delays, diversions and cancellations. - **Paste**: an AeroAPI key. []() ## Cirium FlightStats - **Reads**: flight status by airport and by flight. - **Paste**: two lines: the application ID, then its key. []() ## OAG Flight Info - **Reads**: flight instances by departure airport and date. - **Paste**: your OAG subscription key. []() ## SITA Flight Status - **Reads**: flight status at your airports, kept current from SITA’s change feed. - **Paste**: the API key from developer.aero. For OAuth, add the client ID and the client secret on a second and third line. []() ## SITA BagJourney - **Reads**: bags per flight with their loading status. - **Paste**: the BagJourney API key from developer.aero. BagJourney has no read without a flight, so your deployment checks the key at the first sync. []() ## Sabre - **Reads**: bookings by confirmation id. Travel documents are left out, and only the booking’s traveller count is read. - **Make**: Sabre’s client credentials. - **Paste**: two lines: the EPR credential (`V1:user:group:domain`), then its password. - **Name**: **Environment**, Sabre’s certification host or production. ## Where the credential is held LightHouse never opens these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, when it was checked and the check’s code: never the key, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke the key at the provider too. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/flight-data/ --- # Aviation safety and training > Connect ECCAIRS 2, Q-Pulse, Intelex, xAPI learning records, flight data monitoring exports or training exports to LightHouse, read-only, with reporters' identities left out. The engine reads occurrence reports, quality records, training records and flight data monitoring exports into a knowledge base, for safety, quality and training agents. Audit-ready: reporters’ identities are left out. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. The reports are not transmitted, and LightHouse does not open the credential. ## Read-only, and what is left out These connectors never file, change or close anything, so **read and write is refused**: connect them as **Read**. By default these are left out: - reporters’ names; - everyone’s email addresses, phone numbers and contact details; - travel document numbers, dates of birth, and health and disability special service requests. ## Connect in LightHouse You need the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Make the credential at the system, as the section below describes. 2. Go to **Setup and admin → Connectors**, find the system (search for it, or filter by **Aviation safety and compliance**), and choose **Connect**. 3. Name the fields listed, and leave the access level at **Read**. 4. Paste the credential. Your browser seals it to your deployment; LightHouse never sees it. 5. Your deployment keeps it and checks it. The card shows the result. ## What the health codes mean | Code | The card says | What to do | | --------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | `scope_missing` | The credential signs in, but a scope it carries writes (the scopes are named) | Make a credential with read scopes only, and connect it again | | `auth_failed` | The system refused it | It may have expired or been revoked. Make a new one and connect it again | []() ## ECCAIRS 2 - **Reads**: your organisation’s occurrence reports from EASA’s E2. - **Make**: the E2 API client ID and secret EASA issued (client credentials, as EASA’s 2026 change requires). EASA allow-lists your deployment’s address. - **Paste**: two lines: the client ID, then its secret. - **Name**: **E2 sign-in address**, only if EASA gave you one; otherwise E2’s own is used. []() ## Ideagen Q-Pulse - **Reads**: occurrences with their data fields. - **Make**: an integration user of Q-Pulse’s web services, over https. - **Paste**: two lines: the integration user, then its password. - **Name**: **Q-Pulse web services** (the https address) and **Database**. Q-Pulse signs in by a SOAP envelope, so your deployment checks it at the first sync. []() ## Intelex - **Reads**: incidents, audits, findings and actions from the objects you name. - **Make**: an integration user and its API key. - **Paste**: the API key. - **Name**: **Your Intelex**, the address of your Intelex. []() ## xAPI learning records - **Reads**: training statements from your Learning Record Store (xAPI 1.0.3 or 2.0). - **Make**: a read-only key and secret. - **Paste**: two lines: the LRS key, then its secret. - **Name**: **LRS endpoint**, your Learning Record Store’s xAPI endpoint. []() ## Flight data monitoring exports - **Reads**: event and exceedance exports from your FDM or FOQA tool, row by row, from a bucket prefix or an SFTP drop. - **No credential is pasted.** Your deployment reads the export location your engineer names, as its own identity or a role, so your engineer sets this one up in your source card ([In code](/build/code/)). []() ## Training exports - **Reads**: training records exported by your LMS, row by row, from a bucket prefix or a drop folder. - **No credential is pasted.** As with flight data monitoring exports, your engineer names the export location. ## Where the credential is held LightHouse never opens these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, when it was checked and the check’s code: never the credential, and never what it reads. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke it at the system too. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/aviation-safety/ --- # ERP and HR > Connect SAP S/4HANA, SAP SuccessFactors or Workday to LightHouse, read-only: the client or user to create, the fields to name, what is left out and what the health codes mean. The engine reads organisation, job and ledger records from SAP S/4HANA, SAP SuccessFactors and Workday into a knowledge base, for finance, supply and workforce planning agents. Content is read in place, in your deployment, in your own account. LightHouse receives ids, hashes and counts only. It does not receive the records, and it does not open the credential. ## Read-only These connectors only read. **Read and write is refused** (`422 read_only_connector`) in the API, in LightHouse and in the CLI, and the engine refuses it as well. Connect them as **Read**. The deployment makes GET requests only. ## What is left out No object these connectors read in this release holds the records below. As a final guard, the deployment also drops every field and report column whose name matches its personal-data deny-list, and records only how many it dropped (`dropped_columns`). | Connector | Left out | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | SAP S/4HANA | Individuals’ records (business partners who are people, employees, contacts, addresses); payroll and employee cost postings; bank details and tax ids | | SAP SuccessFactors, Workday | Employee records (names, national ids, dates of birth, home addresses); pay and benefits (compensation, payroll, bank details, tax ids); health, disability and diversity data; performance and disciplinary records | ## Connect in LightHouse Requires the **Client administrator** (`client_admin`) role, signed in as a person, and a deployment whose engine reads this connector ([compatibility reference](/concepts/telemetry-contract/#compatibility-reference)) and keeps credentials in your own store. 1. Create the client or user at the provider, as described for each provider below. 2. Go to **Setup and admin → Connectors**, find the provider (search for it, or filter by family), and choose **Connect**. 3. Enter the fields listed for the provider, and leave the access level at **Read**. 4. Paste the credential. Your browser seals it to your deployment’s key; LightHouse does not see it. 5. Your deployment stores the credential and checks it. The card shows the result of the check. The same connection can be made with `lighthouse-ai connect --credential-stdin`, which seals the credential on your machine. ## What the health codes mean | Code | Meaning | Action | | --------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------- | | `ok` | The credential signs in and reads | None | | `auth_failed` | The provider refused the credential | Create a new client or user, or a new refresh token, and connect again | | `unreachable` | The API host or token host did not answer | Check the host names and your deployment’s outbound access to them | | `scope_missing` | The client or user lacks read on the service the check uses | Grant read on the services listed for the provider, and connect again | []() ## SAP S/4HANA - **Reads**: sales and purchase orders, supplier invoices, material documents, products, journal entries, cost centres and organisations, through SAP’s released OData services. - **Create**: a communication arrangement in S/4HANA with read-only OData services, signed in either by an OAuth 2.0 client (client credentials) or by a communication user (HTTP Basic). - **Paste**: two lines. For OAuth, the client ID, then its secret. For a communication user, the user, then its password. - **Name**: **Your S/4HANA API host** (`https://`), **How it signs in** (OAuth 2.0 client, the default, or communication user), **Token URL** (OAuth only) and **What to read**: any of `sales_orders`, `purchase_orders`, `supplier_invoices`, `material_documents`, `products`, `journal_entries`, `cost_centres` and `business_partners` (organisations only). - **Hosts contacted**: the API host, and the token host where there is one. Redirects are not followed. []() ## SAP SuccessFactors - **Reads**: departments, locations, job codes, positions and job requisitions. Employee records and pay are not read. - **Create**: an OAuth 2.0 client (client credentials) registered in your SuccessFactors tenant, with read on the organisation and recruiting objects only. SAML bearer and HTTP Basic are not supported. - **Paste**: two lines: the client ID, then its secret. - **Name**: **Your API host** (your data centre’s API host, such as `https://api4.successfactors.com`), **Company ID**, **Token URL** and **What to read**: any of `departments`, `locations`, `job_codes`, `positions` and `job_requisitions`. []() ## Workday - **Reads**: supervisory and cost-centre organisations, job profiles, locations, job requisitions, and the reports you name. Workers and pay are not read. - **Create**: an API Client for Integrations with a refresh token, limited to the organisation and recruiting functional areas and to the reports you share with it. - **Paste**: three lines: the client ID, its secret, then the refresh token. - **Name**: **Your Workday host** (`*.workday.com` or `*.myworkday.com`, without `https://`), **Tenant**, **What to read** (any of `organisations`, `job_profiles`, `locations` and `job_requisitions`) and **Reports** (`owner/report`, comma separated, up to 20). Report columns whose names match personal data are dropped and counted. ## Where the credential is held LightHouse does not open these credentials. They are sealed in your browser, or by `lighthouse-ai connect --credential-stdin`, to your deployment’s own key, and your deployment keeps them in your own secrets store. LightHouse keeps the connection’s fingerprint, the access level, the time of the last check and its code. It does not keep the credential or the records read. See [Where every credential is held](/connect/#where-every-credential-is-held). ## Removing it On the card, choose **Disconnect**. Your deployment deletes the credential from your store. Revoke the client, user or refresh token at the provider as well. Documents already written stay in the knowledge base until you delete them. The collectors behind these connectors are in the [collectors catalogue](/collectors/catalogue/), with their certification status. Source: https://docs.atlanticagenticlabs.com/connect/erp-and-hr/ --- # Upload files > Upload files through LightHouse straight into your own deployment's store, from the portal, the CLI or the API, or read a folder: what is accepted and how it is indexed. **Built in the engine.** Upload files through LightHouse, from the portal or the command line, into your own deployment’s store, for a knowledge base with no system behind it. Or drop files into a folder your deployment reads. **Your files never pass through LightHouse.** LightHouse asks your deployment for a link; your deployment makes a link to one new object in its own store, valid for at most fifteen minutes; your browser or the CLI sends the file straight there. LightHouse relays the link, and nothing else. ## Upload in LightHouse You need the **Handler** (`handler`) or **Client administrator** (`client_admin`) role, signed in as a person, and the `upload.prepare` command switched on in LightHouse’s command settings **and** in your deployment’s own command policy. It is off until both say so. 1. Go to **Setup and admin → Connectors → Upload files** (`/setup/connectors/upload`). 2. Choose the files, and the deployment if you have more than one. 3. Choose **Upload**. For each file the page asks your deployment for a link, then sends the file to it, and says when it is in your store. The file is indexed at the first tick of your deployment’s scheduler after its link lapses, by the `uploads` source card (below): within about half an hour, without anyone pressing anything. ## From a terminal ```bash lighthouse-ai kb upload ./handbook.pdf --wait ``` `--deployment NAME` names the deployment where you have more than one. `--wait` waits for your deployment’s link before sending, and exits non-zero if it is refused. The CLI sends the file straight to your store, as the portal does. ## In the API 1. `POST /api/v1/uploads` with `{"filename": "handbook.pdf", "size": 48213, "deployment": "prod"}` (`deployment` optional where there is one). It answers `202` with the upload’s `id` and the command sent. 2. `GET /api/v1/uploads/{id}` until `status` is `applied`; the answer then carries the link: `url`, `method` (`PUT`), the `headers` to send with it, `expires_at` and the object’s `key`. A refused or expired upload says why. 3. `PUT` the file to `url` with exactly those headers. Both need a person’s session, as every command does. ## What your deployment needs - **A store**, named in `AAL_UPLOADS`: | Where it runs | `AAL_UPLOADS` | The link | | ---------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | AWS | `s3:///` | An S3 presigned `PUT` | | Google Cloud | `gs:///` | A Cloud Storage V4 signed URL, signed through the service account | | Azure | `azblob:////` | A user delegation SAS that can create and write one blob | | Your own servers | `file:/var/lib/aal/uploads` | A link to the engine’s own receiver, `python -m aal_engine.uploads serve`, with `AAL_UPLOADS_URL` (where your people’s browsers reach it, ending `/uploads`) and `AAL_UPLOADS_KEY` (32 random characters or more) | - **The command**, in its policy: `upload.prepare: {enabled: true, roles: [handler, client_admin], max_mb: 50}`. `max_mb` is the largest file a link is made for; 50 unless you set it. - **An `uploads` source card**, which reads the same store: ```yaml - id: uploads purpose: Read the files people upload through LightHouse. executor: python target: aal_engine.ingest.connector:run_card overseer: knowledge-lead@example.com budget_usd: 0 effect: internal source: kind: uploads label: standard requires: reads: [files people uploaded through LightHouse] reason: a knowledge base with no system behind it ``` Each link names one new key, made by your deployment from the month, a random part and the file’s cleaned name; the name you upload never chooses a path, and nothing can be read or listed with a link. The formats accepted are those the uploads source reads: `.md`, `.txt`, `.csv`, `.vtt`, `.json`, `.pdf`, `.docx`, `.pptx` and `.xlsx`. A file deleted from the store leaves the corpus. ## A folder Anything that arrives as files can also land in a folder the engine reads: documents you copy in, meeting transcripts, an export from another system. ### Connect a folder in code ```yaml - id: shared-drop purpose: Read the shared drop folder into the knowledge base. executor: python target: aal_engine.ingest.connector:run_card overseer: ops@example.com budget_usd: 0 effect: internal source: kind: folder path: drop label: standard requires: reads: [the shared drop folder] reason: the support agents answer from these guides ``` `path` is relative to the deployment’s working directory, or absolute. The source is named `folder-` unless you give it a `name`. A file may set its own title and class in front matter; your label scheme still decides whether that class is readable: ```markdown --- title: Onboarding guide doc_class: standard --- # Welcome Start here. ``` Run it, and the run’s note says what happened. With two files in `drop/`: ```text written 2, unchanged 0, quarantined 0, removed 0 ``` Delete one and run again: ```text written 0, unchanged 0, quarantined 0, removed 1 ``` ### File types and size limits | Type | How it is read | | --------------------- | --------------------------------------------------------------------------------------------- | | `.md`, `.txt`, `.vtt` | As text | | `.pdf` | Through `pdftotext -layout`, which must be installed in the image; at most 300 seconds a file | Any other file type **fails the pull**, and the error names the file, so an unreadable document is never skipped without you knowing. Change `suffixes` to accept fewer types. Files whose names start with `.` are ignored. There is no size limit per file. ## Permissions The engine needs read access to the folder and nothing else. No credential is involved. ## Where the files are held In your own account: the folder, and the corpus the engine writes from it, are on your deployment’s storage. ## What is indexed Every file of an accepted type, in the folder and its subfolders. A file is read again only when its content changes (its SHA-256); a file that disappears is removed from the corpus, so an agent never cites a document you have withdrawn. ## Check it worked - The run note, as above. - **Agents → Knowledge**: documents from `folder-`. - Each item is a Markdown file under `corpus/folder-/` in the deployment’s working directory. ## Removing it Remove the card. Documents already written stay in the corpus until you delete them. Source: https://docs.atlanticagenticlabs.com/connect/upload/ --- # Collectors > The code that reads each of your systems: in its own repository, documented, certified by Atlantic Agentic Labs and scanned on every change. A **collector** is the code that reads one of your systems: a wiki, a ticket queue, a mailbox, a feed. A [connector](/connect/) is the connection you make in LightHouse, with its credential and its access level; the collector is what the engine runs, in your own account, to read through it. ## One repository, one record per collector Collectors live in their own repository at Atlantic Agentic Labs, apart from the engine. Each collector has: | File | What it holds | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `collector.yaml` | The manifest: its family and kind, the ways to connect, the scopes it asks for, whether it only reads, whether the vendor’s API can move money, the personal data it handles, every host it may contact, the vendor API versions it supports and the lowest engine version it runs on | | `README.md` | Its documentation, in fixed sections: what it reads, how to connect, permissions, limits, data handling and troubleshooting. Each collector’s page on this site is that file | | `certification.yaml` | Each certification, newest first: the date, the vendor API version, the method and when it expires. See [How collectors are certified](/collectors/certification/) | | `security.json` | Its security posture from the last scan on the default branch. See [Security posture](/collectors/security/) | A release of the repository publishes the **catalogue**: every collector’s manifest, documentation, certification and security summary in one file. LightHouse and this site read a pinned release of it, so what you see here is what that release contains. ## How the engine loads them The collectors are one Python distribution, installed with the engine as an extra (`aal-engine[collectors]`) and loaded by entry point. The engine never depends on them: an engine without the extra keeps reading from the sources built into it. A collector you write yourself registers the same way, under the engine’s own `aal_engine.connectors` entry point, and stays in your repository. Release 0.1.0 of the repository, which this site is built from, holds 72 collectors: | Status | Collectors | | -------------------- | ---------- | | Certified | 4 | | Built, not certified | 50 | | Needs onboarding | 18 | Each has its page in the [catalogue](/collectors/catalogue/), with its status. **Built, not certified** means built and tested against recorded or synthetic responses, and not yet run against the vendor’s sandbox or a client environment. A collector is shown as certified only once it is. See [How collectors are certified](/collectors/certification/). Some sources are still read by code built into the engine; those move into the repository one at a time. ## Where to go next [Collector catalogue](/collectors/catalogue/)Every collector in the pinned release, with its status. [Collector pipeline](/collectors/pipeline/)Every request, from requested to certified. [How collectors are certified](/collectors/certification/)The methods, the dates, the expiry and the statuses. [Security posture](/collectors/security/)What is scanned, what blocks a release, and the summary. Source: https://docs.atlanticagenticlabs.com/collectors/ --- # Collector pipeline > Every collector request and where it stands, from requested to certified, built from the public backlog. Requests for new collectors are issues in the collectors repository’s backlog, and this page is that backlog as a board, rebuilt each time the site is built. A card shows the vendor and product, the family, the kind, the stage and how many requests it has. It never shows who asked, their company or what they wrote. ## The board No collector requests yet, as of 6 November 2026. **The pipeline is empty.** Nothing has been requested in the open yet. To ask for a collector: - In LightHouse, go to **Setup and admin → Connectors** and choose **Request collector support** (you need the `client_admin` or `handler` role). Your request appears here without your company's name, and LightHouse tells you as it moves. \[Coming] - Once the backlog is public, anyone can open an issue from its **Collector request** template. \[Coming] - Until then, or without LightHouse, write to . ### Requested 0 Filed, waiting for triage. None ### Triage 0 Checked for duplicates, an existing collector and public API documentation. None ### Approved 0 A person at Atlantic approved the build. None ### Building 0 Being written, with its tests and manifest. None ### Certifying 0 Running against the vendor's sandbox or a client environment. None ### Certified 0 Certified by Atlantic Agentic Labs. None ### Needs onboarding 0 Needs a partner agreement with the vendor, or a client's environment, first. None ### Declined 0 Not built: the issue says why. None ## How to request a collector - **In LightHouse.** Go to **Setup and admin → Connectors** and choose **Request collector support**, or use the same action when a search finds nothing. Give the vendor, the product, what it should read, read or read and write, where you deploy and how urgent it is. LightHouse files the request without your tenant’s name, user or domain: the issue says only how many LightHouse clients asked. If the same vendor and product is already requested, your request is added to it and its count goes up. **Your requests** shows each one’s stage, and the **Notices** page tells you when it is approved, certified or declined. Requires the `handler` or `client_admin` role (`POST /api/v1/collector-requests`); any role from `viewer` up can see the tenant’s requests. A request whose text names your tenant, a person, an email address or your domain is refused before anything is sent. - **As a GitLab issue.** Once the backlog is public, anyone can open an issue with the **Collector request** template. The issue is public: do not name your company, your clients or any person. \[Coming] - **By email.** Until the backlog is public, write to . ## How a request moves | Stage | What happens | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Requested | The request is filed | | Triage | A script, not an agent, checks it: it finds requests for the same vendor and product and links them, names an existing collector or one already coming, looks for public API documentation, and flags a request that seems to name a company for a person to check | | Approved | A person at Atlantic Agentic Labs approves the build. Nothing approves itself | | Building | The collector is written with its manifest, documentation and tests, including the read-only test | | Certifying | It runs against the vendor’s sandbox, or in a client’s environment with that client’s consent | | Certified | Certified by Atlantic Agentic Labs, and in the [catalogue](/collectors/catalogue/) | | Needs onboarding | It needs a partner agreement with the vendor, or a client’s environment, before it can be built or certified | | Declined | It will not be built; the issue says why | A request is in one stage at a time. A request closed without being certified or declined (a duplicate, or withdrawn) leaves the board. ## Where the board comes from The site reads the backlog’s issues when it is built and keeps, for each request, only the vendor, the product, the family, the kind, the stage and the request count. If the backlog cannot be read, the site is built from the last snapshot instead, so the board can be a build behind but is never invented. Source: https://docs.atlanticagenticlabs.com/collectors/pipeline/ --- # How collectors are certified > Certified by Atlantic Agentic Labs, on a date, against a version of the vendor's API, for six months at most. Every collector is certified by **Atlantic Agentic Labs**: on a date, against a named version of the vendor’s API, by a method that says how. The record is kept with the collector’s code, in `certification.yaml`, newest first, and shown on its page in the [catalogue](/collectors/catalogue/). Nothing on it is typed by hand: the status is worked out from the entries. ## The methods | Method | What was run | Certifies? | | -------------------- | ---------------------------------------------------------------------------------------- | ---------------------------- | | `sandbox` | A real run against the vendor’s sandbox or developer account | Yes | | `client-environment` | A real run in a client’s deployment, with that client’s consent. The client is not named | Yes | | `fixtures` | The collector’s tests, against recorded or synthetic responses (not client data) | No: **Built, not certified** | A collector with only `fixtures` entries is built and tested, and shown as **Built, not certified**. Nothing is recorded as `sandbox` without a real run. ## What each entry records | Field | What it says | | ------------------ | ---------------------------------------------------------------------------------- | | Certified on | The date of the run | | Collector version | The version of the collector that was run | | Engine version | The engine it ran on | | Vendor API version | The system and the version of its API, for example “RSS 2.0, Atom 1.0 (RFC 4287)” | | Certified by | Atlantic Agentic Labs, and the certifying engineer’s role (not a person’s address) | | Method | `sandbox`, `client-environment` or `fixtures` | | Evidence | What was run and its CI pipeline, recorded in the collector’s certification record | | Expires on | Six months after the date, or earlier (below) | ## Six months, or earlier A certification lasts **six months** from its date. It ends **earlier** if the vendor publishes a new API version that the collector does not list: the entry’s expiry is brought forward to that date. It also stops applying when the collector’s version changes: a new version is certified afresh. An expired collector still runs; it is shown as **Expired** until it is certified again. ## The statuses | Status | When | | -------------------- | --------------------------------------------------------------------------------------------------------------- | | Certified | The newest entry is `sandbox` or `client-environment`, for the collector’s current version, and has not expired | | Expired | It was certified, and that entry has expired or is for an older version | | Built, not certified | It has only `fixtures` entries | | Needs onboarding | It needs a partner agreement with the vendor, or a client’s environment, before it can be built or certified | | Coming | Not built yet. No date is promised | Certification says the collector reads that vendor’s API as documented, read-only where it says so, on that date. It is not a certification of the vendor, and it does not make your use of the vendor’s data audit-ready on its own: see [Data sovereignty](/data-sovereignty/). Source: https://docs.atlanticagenticlabs.com/collectors/certification/ --- # Security posture > The scanners that run on every collector, what blocks a release, and what each collector's security summary shows. Every collector is scanned on every change, and its security posture is published with it: each collector’s page in the [catalogue](/collectors/catalogue/) ends with its summary. These are scanners, not agents, and nothing about them is a claim you have to take on trust: each line below says what runs and what it gates. ## When the scans run - On every merge request. - On every change to the default branch. - On every release tag. - **Weekly**, on Sunday at 03:00 UTC, so a newly published vulnerability in a dependency that has not changed is still found. ## What is scanned | Check | Tool | Gate | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | Secrets | gitleaks, over the repository’s full history | Any finding fails | | Static analysis | Semgrep and Bandit, per collector | A high or critical finding blocks a release | | Dependencies | pip-audit and OSV-Scanner, on the collector’s resolved dependencies | A high or critical finding blocks a release | | Bill of materials | CycloneDX | Produced for every collector | | Licences | A licence check against an allow-list: MIT, BSD, Apache-2.0, ISC, PSF and MPL-2.0 | Anything else fails | | Network | Every host the collector’s code names must be in its manifest’s `hosts` list | An undeclared host fails | | Read only | A behavioural test, in the collector’s own suite, drives it over a recording transport and checks that it never writes (no POST, PUT, PATCH or DELETE), except the read operations its manifest documents, such as a token request or a search POST | Missing or failing fails | The same secrets scan and pre-commit hooks run in every Atlantic repository: see [Supply chain](/security/supply-chain/). ## The release gate A collector with **any high or critical finding** is marked `release_blocked`, and the release job refuses to tag a release of the repository while any collector is blocked. So no catalogue release, and no page on this site, carries a collector with an open high or critical finding. ## The security summary The scans are merged into the collector’s `security.json`. The one committed with the collector, and published in the catalogue, is from the last pipeline on the default branch; a merge request’s own result stays with that merge request. | On the page | From `security.json` | | -------------------------- | ----------------------------------------------------------------------------- | | Last scanned | `scanned_on` (the pipeline is in a members-only project, so it is not linked) | | Findings by severity | `findings`: critical, high, medium, low and info, across every scanner | | Release blocked | `release_blocked` | | Network allow-list check | `hosts_check`, against the manifest’s `hosts` | | Read-only behavioural test | `read_only_test` | | SBOM | `sbom`: the CycloneDX file | | Dependency licences | `licences`: each package and its licence | | Scanners | `tools`: each scanner and its version | A collector that has not yet been through a scan on the default branch shows Scan pending on each line it lacks and does not show a pass. Source: https://docs.atlanticagenticlabs.com/collectors/security/ --- # Collector catalogue > Every collector in release 0.1.0 of the collectors catalogue, with its certification status. Release 0.1.0 of the collectors catalogue: 72 collectors. Each page is built from the collector’s own manifest, documentation, certification record and last security scan. What the statuses mean: [How collectors are certified](/collectors/certification/#the-statuses). | Collector | Family | Kind | Status | | ------------------------------------------------------------------------------------------- | ------------- | ----------------- | -------------------- | | ![](/_astro/aims.CO8gQmry.png)[AIMS](/collectors/catalogue/aims/) | Aviation | Crew | Needs onboarding | | [Amadeus](/collectors/catalogue/amadeus/) | Aviation | Flights | Built, not certified | | [Amadeus Altéa Departure Control](/collectors/catalogue/amadeus-dcs/) | Aviation | Departure control | Needs onboarding | | [Amadeus Altéa Inventory and Schedules](/collectors/catalogue/amadeus-schedules/) | Aviation | Flights | Needs onboarding | | [Amadeus Altéa Reservations](/collectors/catalogue/amadeus-reservations/) | Aviation | Reservations | Needs onboarding | | [Amadeus NDC orders](/collectors/catalogue/amadeus-orders/) | Aviation | Reservations | Needs onboarding | | [Amazon S3](/collectors/catalogue/s3/) | Storage | Files | Built, not certified | | [AMOS](/collectors/catalogue/amos/) | Aviation | Maintenance | Needs onboarding | | ![](/_astro/aqd-dark.C36RZxaM.png)[AQD](/collectors/catalogue/aqd/) | Aviation | Quality | Needs onboarding | | [Atlassian Confluence](/collectors/catalogue/confluence/) | Knowledge | Wiki | Built, not certified | | [Atlassian Jira](/collectors/catalogue/jira/) | ITSM | Tickets | Built, not certified | | [Bank statements](/collectors/catalogue/bank-statements/) | Finance | Bank | Built, not certified | | [Binance](/collectors/catalogue/binance/) | Finance | Exchange | Built, not certified | | [Centrik](/collectors/catalogue/centrik/) | Aviation | Safety | Needs onboarding | | [Cirium FlightStats](/collectors/catalogue/cirium/) | Aviation | Flights | Built, not certified | | [Coinbase Prime](/collectors/catalogue/coinbase-prime/) | Finance | Exchange | Built, not certified | | [Comply365](/collectors/catalogue/comply365/) | Aviation | Documents | Needs onboarding | | [Datadog](/collectors/catalogue/datadog/) | Observability | Monitoring | Built, not certified | | [Dfns](/collectors/catalogue/dfns/) | Finance | Custody | Built, not certified | | [Dynamics 365](/collectors/catalogue/dynamics/) | CRM | CRM | Built, not certified | | [EASA Easy Access Rules](/collectors/catalogue/easa/) | Regulation | Regulation | Certified | | [ECCAIRS 2](/collectors/catalogue/eccairs/) | Aviation | Occurrences | Built, not certified | | [EUR-Lex (EU law, consolidated)](/collectors/catalogue/eurlex/) | Regulation | Regulation | Certified | | [Fireblocks](/collectors/catalogue/fireblocks/) | Finance | Custody | Built, not certified | | [Flight data monitoring exports](/collectors/catalogue/fdm/) | Aviation | Flight data | Built, not certified | | [FlightAware AeroAPI](/collectors/catalogue/flightaware/) | Aviation | Flights | Built, not certified | | [GitHub](/collectors/catalogue/github/) | Engineering | Code | Built, not certified | | [GitLab](/collectors/catalogue/gitlab/) | Engineering | Code | Built, not certified | | [Gmail](/collectors/catalogue/gmail/) | Communication | Mail | Built, not certified | | [Google Drive](/collectors/catalogue/gdrive/) | Storage | Files | Built, not certified | | [HubSpot](/collectors/catalogue/hubspot/) | CRM | CRM | Built, not certified | | [Ideagen Coruson](/collectors/catalogue/coruson/) | Aviation | Safety | Needs onboarding | | [Ideagen Q-Pulse](/collectors/catalogue/qpulse/) | Aviation | Quality | Built, not certified | | [Intelex](/collectors/catalogue/intelex/) | Aviation | Quality | Built, not certified | | [Jeppesen](/collectors/catalogue/jeppesen/) | Aviation | Crew | Needs onboarding | | [Kraken](/collectors/catalogue/kraken/) | Finance | Exchange | Built, not certified | | [Kyriba](/collectors/catalogue/kyriba/) | Finance | Treasury | Built, not certified | | [LightHouse uploads](/collectors/catalogue/uploads/) | Storage | Files | Built, not certified | | [Local folders](/collectors/catalogue/folder/) | Storage | Files | Built, not certified | | [Microsoft Teams](/collectors/catalogue/teams/) | Communication | Chat | Built, not certified | | [monday.com](/collectors/catalogue/monday/) | Engineering | Work management | Built, not certified | | [NetSuite](/collectors/catalogue/netsuite/) | ERP | ERP | Built, not certified | | [Notion](/collectors/catalogue/notion/) | Knowledge | Wiki | Built, not certified | | [OAG Flight Info](/collectors/catalogue/oag/) | Aviation | Flights | Built, not certified | | [Oracle Database](/collectors/catalogue/oracle-db/) | Data | Database | Built, not certified | | [Oracle Fusion Cloud Applications](/collectors/catalogue/oracle-fusion/) | ERP | ERP | Built, not certified | | [Plusgrade](/collectors/catalogue/plusgrade/) | Aviation | Ancillaries | Needs onboarding | | [QuickBooks Online](/collectors/catalogue/quickbooks/) | Finance | Accounting | Built, not certified | | [Ramco Aviation](/collectors/catalogue/ramco/) | Aviation | Maintenance | Needs onboarding | | [Revolut Business](/collectors/catalogue/revolut/) | Finance | Bank | Built, not certified | | [RSS and Atom feeds](/collectors/catalogue/feed/) | Web | Feed | Certified | | ![](/_astro/sabre.BwCnXmzW.png)[Sabre](/collectors/catalogue/sabre/) | Aviation | Reservations | Built, not certified | | ![](/_astro/sabre.BwCnXmzW.png)[Sabre airline-hosted](/collectors/catalogue/sabre-airline/) | Aviation | Reservations | Needs onboarding | | [Salesforce](/collectors/catalogue/salesforce/) | CRM | CRM | Built, not certified | | [SAP S/4HANA](/collectors/catalogue/sap-s4hana/) | ERP | ERP | Built, not certified | | [SAP SuccessFactors](/collectors/catalogue/sap-successfactors/) | ERP | Hr | Built, not certified | | [ServiceNow](/collectors/catalogue/servicenow/) | ITSM | Tickets | Built, not certified | | [SharePoint and OneDrive](/collectors/catalogue/sharepoint/) | Storage | Files | Built, not certified | | [SITA BagJourney](/collectors/catalogue/sita-bags/) | Aviation | Baggage | Built, not certified | | [SITA Flight Status](/collectors/catalogue/sita-flights/) | Aviation | Flights | Built, not certified | | [SITA WorldTracer](/collectors/catalogue/worldtracer/) | Aviation | Baggage | Needs onboarding | | [Slack](/collectors/catalogue/slack/) | Communication | Chat | Built, not certified | | [Stripe](/collectors/catalogue/stripe/) | Finance | Payments | Built, not certified | | [Training exports](/collectors/catalogue/training-csv/) | Aviation | Training | Built, not certified | | [TRAX](/collectors/catalogue/trax/) | Aviation | Maintenance | Needs onboarding | | [US Electronic Code of Federal Regulations (eCFR)](/collectors/catalogue/ecfr/) | Regulation | Regulation | Certified | | [Vistair SafetyNet](/collectors/catalogue/safetynet/) | Aviation | Safety | Needs onboarding | | [Web Manuals](/collectors/catalogue/webmanuals/) | Aviation | Documents | Needs onboarding | | [Workday](/collectors/catalogue/workday/) | ERP | Hr | Built, not certified | | ![](/_astro/adl.XRNMaUb9.png)[xAPI learning records](/collectors/catalogue/xapi/) | Aviation | Training | Built, not certified | | [Xero](/collectors/catalogue/xero/) | Finance | Accounting | Built, not certified | | [Zendesk](/collectors/catalogue/zendesk/) | ITSM | Tickets | Built, not certified | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/ --- # AIMS > AIMS: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. ![](/_astro/aims.CO8gQmry.png)Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. AIMS is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from AIMS’s interface specification from the vendor (rosters, pairings, flight legs and crew qualifications, read-only). There is no public API reference. Crew records name people, so crew names and contacts stay in your deployment and contact details are left out by default. ## At a glance | Collector | AIMS, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------- | | Reads | AIMS: AIMS crew management and operations control ([the vendor's documentation](https://aims.aero/)) | | Family | Aviation | | Kind | Crew | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: rosters, duties and qualifications read in place, contacts left out. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need AIMS’s interface specification from the vendor (rosters, pairings, flight legs and crew qualifications, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: aims label: internal api: spec_ref: "AIMS interface specification, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Crew and operations} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``AIMS: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/aims/ --- # Amadeus Altéa Departure Control > Amadeus Altéa Departure Control: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Amadeus Altéa Departure Control is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the Altéa Departure Control (Customer Management and Flight Management) enterprise API reference: flight list and passenger list reads. No check-in or boarding call exists in the adapter. ## At a glance | Collector | Amadeus Altéa Departure Control, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | Reads | Amadeus IT Group: Amadeus Altéa Departure Control enterprise API ([the vendor's documentation](https://developers.amadeus.com/enterprise)) | | Family | Aviation | | Kind | Departure control | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: flight and passenger lists per departure (load, acceptance and boarding status), read-only; no check-in or boarding call exists in the adapter. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the Altéa Departure Control (Customer Management and Flight Management) enterprise API reference: flight list and passenger list reads, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: amadeus-dcs label: internal api: spec_ref: "Amadeus Altéa Departure Control API reference, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Departure control} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Amadeus: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amadeus-dcs/ --- # Amadeus NDC orders > Amadeus NDC orders: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Amadeus NDC orders is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the NDC (Offer and Order) enterprise API reference: order retrieve and order list reads. No offer, order or pay call exists in the adapter. ## At a glance | Collector | Amadeus NDC orders, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Amadeus IT Group: Amadeus NDC (Offer and Order) enterprise API ([the vendor's documentation](https://developers.amadeus.com/enterprise)) | | Family | Aviation | | Kind | Reservations | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: NDC orders by id and by change, read-only; no offer, order or pay call. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the NDC (Offer and Order) enterprise API reference: order retrieve and order list reads, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: amadeus-orders label: internal api: spec_ref: "Amadeus NDC Offer and Order API reference, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Reservations} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Amadeus: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amadeus-orders/ --- # Amadeus Altéa Reservations > Amadeus Altéa Reservations: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Amadeus Altéa Reservations is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the Altéa Reservation enterprise API reference (PNR retrieve and the PNR list or queue read your airline is granted), issued with the enterprise contract. Altéa references are issued under the enterprise agreement; if they turn out to be SOAP only, onboarding adds a SOAP transport to the adapter (nothing is built speculatively). ## At a glance | Collector | Amadeus Altéa Reservations, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | Reads | Amadeus IT Group: Amadeus Altéa Reservation (PNR) enterprise API ([the vendor's documentation](https://developers.amadeus.com/enterprise)) | | Family | Aviation | | Kind | Reservations | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: the airline’s PNRs read in place: itinerary, status, remarks and service requests, with document numbers and health service requests left out. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the Altéa Reservation enterprise API reference (PNR retrieve and the PNR list or queue read your airline is granted), issued with the enterprise contract, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: amadeus-reservations label: internal api: spec_ref: "Amadeus Altéa Reservation API reference, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Reservations} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Amadeus: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amadeus-reservations/ --- # Amadeus Altéa Inventory and Schedules > Amadeus Altéa Inventory and Schedules: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Amadeus Altéa Inventory and Schedules is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the Altéa Inventory and Schedule enterprise API reference (schedule and inventory display reads). Schedules and inventory carry no passenger data, though the same exclusions apply if a payload ever does. ## At a glance | Collector | Amadeus Altéa Inventory and Schedules, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Amadeus IT Group: Amadeus Altéa Inventory and Schedule enterprise API ([the vendor's documentation](https://developers.amadeus.com/enterprise)) | | Family | Aviation | | Kind | Flights | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: the airline’s own schedule and inventory state, by flight and date. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the Altéa Inventory and Schedule enterprise API reference (schedule and inventory display reads), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: amadeus-schedules label: internal api: spec_ref: "Amadeus Altéa Inventory and Schedule API reference, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Schedules and flight status} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Amadeus: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amadeus-schedules/ --- # Amadeus > Amadeus: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads flight status for the flights you name, airline and airport reference data, and flight orders by id from the Amadeus Enterprise APIs, read-only, inside your deployment. ## At a glance | Collector | Amadeus, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Amadeus IT Group: Amadeus Enterprise APIs: flight status, reference data, flight orders ([the vendor's documentation](https://developers.amadeus.com/enterprise)) | | Family | Aviation | | Kind | Flights | | Ways to connect | OAuth approval | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | `test.api.amadeus.com`, `api.amadeus.com`, `{environment}` | | Vendor API versions | Authorization v1, On-Demand Flight Status v2, Airline Code Lookup v1, Airport and City Search v1, Flight Order Management v1 | | Lowest engine version | `0.46.0` | ## What it reads - **Flights:** dated flight status (`GET /v2/schedule/flights`) for each flight you name, for every day from `days_back` (0 to 7, default 1) to `days_ahead` (0 to 14, default 2). One record per flight and date. - **Airlines:** reference data by airline code (`GET /v1/reference-data/airlines`), 20 codes to a request. - **Locations:** airports found by keyword (`GET /v1/reference-data/locations`), paged by `meta.links.next`. - **Orders:** flight orders by id (`GET /v1/booking/flight-orders/{id}`). An order that answers 404 is gone: its record is withdrawn. - It reads only what you name; it never lists bookings. The Altéa and NDC enterprise APIs (reservations, departure control, inventory and schedules, NDC orders) are separate collectors that need onboarding. ## How to connect 1. Get the API key and secret your Amadeus account manager issued (client credentials). Amadeus closed its self-service portal on 17 July 2026; enterprise keys reach the same endpoints. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Amadeus**, and leave the access level at **Read**. 3. Name the **environment** (`test` or `production`) and what to read: `flights` (for example `XX487`), `airlines`, `locations`, `orders`. 4. Paste the key and then the secret. Your browser seals them to your deployment, which keeps them and hands them to the collector as `AMADEUS_CLIENT_ID` and `AMADEUS_CLIENT_SECRET` (settable per source as `client_id_env` and `client_secret_env`). ## Permissions - The collector requests no scope. It uses the grant the key has and refuses a token whose scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`); the credential check answers `scope_missing` and names the scopes. - It sends `GET`, and one `POST`: the OAuth token request to `/v1/security/oauth2/token`. The flight order API documents `DELETE` (cancel); no call here sends it. - Your deployment refuses to store this credential at read and write. - The read-only test proves it on every change by driving the real HTTP client through a recorder. ## Limits - Only two hosts are contacted: `test.api.amadeus.com` and `api.amadeus.com`. The environment you choose picks one; there is no third. - None of these APIs offers changed-since. Each run reads the whole window again, and a record whose content has not changed is left untouched, so a run costs requests, not writes. - Requests are paced at 0.2 s by default; `429` and `5xx` are retried with backoff and `Retry-After`. - A location search stops after `max_pages` pages (50 by default), 50 results to a page. - Amadeus does not state rate limits in the specifications it published, and the portal that did is closed. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a flight order or a traveller. - Flight orders carry traveller names and contact details; they stay in your deployment. By default travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set) are left out before a record is written. `exclude_fields` adds paths (for example `**.contact`); `keep_fields` takes a default back by its exact name. - Nothing is cached raw: a raw cache would keep on disk the fields the exclusion removes. - A failure names the host and the status, never the URL, because a URL can carry an order id. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------- | | `credential variable 'AMADEUS_CLIENT_ID' is not set` | The deployment has not been given the key | Connect the credential again, or set the variable | | `POST test.api.amadeus.com: HTTP 401` | Amadeus refused the key and secret | Check the environment (a test key does not work on production) and that the key has not been revoked | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Ask the account manager for a key limited to reading | | `GET api.amadeus.com: HTTP 429` | Amadeus is rate-limiting after the retries | Name fewer flights, or read less often | | `environment is test or production` | Any other value | Choose one of the two | | `name what to read: flights, airlines, locations or orders` | Nothing was named | Name at least one | | `not a flight designator (carrier code, number): ...` | A flight is not like `XX487` or `XX487A` | Correct the designator | | `days_back is 0 to 7 and days_ahead 0 to 14` | The window is too wide | Narrow it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Authorization v1, On-Demand Flight Status v2, Airline Code Lookup v1, Airport and City Search v1, Flight Order Management v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amadeus/ --- # AMOS > AMOS: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. AMOS is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the AMOS API reference from the Swiss-AS customer portal, or the AIM interface specification (work orders, task cards, defects, components and their change times, read-only). Swiss-AS describes hundreds of managed APIs and its AIM integration engine; the reference is on the customer portal. ## At a glance | Collector | AMOS, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | Reads | Swiss AviationSoftware: AMOS maintenance and engineering system ([the vendor's documentation](https://swiss-as.com/interfaces)) | | Family | Aviation | | Kind | Maintenance | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: work orders, task cards, deferred defects and component history read in place; no work order is raised, signed or closed. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the AMOS API reference from the Swiss-AS customer portal, or the AIM interface specification (work orders, task cards, defects, components and their change times, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: amos label: internal api: spec_ref: "AMOS API reference (or AIM interface specification), release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Maintenance} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers and dates of birth, and health or disability special service requests. Contact details are not left out by default for a maintenance system, whose records name engineers and sign-offs; add the fields that hold them to `exclude_fields`. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Swiss AviationSoftware: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/amos/ --- # AQD > AQD: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. ![](/_astro/aqd-dark.C36RZxaM.png)Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. AQD is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from AQD’s web service or export specification from its vendor (occurrences, audits, findings and corrective actions). There is no public reference. The docs link is a neutral SKYbrary description, not a vendor reference. ## At a glance | Collector | AQD, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Reads | AQD (Aviation Quality Database): AQD quality and safety suite ([the vendor's documentation](https://skybrary.aero/index.php/AQD)) | | Family | Aviation | | Kind | Quality | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: AQD’s quality and safety records read in place. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need AQD’s web service or export specification from its vendor (occurrences, audits, findings and corrective actions), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: aqd label: internal api: spec_ref: "AQD web service / export specification, version, as issued by the vendor" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Quality and audit} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``AQD (Aviation Quality Database): needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/aqd/ --- # Bank statements > Bank statements: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads bank and custody statement files from a bucket or an SFTP drop that your banks and custodians already deliver to: camt.053 and camt.052 (ISO 20022), MT940 and MT950, and MT535 statements of holdings, from any bank or custodian (State Street included). It uses no bank’s API and no credential that could move money. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Bank statements, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Any bank or custodian: camt.053, camt.052, MT940, MT950 and MT535 statement files (ISO 20022 and SWIFT MT) ([the vendor's documentation](https://www.iso20022.org/iso-20022-message-definitions)) | | Family | Finance | | Kind | Bank | | Ways to connect | Key pair, Service account | | Scopes | - Read: `s3:ListBucket`, `s3:GetObject`, `sftp:list`, `sftp:read` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Financial, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | ISO 20022 camt.052.001 and camt.053.001, SWIFT MT940, MT950, MT535 (SR2022) | | Lowest engine version | `0.46.0` | ## What it reads - **Bank statements** (camt.053, camt.052, MT940, MT950): one record per statement, with its balances and every entry: booked and value dates, signed amount and currency, references, end-to-end id, counterparty and details (a reversal marked), exact to the digit. - **Statements of holdings** (MT535): one record per statement, with the safekeeping account, each ISIN with description, quantity (as face amount or units), available sub-balance and holding value, and the page total. A page of updates only is marked. - Files with the extensions `.xml`, `.camt`, `.053`, `.052`, `.sta`, `.mt940`, `.940`, `.950`, `.535`, `.txt` and `.fin`, up to `max_mb` (default 50). Anything else, or a file that is not a statement, is skipped and counted. - A file is read again only when it changes (by its ETag or size and time); a file that disappears takes its statements with it. ## How to connect Choose where your banks deliver: - **A bucket you own**, as `s3://bucket/prefix`, `gs://bucket/prefix`, `azblob://account/container/prefix` or `file:/path`. It is read by your deployment’s own identity, or for AWS by a role it assumes (`role_arn`, `external_id`), set up by your engineer. - **An SFTP drop**, as `sftp://user@host:22/path`. In LightHouse, open **Setup and admin, Connectors**, choose **Bank statements**, and paste the server’s host key fingerprint (`SHA256:...`, from `ssh-keygen -lf`), then the PEM of the drop account’s private key. Your browser seals it to your deployment; LightHouse never sees it. The SFTP route needs the `bank-statements` extra (`paramiko`). The SFTP credential is JSON in the variable the source names: `private_key`, `host_key`, and `user` if it is not in the address. ## Permissions None to check: a statement file cannot move money, trade, instruct or approve. The collector only lists and reads files. - **Read-only, by construction and by test.** This collector does not speak HTTP itself, so its read-only tests drive it through stubbed clients that record every call and refuse any other: an SFTP client of which only `listdir_attr` and `open` (always opened `rb`) are ever called, and an S3 client of which only `list_objects_v2` and `get_object` are. Any write, delete, rename or upload would fail those tests. The object-store adapters expose `list` and `get` only. - **Minimum access to give:** for a bucket, list and read (`s3:ListBucket` and `s3:GetObject`, or the equivalent on Cloud Storage or Blob Storage); for SFTP, a drop account that can list and read the directory. - **SFTP host key pinned:** a server that does not present the pinned key is refused before the key signs anything (`the SFTP server's host key is not the pinned one`). ## Limits - Files only: no bank API, no balances that are not in a file you receive. - The SFTP host must be a DNS name; subdirectories and hidden files are skipped. - A statement’s entry details are cut at 300 characters in the record. - MT536, MT564 and ISO 20022 semt.002 are not read yet. - A file over `max_mb`, or with an unknown extension, is skipped and counted (`files skipped` in the run’s log). ## Data handling - Statements hold financial and personal data: account numbers, balances, counterparties’ names and remittance text. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the statements, and never opens the credential. - Each record carries the SHA-256 of the file it came from, so any figure can be traced to the exact bytes your bank delivered. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------- | | `the SFTP server's host key is not the pinned one` | The server presented another key | Check the fingerprint with your bank; never accept a changed one without asking | | `host_key is the server's key fingerprint, SHA256:` | The pinned fingerprint is missing or malformed | Paste the `SHA256:...` fingerprint | | `the SFTP host is a DNS name` | The address uses an IP address or odd characters | Use the host name | | `private_key is an Ed25519, RSA or ECDSA key` | The PEM is not one of those key kinds | Paste the drop account’s private key | | `an object store is s3://bucket/prefix, gs://bucket/prefix, azblob://account/container/prefix or file:/path` | The location is not one of these | Correct the location | | Run succeeded, few records written | Files were skipped (unknown extension, too large, not a statement) | Check the run’s log for `files skipped` | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | ISO 20022 camt.052 and camt.053; SWIFT MT940, MT950, MT535 (SR2022) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/bank-statements/ --- # Binance > Binance: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Binance account’s spot and cross-margin balances, trades, deposits and withdrawals, so reconciliation and reporting agents can check them against the books. It is read-only, and it is built to refuse a key that can withdraw, transfer or trade. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Binance, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Reads | Binance: Binance Spot and Wallet REST API ([the vendor's documentation](https://developers.binance.com/docs/binance-spot-api-docs)) | | Family | Finance | | Kind | Exchange | | Ways to connect | Access token, Key pair | | Scopes | - Read: `Enable Reading` | | Read only | Yes | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.binance.com`, `testnet.binance.vision`, `{host}` | | Vendor API versions | Spot API v3 (/api/v3), SAPI (/sapi/v1) | | Lowest engine version | `0.46.0` | ## What it reads - **Spot balances** (free and locked) and **cross-margin balances** (free, locked, borrowed, interest, net asset), one record per asset, rewritten only when it changes. Zero balances are not recorded. - **Trades** for the symbols you name in `symbols` (Binance answers trades per symbol only), from the last trade id. - **Deposits and withdrawals**, in 89-day windows (Binance allows under 90 days a request), with amount, fee, network, status, address and transaction id. - The first read goes back `history_days` (default 90, at most 3,650). **Futures are not read.** A USD-M futures account is readable only by a key with futures enabled, which can trade, so a key this collector accepts cannot read it. ## How to connect 1. In Binance, make an API key with **Enable Reading** only (an Ed25519 key is recommended), restricted to your deployment’s egress addresses. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Binance**, and name the symbols and the environment (`production` or `testnet`). 3. Paste the API key and either the secret (an HMAC key) or the Ed25519 private key. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_BINANCE` by default): `api_key`, and `api_secret` or `private_key` (a PEM), `environment`, and `view_only_confirmed` for the testnet. ## Permissions This collector is **read-only**: it sends `GET` requests only, and its read-only test proves it on every change. - **Refused by the code:** Binance states a key’s restrictions (`GET /sapi/v1/account/apiRestrictions`). Before every read, and in the health check, a key with any of these nine switches on is refused, naming what it can do: `enableWithdrawals` (withdraw), `enableInternalTransfer` (transfer internally), `permitsUniversalTransfer` (universal transfer), `enableSpotAndMarginTrading` (trade spot and margin), `enableMargin` (use margin), `enableFutures` (trade futures), `enableVanillaOptions` (trade options), `enablePortfolioMarginTrading` (trade portfolio margin), `enableFixApiTrade` (trade over FIX). The error is `Binance: refused: the credential can \; make a view-only one`. - **Not refused by the code:** a switch Binance adds later that is not on that list. `enableReading` is expected and is not checked. - **Testnet:** Binance’s spot testnet has no `/sapi`, so a testnet key’s restrictions are not stated. The collector reads only once you have confirmed the key can only read (`view_only_confirmed`), skips the margin, deposit and withdrawal calls, and says so. - **IP restriction:** the check reports `ipRestrict`; a key without one is told to pin it (it is not refused). - **Signing:** each request carries `timestamp`, `recvWindow` and a signature over the query string: HMAC-SHA256 with the secret, or Ed25519 with the private key (an RSA key is refused: `private_key is an Ed25519 key`). The secret never leaves your store. - **Hosts:** only `api.binance.com` (production) or `testnet.binance.vision`, over https; redirects are never followed. ## Limits - Spot API v3 and the SAPI wallet endpoints. - Requests are paced (0.2 s apart) and retried on 429 and 5xx with back-off. - A margin account that is absent or unreadable is skipped, not an error. - `symbols` must be alphanumeric Binance symbols such as `BTCUSDT`. - Amounts are exact decimals; a number that arrives as a float is refused. ## Data handling - Records hold financial data: balances, trades, deposit and withdrawal amounts and addresses. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------ | | `Binance: refused: the credential can withdraw; make a view-only one` | A switch that moves funds is on (the action is named) | Make a key with Enable Reading only | | `Binance does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | Testnet key, not yet confirmed | Confirm it can only read | | `private_key is an Ed25519 key` | The PEM is not an Ed25519 key | Use an Ed25519 key, or an HMAC secret | | `environment is production or testnet` | The environment is something else | Correct it | | `symbols are Binance symbols, e.g. BTCUSDT` | A symbol has punctuation | Use `BTCUSDT`, not `BTC-USDT` | | `Binance answered HTTP 401` | The key or signature was refused | Check the key, the secret and the IP restriction | | `Binance answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Spot API v3; SAPI v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/binance/ --- # Centrik > Centrik: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Centrik is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Centrik’s API reference and integration guide from TrustFlight (safety reports and occurrences, audits and findings, corrective actions, the risk register and documents, each with its list, id, change time and paging, and an API credential limited to reading). There is no public API reference. Reporters’ names and everyone’s contact details are left out by default. ## At a glance | Collector | Centrik, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------ | | Reads | TrustFlight: Centrik safety management system ([the vendor's documentation](https://trustflight.com/)) | | Family | Aviation | | Kind | Safety | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: the operator’s safety reports, occurrences, audits, findings, corrective actions, risks and documents read in place, reporters left out. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Centrik’s API reference and integration guide from TrustFlight (safety reports and occurrences, audits and findings, corrective actions, the risk register and documents, each with its list, id, change time and paging, and an API credential limited to reading), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: centrik label: internal api: spec_ref: "Centrik API reference and integration guide, version, as issued by TrustFlight" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Safety management} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``TrustFlight: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/centrik/ --- # Cirium FlightStats > Cirium FlightStats: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads flight status by airport and by flight from Cirium’s FlightStats Flex Flight Status API, read-only, inside your deployment. ## At a glance | Collector | Cirium FlightStats, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Reads | Cirium: Cirium FlightStats Flex Flight Status API ([the vendor's documentation](https://developer.flightstats.com/api-docs/)) | | Family | Aviation | | Kind | Flights | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `api.flightstats.com`, `{host}` | | Vendor API versions | Flex Flight Status v2 | | Lowest engine version | `0.46.0` | ## What it reads - **Airports:** departures and arrivals of each airport you name, in blocks of up to 6 hours across the window (`GET .../airport/status/{airport}/{dep|arr}/{year}/{month}/{day}/{hour}`). - **Flights:** today’s status of each flight you name by carrier and number (`GET .../flight/status/{carrier}/{flight}/dep/{year}/{month}/{day}`). - One record per flight, keyed by FlightStats’ `flightId`, with its route, status and departure time. - The window runs from `hours_back` (0 to 72, default 6) before now to `hours_ahead` (0 to 72, default 12) after, from an hour before the last run when there was one. ## How to connect 1. Get a FlightStats application id and key from Cirium’s developer portal. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Cirium FlightStats**, and leave the access level at **Read**. 3. Name the `airports` (IATA or ICAO codes) and the `flights` (such as `XX101`). 4. Paste the application id and then the key. Your browser seals them to your deployment, which hands them to the collector as `CIRIUM_APP_ID` and `CIRIUM_APP_KEY`. ## Permissions - `GET` only. The Flex status APIs are read-only and no other verb is sent. - **The key travels in the query**, as FlightStats defines it (`appId`, `appKey`). So nothing is cached (the cache index is keyed by URL) and every failure names the host only. - Requests ask for `extendedOptions=useHTTPErrors`, without which an authentication failure is an HTTP 200 carrying an `error` element that would read as “no flights”. - Your deployment refuses to store this credential at read and write. Only `api.flightstats.com` is contacted. ## Limits - No paging; an airport is read in blocks of `hours_per_request` hours (1 to 6, default 6) because the public reference does not state a limit and a smaller block is never refused. `max_flights` (1000) caps one block. - FlightStats offers no changed-since: the window from the last run, less an hour, is read again, and unchanged flights are not rewritten. - Rate limits are contractual and not published; the default pace is one request a second (`delay_s`). ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a flight record. - Nothing is cached raw, and a failure names the host and the status, never the URL. - Flight status carries no passenger data. The standard exclusions still apply to every record before it is written (travel document numbers, dates of birth, health or disability special service requests); `exclude_fields` adds paths and `keep_fields` takes a default back by its exact name. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------ | -------------------------------------------------------------------------------- | --------------------------------------------------------------- | | `credential variable 'CIRIUM_APP_ID' is not set` | The deployment has not been given the application id or key | Connect the credential again | | `GET api.flightstats.com: FlightStats error 403` | FlightStats refused the application id or key (reported through `useHTTPErrors`) | Check the id and key, and that the application may use this API | | `GET api.flightstats.com: HTTP 403` | The same refusal as an HTTP status | As above | | `name airports or flights to read` | Neither was named | Name at least one | | `not airport codes: [...]` | A code is not 3 or 4 letters or digits | Correct it | | `hours_per_request is 1 to 6` | A block longer than 6 hours | Use 6 or fewer | | `hours_back and hours_ahead are 0 to 72` | The window is too wide | Narrow it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | --------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Flex Flight Status v2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/cirium/ --- # Coinbase Prime > Coinbase Prime: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Coinbase Prime entity’s portfolios, balances, orders, fills and transactions, so reconciliation and reporting agents can check them against the books. It is read-only. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Coinbase Prime, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------ | | Reads | Coinbase: Coinbase Prime REST API ([the vendor's documentation](https://docs.cdp.coinbase.com/prime/docs/welcome)) | | Family | Finance | | Kind | Exchange | | Ways to connect | Access token | | Scopes | - Read: `Read` | | Read only | Yes | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.prime.coinbase.com`, `{host}` | | Vendor API versions | Prime REST API v1 | | Lowest engine version | `0.46.0` | ## What it reads - **Portfolios** the key can see (or only those named in `portfolios`), and each portfolio’s **balances**: amount, holds, withdrawable amount and fiat value, per asset. Balances are a snapshot: one record per portfolio and asset, rewritten only when it changes and removed when the asset disappears. - **Orders, fills and transactions** per portfolio, oldest first from the last cursor: product, side, status, price, quantity, value, commission, venue; for transactions the type, status, amount, fees, wallet and completion time. - The first read goes back `history_days` (default 90, at most 3,650). ## How to connect 1. In Coinbase Prime, make an API key with the **Read** permission only, and pin it to your deployment’s egress addresses. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Coinbase Prime** (optionally name the portfolios). 3. Paste the access key, passphrase and signing key, and confirm the key was made with Read only. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_COINBASE_PRIME` by default): `access_key`, `passphrase`, `signing_key` and `view_only_confirmed` (`yes`). ## Permissions This collector is **read-only**: it sends `GET` requests only, and its read-only test proves it on every change. - **Refused by the code:** nothing, by permission. Coinbase Prime’s REST API has no call that answers an API key’s own permissions (the users endpoints describe people, not keys), so this collector cannot see whether a key can trade or withdraw. A key with the Trade or Transfer permission would not be detected. - **What stops it:** the collector reads only once you have confirmed the key was made with **Read** only (`view_only_confirmed`). Without it, every pull fails with `Coinbase Prime does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read`, and the health check says the same. Make the key Read-only in Prime: that, not this code, is what stops a key from moving funds. - **Signing:** each request carries an HMAC-SHA256 of timestamp, method and path under the signing key, base64, in `X-CB-ACCESS-SIGNATURE`. The signing key never leaves your store. - **Hosts:** only `api.prime.coinbase.com`, over https; redirects are never followed. ## Limits - Prime REST API v1; pages of 100 by cursor, oldest first. - The signature covers the timestamp, method and path, not the query string. Coinbase’s reference is ambiguous on that point; it is the first thing to confirm against Prime’s sandbox before a certified run. - Requests are paced (0.2 s apart) and retried on 429 and 5xx with back-off. - Amounts are exact decimals; a number that arrives as a float is refused. ## Data handling - Records hold financial data: balances, orders, fills and transaction amounts. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | --------------------------------------------------------- | | `Coinbase Prime does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | You have not confirmed the key is Read only | Confirm it, after checking the key in Prime | | `Coinbase Prime answered HTTP 401` | The key, passphrase or signature is wrong | Check all three credential parts | | `Coinbase Prime answered HTTP 403` | The key lacks access to the portfolio | Give the key Read on that portfolio | | `Coinbase Prime answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | | `Coinbase Prime could not be reached` | A network failure after retries | Check the deployment’s egress to `api.prime.coinbase.com` | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Prime REST API v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/coinbase-prime/ --- # Comply365 > Comply365: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Comply365 is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Comply365’s API or integration specification, usually under NDA (documents, revisions and read-and-sign status). There is no public developer documentation; the specification is usually issued under NDA. ## At a glance | Collector | Comply365, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------- | | Reads | Comply365: Comply365 document and compliance platform ([the vendor's documentation](https://www.comply365.com/)) | | Family | Aviation | | Kind | Documents | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: controlled documents and their revisions read in place. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Comply365’s API or integration specification, usually under NDA (documents, revisions and read-and-sign status), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: comply365 label: internal api: spec_ref: "Comply365 API / integration specification, version, as issued by the vendor" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Documents and manuals} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Comply365: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/comply365/ --- # Atlassian Confluence > Atlassian Confluence: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the pages of the Confluence spaces you name, with their version and where they sit in the page tree, so a citation can name the page and its path. A page deleted or archived in Confluence leaves the knowledge base. ## At a glance | Collector | Atlassian Confluence, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Reads | Atlassian: Confluence Cloud ([the vendor's documentation](https://developer.atlassian.com/cloud/confluence/rest/v1/intro/)) | | Family | Knowledge | | Kind | Wiki | | Ways to connect | Access token | | Scopes | - Read: `read:page:confluence`, `read:space:confluence` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `{tenant}.atlassian.net` | | Vendor API versions | Confluence Cloud REST API (/wiki/rest/api, content and content/search) | | Lowest engine version | `0.45.0` | ## What it reads - Pages (`type = page`) in the spaces you name, as plain text from their export view; images become `[image]`, links are kept inline. - For each page: its title, space, version number, last-modified day, ancestor path and a link to it. - The first pull lists each space whole, however deep its tree. Later pulls ask for the pages changed since the cursor, oldest first. - Archived pages too, if you list `archived` among `statuses`. - Deletions: every `reconcile_hours` (six by default) the collector lists each space’s page ids, without bodies, and removes every page it holds that is no longer there. A space taken out of the configuration has its pages removed. - Never read: blog posts, comments and attachments. ## How to connect 1. Create or choose an integration account in your Atlassian site with access to the spaces you name and nothing else. Do not use a site administrator. 2. Signed in as that account, create an API token at id.atlassian.com (Security, API tokens). 3. In LightHouse, open **Connectors**, choose **Confluence**, name the site (`https://.atlassian.net`), the space keys, the label and how often to read, and paste the account’s email address and token. 4. In code, set `CONFLUENCE_BASE_URL` (the site’s wiki address), `CONF_EMAIL` and `CONF_TOKEN` from your secret store and add a `kind: confluence` source card with `spaces`, `label` and `requires`. ## Permissions The collector signs in with the account’s email address and API token (HTTP Basic). Atlassian API tokens carry no scopes, so what the account can read is what the collector can read; LightHouse’s card lists `read:page:confluence` and `read:space:confluence` for a scoped token. Every request is a `GET`: `/rest/api/content` (a space’s pages, and page ids alone for deletions) and `/rest/api/content/search` (pages changed since the cursor). The credential never follows a link off the configured site. Its read-only test proves it on every change. ## Limits - You must name the spaces; a whole site is never the default. Space keys with characters other than letters, digits and `-` are dropped. - `limit` caps a pull that follows the cursor (oldest first, so it resumes where it stopped). The first pull is never capped, because a capped listing is in no order a cursor could resume from. - Confluence reports modification dates to the day, so a pull re-reads that day’s pages; an unchanged page is not rewritten. - A space the account cannot see (404, 403 or an unknown key) is skipped and counted as `space-unavailable`; its pages are kept until it can be read again. - Rate limits (429 and 5xx) are waited out with back-off, up to six times. - A self-hosted Data Center site is connected in code only. ## Data handling - Page text is copied into the deployment’s corpus under the source’s `label`. Pages can name people and hold personal data; the author’s display name is not kept. - The token stays in your secret store (or sealed under your own tenant’s key in LightHouse until the deployment can keep it); it is never written to logs or run notes. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------ | | `CONFLUENCE_BASE_URL is not set: name the client's Confluence site` | The site address is missing | Set `CONFLUENCE_BASE_URL` | | `no Confluence credentials: set CONF_EMAIL and CONF_TOKEN` | The account email or token is missing | Set both | | `name the spaces to sync; a whole site is never the default` | `spaces` is empty | Name the space keys | | `statuses are current and archived` | An unknown status was listed | Use `current` and/or `archived` | | `Confluence's next link leaves the configured site; refused` | A paging link pointed at another host | Check the site address; report it if it persists | | `HTTP 401` or `HTTP 403` | The token was revoked, or the email is not the token’s owner | Make a new token for the integration account | | Read succeeded, 0 written | No page changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Confluence Cloud REST API, content and content/search | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/confluence/ --- # Ideagen Coruson > Ideagen Coruson: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Ideagen Coruson is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Ideagen Coruson’s API guide, issued to customers (hazards, occurrences, investigations, risks and actions, read-only). There is no public reference: Ideagen’s API guides are behind customer sign-in. Q-Pulse, whose guide Ideagen publishes, is the separate `qpulse` collector. ## At a glance | Collector | Ideagen Coruson, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------- | | Reads | Ideagen: Ideagen Coruson safety management ([the vendor's documentation](https://www.ideagen.com/)) | | Family | Aviation | | Kind | Safety | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: Coruson’s safety records read in place, reporters left out. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Ideagen Coruson’s API guide, issued to customers (hazards, occurrences, investigations, risks and actions, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: coruson label: internal api: spec_ref: "Ideagen Coruson API guide, version, as issued to the customer" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Safety management} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Ideagen: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/coruson/ --- # Datadog > Datadog: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the monitors, incidents and postmortem notebooks of a Datadog account, so operations agents can explain an alert from what the team wrote about the last one. It reads the descriptions and the people’s text, never the telemetry. ## At a glance | Collector | Datadog, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Datadog: Datadog API (monitors, incidents, notebooks) ([the vendor's documentation](https://docs.datadoghq.com/api/latest/)) | | Family | Observability | | Kind | Monitoring | | Ways to connect | Access token | | Scopes | - Read: `monitors_read`, `incident_read`, `notebooks_read` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `api.datadoghq.com`, `api.datadoghq.eu`, `api.us3.datadoghq.com`, `api.us5.datadoghq.com`, `api.ap1.datadoghq.com`, `api.ddog-gov.com`, `api.{site}`, `app.{site}`, `api`, `app`, `datadoghq.com` | | Vendor API versions | Datadog API v1 (monitors, notebooks) and v2 (incidents) | | Lowest engine version | `0.45.0` | ## What it reads - Monitors: name, message, query, type, state, tags and priority. The monitor API has no “modified since” filter, so each run lists them all and keeps the newer ones; a monitor that has gone is withdrawn. - Incidents: title, state, severity, customer impact and the text fields the responders filled in (summary, root cause, and any the account added). - Postmortems: Datadog keeps them as notebooks of type `postmortem`; their Markdown cells are the record. Graph cells are left out. - Each kind has its own modified-time cursor, and the boundary item is re-read, which costs nothing because an unchanged record is not rewritten. - Never read: dashboards, logs, traces and metrics. ## How to connect 1. Create an API key and an application key with only the read scopes below (Organization settings, Application keys). 2. In LightHouse, open **Connectors**, choose **Datadog**, pick your site (`us1`, `us3`, `us5`, `eu1`, `ap1` or `us1-fed`), a label and how often to read, and enter the two keys. 3. In code, give the deployment `DD_API_KEY` and `DD_APP_KEY` from your secret store and add a `kind: datadog` source card with `site` (the API host suffix, such as `datadoghq.eu`), `label` and `requires`. `api_key_env` and `app_key_env` change the variable names. ## Permissions Read scopes only: `monitors_read`, `incident_read` and `notebooks_read`. The collector sends only `GET` requests, to `api.` and no other host. A key that could write is a key a leak turns into an outage, so give the application key no write scope. Its read-only test proves it on every change. ## Limits - The site must be a Datadog site (`datadoghq.com`, `datadoghq.eu`, a regional `*.datadoghq.com`, or `ddog-gov.com`); anything else is refused. - Incidents and postmortems are kept when deleted in Datadog; only monitors are withdrawn. - The monitor list is read whole on every run. - Requests are paced and back off when Datadog asks (`Retry-After`). ## Data handling - Monitor messages, incident text and postmortem text are copied into the deployment’s corpus under the source’s `label`. They can name people and hold personal data. - Both keys stay in your secret store and are never written to logs or run notes; they are sent only to the API host. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------- | | `is not a Datadog site` | `site` is not a Datadog API host suffix | Use `datadoghq.com`, `datadoghq.eu`, `us5.datadoghq.com` and the like | | `unknown Datadog kinds` | `kinds` names something other than monitors, incidents or postmortems | Correct the list | | `credential variable 'DD_API_KEY' is not set` | A key variable is empty (the name is shown, never a value) | Set `DD_API_KEY` and `DD_APP_KEY` | | `HTTP 403` | The application key lacks a read scope, or belongs to another site | Add the scope; check the site | | Read succeeded, 0 written | Nothing was modified since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Datadog API v1 (monitors, notebooks) and v2 (incidents) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/datadog/ --- # Dfns > Dfns: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Dfns organisation’s wallets, asset balances and transfers, so treasury and reconciliation agents can check custody against the books. It is read-only, and it is built to refuse a service account that can move funds. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Dfns, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Dfns: Dfns wallet-as-a-service API (wallets, assets, transfers) ([the vendor's documentation](https://docs.dfns.co/api-reference/overview)) | | Family | Finance | | Kind | Custody | | Ways to connect | Access token | | Scopes | - Read: `Wallets:Read`, `Wallets:Transfers:Read` | | Read only | Yes | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.dfns.io`, `api.uae.dfns.io`, `{host}` | | Vendor API versions | Dfns REST API (unversioned paths: /wallets, /auth/service-accounts) | | Lowest engine version | `0.46.0` | ## What it reads - **Wallets and their balances:** for each wallet and asset, the balance (Dfns gives integer strings in the asset’s smallest unit with its `decimals`; they are scaled exactly), with the wallet’s name, id, network and address. - **Transfers per wallet**, newest first: status, kind, amount (for native assets), token contract, recipient, hash, fee and requested date. Reading stops at the last newest transfer seen less a week, so a transfer whose status moved on is read again. - The first read goes back `history_days` (default 90, at most 3,650). ## How to connect 1. In Dfns, make a service account with a **read-only** role (`Wallets:Read`, `Wallets:Transfers:Read`) and a token for it. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Dfns**, and give the region (`eu`, the default, or `uae`). 3. Paste the token and the service account’s id (`service_account_id`, so its permissions can be read). Your browser seals it to your deployment; LightHouse never sees it. 4. Pin the token to your deployment’s egress addresses in Dfns. The credential is JSON in the variable the source names (`AAL_DFNS` by default): `token`, `service_account_id`, `region`, and `view_only_confirmed` when needed. ## Permissions This collector is **read-only**: it sends `GET` requests only, and its read-only test proves it on every change. Reads need only the bearer token; every Dfns call that changes state needs a user-action signature with the service account’s private key, which this collector never holds and never asks for. - **Refused by the code:** when the token may read service accounts (`GET /auth/service-accounts`), every operation assigned to the account and to its tokens is checked, and the account is refused, naming the operations, if it holds any of these: `Wallets:Transfers:Create`, `Wallets:Transactions:Create`, `Vaults:Transfers:Create`, `Vaults:Locks:Transfer`, `Vaults:Quarantines:Release`, `Payouts:Create`, `Payouts:Update`, `Payins:Create`, `Exchanges:Withdrawals:Create`, `Exchanges:Deposits:Create`, `Swaps:Create`, `Stakes:Create`, `Stakes:Update`, `Allocations:Create`, `Allocations:Update`, `Wallets:Offers:Settle`, `Keys:Signatures:Create`, `KeyStores:Instructions:Keys:Sign`, `Keys:Export`, `Policies:Evaluations:Vote`, `Permissions:Assign`, `Wallets:Signatures:Create`. The error is `Dfns: refused: the credential can \; make a view-only one`. - **Not detectable by the code:** if the token may not read service accounts (the narrowest read-only role gets a 403), or the listing does not include the account named, Dfns does not state the permissions. The collector then reads only once you have confirmed the account was given read-only permissions (`view_only_confirmed`). A service account made without a role inherits its creator’s permissions, which is the case the confirmation is for. An operation not on the list above would not be caught. - **Hosts:** `api.dfns.io` or `api.uae.dfns.io` by region, both over https; redirects are never followed. ## Limits - Pages of 100, following `nextPageToken`. - Requests are paced (0.1 s apart) and retried on 429 and 5xx with back-off. - Transfer amounts are shown as money only for native-asset transfers from a wallet whose native asset was read; others show the smallest-unit amount. - `region` must be `eu` or `uae`. ## Data handling - Records hold financial data: balances, amounts, wallet addresses and recipients’ addresses. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ---------------------------------------------- | | `Dfns: refused: the credential can Wallets:Transfers:Create ...; make a view-only one` | The account or a token holds a fund-moving operation | Make a read-only service account and reconnect | | `Dfns does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | The permissions cannot be read and you have not confirmed | Confirm the account is read-only | | `region is one of eu, uae` | The region is not one of those | Correct the region | | `Dfns answered HTTP 401` | The token is wrong or expired | Make a new token | | `Dfns answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | --------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Dfns REST API (unversioned paths) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/dfns/ --- # Dynamics 365 > Dynamics 365: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads accounts, opportunities and cases from a Dynamics 365 (Dataverse) environment, so commercial and service agents can answer from the account and case history. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Dynamics 365, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Microsoft: Dynamics 365 (Dataverse Web API) ([the vendor's documentation](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/overview)) | | Family | CRM | | Kind | CRM | | Ways to connect | OAuth approval | | Scopes | - Read: `/.default` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `{org}.crm{region}.dynamics.com`, `login.microsoftonline.com` | | Vendor API versions | Dataverse Web API v9.2 | | Lowest engine version | `0.46.0` | ## What it reads - **Accounts:** name, account number, industry, website, city, country, description, primary contact (as its formatted name). - **Opportunities:** name, customer, state, sales stage, estimated value, estimated close date, close probability, description. - **Cases** (the `incident` table): title, ticket number, customer, state, priority, case type, description. - Only the tables you name in `objects` (`accounts`, `opportunities`, `cases`), and only the columns above (`$select`), with lookups as their formatted names. - Changes only: each table is read by `modifiedon` (UTC), oldest first, 500 a page, following `@odata.nextLink`, which must stay on the environment’s host. ## How to connect 1. In Microsoft Entra, make an app registration with a certificate, as for SharePoint, and note the directory (tenant) id and application (client) id. 2. In your Dynamics 365 environment, add the app as an **application user** with a security role that is a read-only copy over the three tables. 3. In LightHouse, open **Setup and admin, Connectors**, choose **Dynamics 365**, and give `environment_url` (`https://.crm.dynamics.com`, or `crm2`, `crm4` and so on for your region) and `objects`. 4. Paste the certificate’s private key. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`DYNAMICS_CREDENTIAL` by default): `tenant_id`, `client_id`, `certificate` and `environment_url`. ## Permissions - **Scope requested:** `/.default`: a token for that environment alone, minted from a certificate assertion signed in your own account (client-credentials grant). No client secret exists. - Dataverse states no permissions in the token, so **read-only is the security role you give the application user**: a copy of a read-only role over accounts, opportunities and cases. The connection check says so. - **What the collector does:** `GET` requests to `/api/data/v9.2/`, plus one `POST` to Microsoft’s token endpoint (`login.microsoftonline.com//oauth2/v2.0/token`) for the access token. Its read-only test proves that on every change. - **Hosts:** your environment and Microsoft’s login host. A next-page link to any other host is refused. ## Limits - Dataverse Web API v9.2. - `environment_url` must look like `https://.crm.dynamics.com` (with an optional region number after `crm`). - Pages of 1 to 5,000 rows (`page_size`, default 500). - Deletions are found by listing primary keys every six hours; a deleted record is removed from the corpus then, not at once. - A table the role cannot list (403 or 404) skips the deletion check for it rather than failing the read. ## Data handling - Accounts, contacts’ names and cases hold personal data. Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. - The private key is used only to sign the assertion; it is never put in a request, a log line or an error message. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------ | ------------------------------------------------------------- | ------------------------------------------------------ | | `credential variable 'DYNAMICS_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect Dynamics 365 again in LightHouse | | `the dynamics credential has no environment_url` | A field (named in the message) is missing | Re-enter all four fields | | `environment_url is https://.crm.dynamics.com` | The URL is not a Dataverse environment | Use the environment’s own address | | `tenant_id is the directory's id, a GUID` | `tenant_id` is not a GUID | Copy the directory id from Entra | | `HTTP 401` or `HTTP 403` | The app is not an application user, or its role lacks a table | Add the application user and give it read on the table | | `HostNotAllowed` (`... is not an allowed host`) | A next-page link named another host | Report it; nothing was sent there | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Dataverse Web API v9.2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/dynamics/ --- # EASA Easy Access Rules > EASA Easy Access Rules: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Certified Certified by Atlantic Agentic Labs on 7 November 2026, against Easy Access Rules downloads (PDF, HTML); no versioned API; expires 7 May 2027. Reads the European Union Aviation Safety Agency’s Easy Access Rules: the consolidated rules, acceptable means of compliance and guidance material for a domain, as EASA publishes them for download. EASA has no versioned API for them, so you name each document by its download address and the collector notices when the bytes change. ## At a glance | Collector | EASA Easy Access Rules, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | European Union Aviation Safety Agency: Easy Access Rules (download library) ([the vendor's documentation](https://www.easa.europa.eu/en/document-library/easy-access-rules)) | | Family | Regulation | | Kind | Regulation | | Ways to connect | None (no credential) | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `www.easa.europa.eu` | | Vendor API versions | Easy Access Rules downloads (PDF, XML, HTML); no versioned API | | Lowest engine version | `0.45.0` | ## What it reads - The documents you name, each by an `https://` address on [www.easa.europa.eu](http://www.easa.europa.eu): PDF downloads, XML downloads, or library pages (HTML). - For each document: its text, with the title you give it and a link to where it was read. - A document is read again only when its bytes change (the collector compares their SHA-256). A document you remove from the list is withdrawn from the knowledge base. It does not search the EASA site or follow links from a page: a site redesign would otherwise change what is read without anyone deciding to. ## How to connect 1. In LightHouse, open **Connectors** and choose **EASA Easy Access Rules**. 2. For each document, give an id of your own (for example `ear-air-ops`), its download address (from the document’s page in EASA’s library) and a title. 3. Choose a label (normally `regulation`) and how often to read. Weekly is usually enough: EASA revises each set a few times a year. No credential is needed. ## Permissions None. The collector sends only `GET` requests, without credentials, to `www.easa.europa.eu` (or any other host you add to the source’s allowed hosts). Its read-only test proves it on every change, and the certification run recorded every request it made against the live library. ## Limits - EASA’s downloads do not answer conditional requests, so each read downloads every document in full (tens of megabytes for a large set) and then compares it. Read weekly, not hourly. - PDFs are read with `pdftotext` (poppler-utils). The Atlantic Agentic gateway image includes it from engine 0.47.0; on a deployment that does not use our image, install it where the collector runs. A scanned PDF with no text layer gives an empty document. - ZIP downloads (some XML editions come zipped) are not read; name the PDF or the unzipped XML instead. - Requests are paced (one second apart by default) and back off when EASA asks (`Retry-After`). ## Data handling - The documents are public; they carry no personal data. Reuse is subject to EASA’s legal notice; set the source’s `licence` to record it. - The raw bytes are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. - Nothing leaves your deployment: the collector runs inside it, and only the counts of documents read reach LightHouse. - XML is parsed with `defusedxml`, which refuses entity expansion and external entities. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------- | | `documents without an https url` | An address is not `https://` | Use the address from EASA’s library | | `no reader for application/zip` | The address is a ZIP download | Name the PDF edition instead | | `pdftotext is not installed` | The deployment lacks the PDF reader (our gateway image has it from engine 0.47.0) | Update the image, or install poppler-utils where the collector runs | | `HostNotAllowed` | The address, or a redirect, is not on an allowed host | Add the host, if you trust it | | Read succeeded, 0 written | No document’s bytes changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | --------------- | --------- | -------- | --------------------------------------------------------- | ----------------------------------- | -------------- | | 7 November 2026 | `1.0.0` | `0.45.0` | Easy Access Rules downloads (PDF, HTML); no versioned API | Vendor's sandbox (a real run) | 7 May 2027 | | 7 November 2026 | `1.0.0` | `0.45.0` | Easy Access Rules downloads (PDF, HTML); no versioned API | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/easa/ --- # ECCAIRS 2 > ECCAIRS 2: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads your organisation’s occurrence reports from EASA’s ECCAIRS 2 (E2), read-only, inside your deployment, with reporters left out. ## At a glance | Collector | ECCAIRS 2, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | EASA (European Union Aviation Safety Agency): ECCAIRS 2 (E2) API ([the vendor's documentation](https://www.easa.europa.eu/en/domains/safety-management/aviation-safety-reporting/aviation-safety-reporting-organisations)) | | Family | Aviation | | Kind | Occurrences | | Ways to connect | OAuth approval | | Scopes | - Read: | | Read only | Yes, except: \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact | | Hosts it may contact | `api.aviationreporting.eu`, `*.aviationreporting.eu` | | Vendor API versions | E2 API Guide v4.19, OAuth 2.0 client credentials (EASA's 2026 change) | | Lowest engine version | `0.46.0` | ## What it reads - Occurrence reports modified since the last run (on the first run, within the last `days_back` days: 1 to 3650, default 365), through `POST /occurrences/readable/result/bool/scroll`, a query with a range on `modificationDate`, paged by `scrollId` (valid 30 minutes) in pages of `page_size` (1 to 10000, default 200). - One record per occurrence, keyed by E2’s `e2Id`, with its status, version and type. - These POSTs are queries: the only calls this source makes besides the token request. ## How to connect 1. Ask EASA’s ECCAIRS2 support for an API client for your organisation. Access needs your organisation’s E2 roles, and EASA allow-lists your deployment’s address. 2. In LightHouse, open **Setup and admin, Connectors**, choose **ECCAIRS 2**, and leave the access level at **Read**. 3. Name `token_url` only if EASA gave you one; otherwise E2’s own (`{base}/idp/oauth2/token`) is used. Name the reporter attributes of your taxonomy version in `exclude_fields` (for example `**.ATTRIBUTES.`): E2 holds values under numeric ids, and this collector does not guess them. 4. Paste the client id and then the secret. Your browser seals them to your deployment, which hands them to the collector as `ECCAIRS_CLIENT_ID` and `ECCAIRS_CLIENT_SECRET`. ## Permissions - OAuth client credentials only, as EASA’s 2026 change requires. The collector requests no scope and refuses a token whose granted scope names a write; the credential check says so. - It sends `POST` only to the two reads in the manifest’s `read_operations`: the token request and the occurrence query. - Your deployment refuses to store this credential at read and write. Only hosts ending `.aviationreporting.eu` are accepted. ## Limits - The E2 API Guide (v4.19) is written for authorities. Whether an organisation’s role can read its own submitted reports through these endpoints, the token path under the API base and the IP allow-list are the questions onboarding settles with EASA’s ECCAIRS2 support. - The token path follows the French DSAC’s webinar of 24 March 2026 (organisations to move to client credentials by June 2026); confirm it at onboarding. - Incremental by `modificationDate`, to the day: the day of the last run is read again, and unchanged records are not rewritten. - A scroll stops on an empty page or when the total is reached; more than `max_pages` (1000) pages fails the run. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never an occurrence or a reporter. - Reporters are protected by default: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details are left out of every record before it is written, as are travel document numbers and dates of birth. Just culture and data protection both need a reporter kept from anyone who does not need them. Names are matched whatever the case, spacing, `_` or `-`, so `reporterName` also catches an export’s `Reporter Name`. - `exclude_fields` adds paths (for example `**.contact`); `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. Free-text narratives are indexed as written and may still name people: add the fields that hold them to `exclude_fields`. - Nothing is cached raw, and a failure names the host and the status, never the URL. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `credential variable 'ECCAIRS_CLIENT_ID' is not set` | The deployment has not been given the client | Connect the credential again | | `POST api.aviationreporting.eu: HTTP 401` | EASA refused the client or the token | Check the client has not been revoked and that EASA has allow-listed your deployment’s address | | `POST api.aviationreporting.eu: HTTP 403` | The organisation’s role cannot read these endpoints | Ask EASA’s ECCAIRS2 support (see Limits) | | `POST api.aviationreporting.eu: no access token` | The token path is not the one EASA uses for you | Ask EASA for the token path and set `token_url` | | `ECCAIRS 2 is reached on EASA's aviationreporting.eu hosts only` | `base_url` or `token_url` is another host, or `base_url` is not https | Use the addresses EASA gave you | | `page_size is 1 to 10000 and days_back 1 to 3650` | A setting is out of range | Correct it | | `eccairs: more than 1000 pages; raise max_pages` | The scroll did not end | Narrow `days_back`, or raise `max_pages` after checking the query | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | E2 API Guide v4.19; OAuth 2.0 client credentials | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/eccairs/ --- # US Electronic Code of Federal Regulations (eCFR) > US Electronic Code of Federal Regulations (eCFR): what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Certified Certified by Atlantic Agentic Labs on 7 November 2026, against eCFR versioner API v1; expires 7 May 2027. Reads named parts of the US Code of Federal Regulations from the eCFR, the Office of the Federal Register’s continuously updated edition, through its public versioner API. Each section (and each appendix) becomes one document, so a citation names the section, not “somewhere in Part 121”. ## At a glance | Collector | US Electronic Code of Federal Regulations (eCFR), version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | Reads | US Office of the Federal Register: eCFR versioner API ([the vendor's documentation](https://www.ecfr.gov/developers/documentation/api/v1)) | | Family | Regulation | | Kind | Regulation | | Ways to connect | None (no credential) | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `www.ecfr.gov` | | Vendor API versions | eCFR versioner API v1 | | Lowest engine version | `0.45.0` | ## What it reads - The parts you name of one CFR title (title 14, Aeronautics and Space, by default): for example `121` and `135`. - For each part: every section and appendix in the current text, with its heading, its number and a link to it on [www.ecfr.gov](http://www.ecfr.gov). - A part is read again only when the eCFR records a new amendment date for it. A section the amendment removed is withdrawn from the knowledge base. It never reads a whole title: you name the parts. ## How to connect 1. In LightHouse, open **Connectors** and choose **eCFR**. 2. Name the title (14 unless you say otherwise) and the parts to read. 3. Choose a label (normally `regulation`) and how often to read. The eCFR is updated daily; a daily read costs one small request per part when nothing has changed. No credential is needed. ## Permissions None. The collector sends only `GET` requests, without credentials, to `www.ecfr.gov`. Its read-only test proves it on every change, and the certification run recorded every request it made against the live eCFR. ## Limits - One title per source; add a source per title. - Reserved sections (“\[Reserved]”) are kept with their heading and an empty body, so a question about them is answered with “reserved”, not silence. - The eCFR is an editorial compilation, not the official legal edition (the annual CFR and the Federal Register are). Each record says where it came from and when. - Requests are paced (one second apart by default) and back off when the eCFR asks (`Retry-After`). ## Data handling - The text is public and in the public domain (17 U.S.C. 105); it carries no personal data. - The raw XML is cached in your deployment, named by its SHA-256, so any passage can be traced to what was served. - Nothing leaves your deployment: the collector runs inside it, and only the counts of sections read reach LightHouse. - XML is parsed with `defusedxml`, which refuses entity expansion and external entities. ## Troubleshooting | What you see | What it means | What to do | | ----------------------------- | ------------------------------------------------- | -------------------------------------------- | | `not CFR part numbers` | A part is not a number (optionally with a letter) | Use the part number alone, for example `121` | | `the eCFR lists no versions` | The part does not exist in that title | Check the title and part | | `no sections in the eCFR XML` | The eCFR returned the part with no sections | Retry later; if it persists, report it to us | | `HTTPStatusError 429` | The eCFR is rate-limiting | It backs off by itself; read less often | | Read succeeded, 0 written | No part has been amended since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | --------------- | --------- | -------- | --------------------- | ----------------------------------- | -------------- | | 7 November 2026 | `1.0.0` | `0.45.0` | eCFR versioner API v1 | Vendor's sandbox (a real run) | 7 May 2027 | | 7 November 2026 | `1.0.0` | `0.45.0` | eCFR versioner API v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/ecfr/ --- # EUR-Lex (EU law, consolidated) > EUR-Lex (EU law, consolidated): what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Certified Certified by Atlantic Agentic Labs on 7 November 2026, against Cellar SPARQL 1.1 (CDM ontology); EUR-Lex legal-content HTML; expires 7 May 2027. Reads named EU acts from EUR-Lex in their latest consolidated version: the text that applies today, with every amendment folded in. The Publications Office’s public SPARQL endpoint says which consolidation is newest; an act is read again only when a new one appears. ## At a glance | Collector | EUR-Lex (EU law, consolidated), version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Publications Office of the European Union: EUR-Lex and the Cellar SPARQL endpoint ([the vendor's documentation](https://op.europa.eu/en/web/cellar/cellar-data/metadata/knowledge-graph)) | | Family | Regulation | | Kind | Regulation | | Ways to connect | None (no credential) | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `publications.europa.eu`, `eur-lex.europa.eu` | | Vendor API versions | Cellar SPARQL 1.1 (CDM ontology), EUR-Lex legal-content HTML | | Lowest engine version | `0.45.0` | ## What it reads - The acts you name by CELEX number (for example `32012R0965`, the EU air operations regulation). - For each act: the full text of its newest consolidated version, in the language you choose (English by default), with its title, its date and a link to it on eur-lex.europa.eu. An act that has never been consolidated is read as adopted. ## How to connect 1. In LightHouse, open **Connectors** and choose **EUR-Lex**. 2. Name the acts by CELEX number. EUR-Lex shows it on every act’s page. 3. Choose a language (a two-letter code, `EN` by default), a label (normally `regulation`) and how often to read. A daily or weekly read costs one query when nothing has changed. No credential is needed. ## Permissions None. The collector sends only `GET` requests, without credentials, to `publications.europa.eu` (the SPARQL query, sent as a `GET`) and `eur-lex.europa.eu` (the text). Its read-only test proves it on every change, and the certification run recorded every request it made against the live services. ## Limits - The consolidated text is the Publications Office’s convenience version, not the authentic text published in the Official Journal. Each record says so in its metadata, and an answer that quotes it can say so too. - Each act is one document, however long: the consolidated air operations regulation is over a million characters. - Requests are paced (one second apart by default) and back off when the service asks (`Retry-After`). ## Data handling - The text is public: © European Union, reused under Commission Decision 2011/833/EU. It carries no personal data. - The raw HTML is cached in your deployment, named by its SHA-256, so any passage can be traced to what was served. - Nothing leaves your deployment: the collector runs inside it, and only the counts of acts read reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | --------------------------- | ---------------------------------------------------- | ------------------------------------------------------------- | | `not CELEX numbers of acts` | A number is not an act’s CELEX number | Copy it from the act’s EUR-Lex page, for example `32018R1139` | | `not a language code` | The language is not two capital letters | Use `EN`, `FR`, `DE` and so on | | `HTTPStatusError 503` | EUR-Lex or the SPARQL endpoint is busy | It retries by itself; read again later | | Read succeeded, 0 written | No act has a newer consolidation since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | --------------- | --------- | -------- | ------------------------------------------------------------ | ----------------------------------- | -------------- | | 7 November 2026 | `1.0.0` | `0.45.0` | Cellar SPARQL 1.1 (CDM ontology); EUR-Lex legal-content HTML | Vendor's sandbox (a real run) | 7 May 2027 | | 7 November 2026 | `1.0.0` | `0.45.0` | Cellar SPARQL 1.1 (CDM ontology); EUR-Lex legal-content HTML | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/eurlex/ --- # Flight data monitoring exports > Flight data monitoring exports: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads event and exceedance exports from your flight data monitoring (FDM or FOQA) tool, row by row, from a bucket prefix or an SFTP drop your deployment mounts, read-only. ## At a glance | Collector | Flight data monitoring exports, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Flight data monitoring tools (Safran, CAE): FDM / FOQA event and exceedance exports ([the vendor's documentation](https://www.cassiopee.aero/)) | | Family | Aviation | | Kind | Flight data | | Ways to connect | None (no credential), Service account | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | CSV and JSON exports (no vendor API) | | Lowest engine version | `0.46.0` | ## What it reads - Every `.csv` file (and `.json` list of objects) under the prefix you name: each row is one record, keyed by `id_columns` and titled by `title_columns`. - Flight data monitoring tools (Safran Cassiopée, CAE Flightscape and their successors) publish no read API; they export events and exceedances as files, CSV the long-standing format. This collector reads those files and never connects to the tool. ## How to connect 1. Make the export write to a bucket prefix, or to an SFTP server whose landing directory the deployment mounts. 2. Your engineer sets this source up in the source card (there is no key to paste): `store` (`s3://bucket/prefix/`, `gs://`, `azblob://` or `file:/path`), `id_columns` (what identifies a row), `title_columns` (the fields joined for the title), and for S3 a `role_arn` (and `external_id`, `region`). 3. Give the role read access to that prefix only. In LightHouse the card reads **Read**. ## Permissions - No credential is stored. The deployment’s identity, or the role it assumes, is the permission; grant list and get on the one prefix and nothing else. - The collector only lists and reads objects (and, for a `file:` store, reads files). It never writes, moves or deletes an export. Its read-only test uses a stub S3 client that records every operation and fails on any but list and get, and checks that a drop folder is byte-for-byte unchanged afterwards; there is no HTTP to record. - Nothing here connects to the system that produced the export, so nothing here could change it. ## Limits - Only files ending `.csv` or `.json` (a list of objects) are read; others are ignored. - A file is read again only when its ETag changes. Files larger than `max_mb` (50 by default) are skipped and counted. - Column names are the export’s own and none is assumed: set `id_columns` (otherwise a row’s hash is its id, so an edited row becomes a new record and the old one is withdrawn) and `title_columns`. - Rows that leave a file, and files that are removed, become withdrawals. - Google Cloud Storage and Azure Blob stores are read through the engine’s adapters, which need their own identity libraries in the deployment. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a row. - FDM is de-identified by programme agreement, and an event export should carry no crew identity; where an export carries more, add its columns to `exclude_fields`. - Contact fields and reporter names are left out by default, as are travel document numbers and dates of birth. `exclude_fields` adds columns (for example `**.Captain`); `keep_fields` takes a default back by its exact name. Nothing is cached raw. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------- | --------------------------------------------------------- | ------------------------------------ | | `a source needs its label` | No label was given | Give the source a label | | `the store's prefix is a plain path` | The prefix holds characters a path cannot | Use a plain prefix | | Read succeeded, nothing written | No file’s ETag has changed since the last read | Nothing to do | | Fewer rows than expected | A file over `max_mb` was skipped (the source counts them) | Raise `max_mb`, or split the export | | A title of the form `: #` | `title_columns` is not set, or its columns were empty | Name the columns for the title | | Rows reappear as new records | `id_columns` is not set, so ids are row hashes | Name the columns that identify a row | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | CSV and JSON exports | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/fdm/ --- # RSS and Atom feeds > RSS and Atom feeds: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Certified Certified by Atlantic Agentic Labs on 7 November 2026, against RSS 2.0; Atom 1.0 (RFC 4287); expires 7 May 2027. Reads a publisher’s RSS 2.0 or Atom 1.0 feed: a regulator’s notices, a standards body’s updates, a vendor’s security advisories, a news desk. Each item becomes one document in the knowledge base, kept with its link and the hash of exactly what the publisher served. ## At a glance | Collector | RSS and Atom feeds, version `1.0.1` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------- | | Reads | Any publisher: RSS 2.0 and Atom 1.0 feeds ([the vendor's documentation](https://www.rfc-editor.org/rfc/rfc4287)) | | Family | Web | | Kind | Feed | | Ways to connect | None (no credential) | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | RSS 2.0, Atom 1.0 (RFC 4287) | | Lowest engine version | `0.45.0` | ## What it reads - The feed at the address you give, and nothing it links to. - For each item: its title, its summary or content (with markup removed), its link, its identifier (`guid` or Atom `id`) and its date (`pubDate`, Atom `updated` or `published`). - Only items newer than the last one read. The first read takes everything the feed currently lists. It does not follow links, download attachments or read pages behind a sign-in. ## How to connect 1. In LightHouse, open **Connectors** and choose **RSS and Atom feeds**. 2. Paste the feed’s address. It must start with `https://`. 3. Add the feed’s host to the source’s allowed hosts (LightHouse fills in the host of the address you pasted). If the publisher redirects to another host, add that host too, or the read stops at the redirect. 4. Choose a label for what the feed contains (for example `regulation` or `internal`) and how often to read it. Nothing reads on a schedule until you choose one. No credential is needed: a feed that requires a sign-in is not supported by this collector. ## Permissions None. The collector sends only `GET` requests, with no credentials, to the hosts you allow. Its read-only test proves it on every change. ## Limits - One feed per source. Add a source per feed. - Items without an identifier or a link are skipped. - Dates are read as RFC 822 (RSS `pubDate`) or ISO 8601 (Atom) and compared in UTC. An item whose date cannot be read is offered on every read; unchanged items are not rewritten, so this costs a fetch, not duplicates. - An item with no summary or content (some publishers list titles and links only) is kept with its title and link and an empty body. - Requests are paced (one second apart by default) and back off when the publisher asks (`Retry-After`). - Plain `http://` feeds are refused. ## Data handling - Feeds are public by nature; the collector expects no personal data. If a feed carries some (a named author, for example), it is kept as the publisher wrote it and labelled like the rest of the item. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. - Nothing leaves your deployment: the collector runs inside it, and only the counts of items read reach LightHouse. - XML is parsed with `defusedxml`, which refuses entity expansion and external entities. ## Troubleshooting | What you see | What it means | What to do | | ------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------- | | `HostNotAllowed` | The feed, or a redirect, is on a host not in the source’s allowed hosts | Add the host, if you trust it | | `non-https` | The address or a redirect uses plain `http://` | Ask the publisher for an https feed | | `EntitiesForbidden` | The feed uses XML entities, which are refused | Report it to the publisher; it cannot be read safely | | `HTTPStatusError 404` | The feed has moved | Update the address | | Read succeeded, 0 written | Nothing newer than the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | --------------- | --------- | -------- | ---------------------------- | ----------------------------------- | -------------- | | 7 November 2026 | `1.0.1` | `0.45.0` | RSS 2.0; Atom 1.0 (RFC 4287) | Vendor's sandbox (a real run) | 7 May 2027 | | 6 November 2026 | `1.0.0` | `0.45.0` | RSS 2.0; Atom 1.0 (RFC 4287) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/feed/ --- # Fireblocks > Fireblocks: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Fireblocks workspace’s vault accounts, asset balances and transactions, so treasury and reconciliation agents can check custody against the books. It is read-only, and it is built to refuse a key that can move funds. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Fireblocks, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Reads | Fireblocks: Fireblocks API (vault accounts, balances, transactions) ([the vendor's documentation](https://developers.fireblocks.com/reference/api-overview)) | | Family | Finance | | Kind | Custody | | Ways to connect | Key pair | | Scopes | - Read: `Viewer` | | Read only | Yes | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.fireblocks.io`, `eu-api.fireblocks.io`, `eu2-api.fireblocks.io`, `sandbox-api.fireblocks.io`, `{host}` | | Vendor API versions | REST API v1 | | Lowest engine version | `0.46.0` | ## What it reads - **Vault accounts and their asset balances:** for each vault and asset, the total, available, pending, frozen and locked amounts, each with its asset code. Balances are a snapshot: one record per vault and asset, rewritten only when it changes and removed when the asset disappears. - **Transactions:** read by `lastUpdated`, oldest first, so a transaction whose status changes after it was read is read again and its record rewritten. Each carries its operation, status and sub-status, amounts (requested, net, amount), network fee, source and destination type and name, hash and dates. - The first read goes back `history_days` (default 90, at most 3,650). It does not read addresses’ private material, policies, users, or webhooks. ## How to connect 1. In Fireblocks, make an API user with the **Viewer** role and upload the CSR of an RSA key pair you made yourself. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Fireblocks** and give the region (`us`, `eu`, `eu2` or `sandbox`). 3. Paste the API key and the RSA private key, and confirm the role is Viewer. Your browser seals it to your deployment; LightHouse never sees it. 4. Pin the API user to your deployment’s egress addresses in Fireblocks. The credential is JSON in the variable the source names (`AAL_FIREBLOCKS` by default): `api_key`, `private_key`, `region`, and `view_only_confirmed` (`yes`). ## Permissions This collector is **read-only**. It sends `GET` requests only, and its read-only test proves it on every change. The checks below run first on every pull and in the health check; nothing is read with a key that fails. - **Refused by the code:** an API user that may list API users (`GET /v1/management/api_users`), which Fireblocks allows only to the **Admin** and **Non-Signing Admin** roles. The error is `Fireblocks: refused: the credential can administer the workspace (Admin or Non-Signing Admin role); make a view-only one`. - **Not detectable by the code:** Fireblocks gives an API key no way to read its own role, so a key that is *not* an administrator is not shown to be a Viewer. An **Editor**, **Signer** or **Approver** key (which can create transactions or sign) would pass the check above. The collector therefore reads only once you have confirmed the role is Viewer (`view_only_confirmed`); without it the error is `Fireblocks does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read`. Make the key a Viewer in Fireblocks: that, not this code, is what stops a key from moving funds. - **Signing:** each request carries a JWT signed here with your private key (RS256; `uri`, `nonce`, `iat`, `exp` 25 seconds on, `sub` the key, `bodyHash` the SHA-256 of the body). The private key never leaves your store. - **Hosts:** only Fireblocks’ own region hosts. A next-page link to any other host is refused (`a next page on another host`), a redirect is never followed, and plain `http` is refused. ## Limits - API v1. Vaults are read 200 a page and transactions 200 a page, following Fireblocks’ `next-page` header. - Requests are paced (0.1 s apart) and retried on 429 and 5xx with back-off. - Amounts are exact decimals; a number that arrives as a float is refused. - `region` must be one of `us`, `eu`, `eu2`, `sandbox`. - Fireblocks is the system of record: an amount here is as of the last read. ## Data handling - Records hold financial data: balances, transaction amounts and the names of vaults and counterparties’ account types. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body: a provider’s error can echo a key, an account or a balance. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ | | `Fireblocks: refused: the credential can administer the workspace (Admin or Non-Signing Admin role); make a view-only one` | The API user is an administrator | Make a Viewer API user and reconnect | | `Fireblocks does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | The role cannot be read, and you have not confirmed it | Confirm the role is Viewer | | `region is one of us, eu, eu2, sandbox` | The region is not one of those | Correct the region | | `Fireblocks answered HTTP 401` | The API key or the signature is wrong | Check the key and that the private key matches the CSR | | `Fireblocks answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | | `Fireblocks: refusing a request to a host that is not the provider's` | A request named another host | Report it; nothing was sent there | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | REST API v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/fireblocks/ --- # FlightAware AeroAPI > FlightAware AeroAPI: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads an operator’s and an airport’s flights (schedule, gates, delays, diversions and cancellations) from FlightAware AeroAPI v4, read-only, inside your deployment. ## At a glance | Collector | FlightAware AeroAPI, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Reads | FlightAware: FlightAware AeroAPI v4 ([the vendor's documentation](https://static.flightaware.com/rsrc/aeroapi/aeroapi-openapi.yml)) | | Family | Aviation | | Kind | Flights | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `aeroapi.flightaware.com` | | Vendor API versions | AeroAPI 4.30.0 (OpenAPI document) | | Lowest engine version | `0.46.0` | ## What it reads - **Operators:** `GET /operators/{id}/flights`: scheduled, arrived and en-route flights of each operator you name (ICAO codes are preferred, as FlightAware advises). - **Airports:** `GET /airports/{id}/flights`: scheduled and actual arrivals and departures of each airport you name. - One record per flight, keyed by `fa_flight_id`, FlightAware’s id for the flight, with its route, status, registration and whether it was cancelled or diverted. - The window runs from `hours_back` (1 to 240, default 24) before now to `hours_ahead` (0 to 48, default 48) after; AeroAPI serves at most 10 days back and 2 ahead. You must name operators or airports: a whole feed is never the default. ## How to connect 1. Make an AeroAPI key at FlightAware (Personal tier for testing, Standard for production). 2. In LightHouse, open **Setup and admin, Connectors**, choose **FlightAware AeroAPI**, and leave the access level at **Read**. 3. Name the `operators` and `airports`, and set `per_second` to your tier’s rate: 0.1 for Personal (10 a minute), 5 for Standard, up to 100 for Premium. 4. Paste the key. Your browser seals it to your deployment, which hands it to the collector as `AEROAPI_KEY` (`credential_env`). ## Permissions - `GET` only, with the key as `x-apikey`. The only writes AeroAPI has are alert configurations, and nothing here calls them. - Your deployment refuses to store this credential at read and write. - Only `aeroapi.flightaware.com` is contacted. The read-only test proves it on every change. ## Limits - **Cost is bounded per run.** AeroAPI bills per result set (a page of up to 15 records). `max_result_sets` (200 by default) stops a run first and fails it, rather than indexing half a window as if it were all of it. - AeroAPI offers no changed-since. Each run reads from the previous run’s start, less an hour’s overlap, to `hours_ahead`; a flight whose record has not changed is not rewritten. - `per_second` sets the pace (default 0.1, one request every ten seconds); set it to your tier or you will be throttled. - Paging follows the opaque cursor in `links.next`. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a flight record. - Nothing is cached raw, and a failure names the host and the status, never the URL. - Flight status carries no passenger data. The standard exclusions still apply to every record before it is written (travel document numbers, dates of birth, health or disability special service requests); `exclude_fields` adds paths and `keep_fields` takes a default back by its exact name. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------- | --------------------------------------------------------------------------------------- | | `credential variable 'AEROAPI_KEY' is not set` | The deployment has not been given the key | Connect the credential again | | `GET aeroapi.flightaware.com: HTTP 401` | FlightAware refused the key | It may be revoked or for another product; make a new one | | `GET aeroapi.flightaware.com: HTTP 429` | Your tier’s rate limit, after the retries | Lower `per_second`, or move up a tier | | `flightaware: max_result_sets (200) reached before the window was read; raise it or narrow the window` | The window holds more pages than the cap allows | Narrow `hours_back`, name fewer airports, or raise the cap knowing every page is billed | | `name operators or airports; a whole feed is never the default` | Neither was named | Name at least one | | `hours_back is 1 to 240 and hours_ahead 0 to 48 (AeroAPI's window)` | The window is outside what AeroAPI serves | Narrow it | | `per_second is the account tier's rate, above 0 and at most 100` | An impossible rate | Use your tier’s rate | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | AeroAPI 4.30.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/flightaware/ --- # Local folders > Local folders: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the documents in a folder on the deployment’s own storage: manuals dropped into an inbox, meeting transcripts, an export from another system, a synced Drive or SharePoint library. Each file becomes one document. It is the common landing place for anything that arrives as files, and it uses no network at all. ## At a glance | Collector | Local folders, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Atlantic Agentic Labs: Drop folder (files on the deployment's disk) ([the vendor's documentation](https://docs.atlanticagenticlabs.com/connect/upload/)) | | Family | Storage | | Kind | Files | | Ways to connect | None (no credential) | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content | | Hosts it may contact | `localhost` | | Vendor API versions | none (local files) | | Lowest engine version | `0.45.0` | ## What it reads - Every file of an accepted type in the folder and its subfolders: `.md`, `.txt` and `.vtt` as text, and `.pdf` through `pdftotext -layout`. - A file may begin with front matter that sets its own `title` and a class (`doc_class`, `label` or `sensitivity`); your label scheme still decides whether that class is readable. - A file is read again only when its SHA-256 changes. A file that disappears becomes a tombstone, so the knowledge base stops citing a document that was withdrawn. - Files whose names start with `.` are ignored. ## How to connect 1. Put the folder where the deployment can read it (`path` is relative to the deployment’s working directory, or absolute). 2. Add a source card with `kind: folder`, the `path`, a `label`, and the `requires` block naming what is read and why. 3. The source is named `folder-` unless you give it a `name`. No credential is involved. Install `pdftotext` (poppler) in the image if the folder holds PDFs. ## Permissions Read access to the folder, and nothing else. The collector opens files for reading only; it never writes, renames or deletes in the folder, and it makes no network request. Its read-only test runs it against a folder the operating system will not let it write to and checks the folder is unchanged. ## Limits - A file of a type the collector cannot read **fails the pull**, and the error names the file (`is not an accepted format here`), because an unreadable document skipped silently is a gap nobody hears about. Narrow `suffixes` to accept fewer types. - PDFs need `pdftotext` and take at most 300 seconds a file. - There is no size limit per file; a very large folder is read in one pull. - The change test is the content hash, so a file touched but not edited costs a read of its bytes and nothing more. ## Data handling - Everything stays in the deployment: the folder and the corpus written from it are on its own storage. Only the counts (written, unchanged, quarantined, removed) reach LightHouse. - The document text may hold personal data of any kind; it is labelled by the source’s `label` (or the file’s own class) and handled under that label’s rules. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | `is not an accepted format here` | A file in the folder has a suffix the source does not accept | Remove it, or move it out; or accept the suffix if the collector can read it | | `no reader for` | The suffix is accepted by `suffixes` but the collector has no reader for it | Convert the file to text or PDF | | `pdftotext is not installed` | A PDF was found and the tool is not in the image | Install poppler-utils in the deployment image | | Read succeeded, 0 written | No file changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | none (local files) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/folder/ --- # Google Drive > Google Drive: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the documents in the Google Drive folders and shared drives you name, so agents can answer from the team’s working documents. It follows Drive’s change feed, so only what changed is read, and what the owner withdraws is withdrawn from the knowledge base. ## At a glance | Collector | Google Drive, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------- | | Reads | Google: Google Drive ([the vendor's documentation](https://developers.google.com/drive/api/guides/about-sdk)) | | Family | Storage | | Kind | Files | | Ways to connect | Service account, OAuth approval | | Scopes | - Read: `https://www.googleapis.com/auth/drive.readonly` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `www.googleapis.com` | | Vendor API versions | Google Drive API v3 | | Lowest engine version | `0.45.0` | ## What it reads - Everything beneath the folders you name (`folders`, by folder id) and the whole of the shared drives you name (`drives`). - Google Docs and Slides, exported as plain text; Google Sheets, exported as CSV (Drive exports the first sheet only); plain text, Markdown and CSV files, downloaded as they are. - Anything else (images, PDFs, archives) is skipped and counted in the log, not refused by name: a shared drive always holds an image, and refusing it would stop every document in the drive from being read. - The cursor is Drive’s changes page token, kept with the ids in scope. A file deleted, trashed or moved out of scope becomes a withdrawal. If a folder leaves scope, the whole scope is read again, which costs nothing for unchanged files. ## How to connect 1. Create a service account for LightHouse’s reading, or use the account your platform already mints tokens with. 2. Share the folders or shared drives with the service account’s address, or, to read a personal Drive, grant the service account domain-wide delegation for `https://www.googleapis.com/auth/drive.readonly` and nothing broader. 3. In LightHouse, open **Connectors**, choose **Google Drive**, name the folders or shared drives, the label and how often to read, and attach the service-account key. Where your deployment keeps credentials in your own store, the key is sealed in your browser and LightHouse never sees it. 4. In code, give the deployment an OAuth access token with the `drive.readonly` scope as `GDRIVE_TOKEN` (minting and refreshing it is your platform’s job; the collector holds no refresh token) and add a `kind: gdrive` source card with `folders` and/or `drives`, `label` and `requires`. ## Permissions `https://www.googleapis.com/auth/drive.readonly` only. The collector sends only `GET` requests to `www.googleapis.com`: `/drive/v3/files` (including shared drives), `/drive/v3/changes` and its start token, `/drive/v3/files/{id}/export` and `/drive/v3/files/{id}?alt=media`. It never writes, even when the connection is made with a wider scope. Its read-only test proves it on every change. ## Limits - You must name folders or shared drives; a whole Drive is never the default. Ids are letters, digits, `_` and `-`. - Sheets export only their first sheet. - Files of other types are skipped and counted, not read. - The access token lasts about an hour; a long pull needs a platform that mints a fresh one for each run. ## Data handling - Document text is copied into the deployment’s corpus under the source’s `label`. Documents can name people and hold personal data of any kind. - The token stays in your secret store, is never written to logs or run notes, and is sent only to Google. The engine holds no refresh token, so a leaked run directory holds nothing that outlives the hour. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------- | | `name the folders or shared drives to sync; a whole Drive is never the default` | Neither `folders` nor `drives` is set | Name them by id | | `not Drive ids` | A folder or drive id has characters other than letters, digits, `_` and `-` | Copy the id from the folder’s address | | `credential variable 'GDRIVE_TOKEN' is not set` | No access token in the environment | Mint a token with the `drive.readonly` scope and set it | | `HTTP 401` | The one-hour token has expired | Mint a fresh token for each run | | `HTTP 403` or `HTTP 404` on a folder | The service account has no access to the folder | Share the folder with the service account | | Read succeeded, 0 written | Nothing changed since the last page token | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Google Drive API v3 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/gdrive/ --- # GitHub > GitHub: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads issues, pull requests, their comments and the Markdown documents of the GitHub repositories you name, so engineering agents can answer from the design notes and the issue history. Optionally it reads every text file of the default branch (code) of named repositories or whole organisations. ## At a glance | Collector | GitHub, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Reads | GitHub: GitHub REST API (github.com and GitHub Enterprise Server) ([the vendor's documentation](https://docs.github.com/en/rest)) | | Family | Engineering | | Kind | Code | | Ways to connect | Access token | | Scopes | - Read: `Metadata: read`, `Contents: read`, `Issues: read`, `Pull requests: read` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `api.github.com`, `codeload.github.com` | | Vendor API versions | GitHub REST API, X-GitHub-Api-Version 2022-11-28 | | Lowest engine version | `0.47.1` | ## What it reads - Issues and pull requests (GitHub lists both with issues): title, body, comments, state, labels and the repository. Read since the newest `updated_at` seen per repository. - Markdown files (`*.md`) on the default branch, optionally only under `doc_paths`. The cursor keeps each file’s blob sha; an unchanged file is not fetched, and a file that leaves the tree is withdrawn. - With `code: true`: every text file of the default branch, from one tarball per repository, re-read only when the repository’s `pushed_at` moves. `orgs` names organisations whose every repository is read. - Left out of code reads: version-control internals, dependency and build directories (`node_modules`, `build`, `vendor`, …), lockfiles, binaries and generated files by suffix, empty files and files over `max_file_bytes` (256 KiB). Each skip is counted by reason. - Never read: wikis and Actions or CI results. ## How to connect 1. Create a fine-grained personal access token limited to the repositories you want, with only the permissions below. 2. In LightHouse, open **Connectors**, choose **GitHub**, name the repositories (`owner/name`), a label and how often to read, and paste the token. 3. In code, give the deployment the token as `GITHUB_TOKEN` from your secret store and add a `kind: github` source card with `repos` (and `orgs` with `code: true` where wanted), `label` and `requires`. 4. For GitHub Enterprise Server set `base_url` to `https:///api/v3`. A source that sets `credential_env: ""` reads public repositories without a token. ## Permissions Read only. For a fine-grained token: Metadata read, Contents read, Issues read and Pull requests read. The collector sends only `GET` requests to the API root (`api.github.com` by default, or the Enterprise Server’s host) and, for code reads, to `codeload.github.com` through the tarball redirect. The Authorization header is removed before a redirect is followed, as the redirect target carries its own short-lived token. Its read-only test proves it on every change. ## Limits - You must name repositories or, with `code: true`, organisations; an organisation is never the default. - A repository tree too large for GitHub to return whole is a failure, not a partial sync: reading half the documents and withdrawing the rest would empty the index. - A listing that has lost more than 25 repositories and more than a tenth of those the last pull knew fails the pull rather than withdrawing them. - A rate limit is waited out (the tarball stream waits for the reset); a 304 does not count against GitHub’s limit, so a quiet repository costs nothing. - Files over `max_file_bytes` (256 KiB) are skipped in code reads. - Documents have no modified date, so a pull compares blob shas, not dates. ## Data handling - Issue, comment and document text is copied into the deployment’s corpus under the source’s `label`. Comments carry the author’s login. Repositories can hold personal data and secrets in text; use a restrictive label for code. - The token stays in your secret store and is never written to logs or run notes; it is sent only to the API host. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------- | | `not owner/name repositories` | A repository is not written `owner/name` | Correct the name | | `name the repositories to sync; an organisation is never the default` | Neither `repos` nor `orgs` is set | Name the repositories | | `orgs reads every repository's code: it needs code: true` | `orgs` was given without `code: true` | Set `code: true`, or use `repos` | | `base_url must be an https URL` | An Enterprise Server address that is not https | Use the https API root | | `credential variable 'GITHUB_TOKEN' is not set` | The token variable is empty | Set it, or `credential_env: ""` for public repositories | | `the tree is truncated; name doc_paths to narrow it` | The repository is too large for one tree listing | Set `doc_paths` | | `refusing to delete` | The organisation listing lost most of the repositories the last pull knew | Check the token’s access; it is not a deletion | | `HTTP 401` or `HTTP 403` | The token is revoked, expired or lacks access to the repository | Make a new token with the permissions above | | Read succeeded, 0 written | Nothing changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | GitHub REST API, X-GitHub-Api-Version 2022-11-28 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/github/ --- # GitLab > GitLab: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads Markdown files, issues, merge requests, wiki pages and failed-pipeline results from the GitLab projects (or groups of projects) you name, on GitLab.com or your own instance, so engineering agents can answer from the design notes, the review history and the failing builds. ## At a glance | Collector | GitLab, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Reads | GitLab: GitLab REST API v4 (GitLab.com and self-managed) ([the vendor's documentation](https://docs.gitlab.com/ee/api/rest/)) | | Family | Engineering | | Kind | Code | | Ways to connect | Access token, OAuth approval | | Scopes | - Read: `read_api` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `gitlab.com` | | Vendor API versions | GitLab REST API v4 | | Lowest engine version | `0.45.0` | ## What it reads - Issues and merge requests: title, description and comments (system notes left out), state, labels, and for merge requests the source and target branches. Read since the newest `updated_at` seen per project. - Pipelines: status and ref; the jobs of failed or cancelled pipelines only. - Markdown files on the default branch, optionally only under `doc_paths`. The cursor keeps each file’s blob id; an unchanged file is not fetched, and one that leaves the tree is withdrawn. - Wiki pages: each page’s content; the cursor keeps a hash of it. A page that goes is withdrawn. - `groups` expand to their projects, subgroups included and archived ones left out. - Never read: code and other non-Markdown files. ## How to connect 1. Create a personal, group or project access token with the `read_api` scope only (User settings, Access tokens), or approve LightHouse’s OAuth application with the read level. 2. In LightHouse, open **Connectors**, choose **GitLab**, name the instance (GitLab.com by default), the projects (`group/name`) and groups, a label and how often to read, and approve or paste the token. 3. In code, give the deployment the token as `GITLAB_TOKEN` from your secret store and add a `kind: gitlab` source card with `projects` and/or `groups`, `label` and `requires`. Set `instance_url` for a self-managed instance. A source that sets `credential_env: ""` reads public projects without a token. ## Permissions `read_api` only. The collector sends only `GET` requests to `/api/v4`, with the token as a Bearer token; it never writes. The tree, file, wiki, issue, merge request, note and pipeline endpoints are all reads. Its read-only test proves it on every change. ## Limits - You must name projects or groups; a whole instance is never the default. Project paths are `group/name` (nested groups `a/b/name`). - The instance address must be `https://`; requests to any other host are refused. - Only pipelines that failed or were cancelled have their jobs listed. - A tree that GitLab pages is followed to its last page before anything is compared; a failing page fails the pull rather than withdrawing what was not listed. - A 304 with nothing cached is an error, never an empty listing. A wiki that answers 404 is left as it was, because GitLab answers 404 for a disabled wiki and for one the token cannot see alike. ## Data handling - Issue, comment, document and wiki text is copied into the deployment’s corpus under the source’s `label`. Notes carry the author’s name. Text can hold personal data. - The token stays in your secret store and is never written to logs or run notes; it is sent only to the instance host. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------- | | `name the projects or groups to sync; a whole instance is never the default` | Neither `projects` nor `groups` is set | Name them | | `not group/name projects` | A project is not written `group/name` | Correct the path | | `instance_url must be an https URL` | The instance address is not https | Use the https address | | `credential variable 'GITLAB_TOKEN' is not set` | The token variable is empty | Set it, or `credential_env: ""` for public projects | | `HTTP 401` or `HTTP 403` | The token is revoked, expired or lacks `read_api` | Make a new token with `read_api` | | Read succeeded, 0 written | Nothing changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | GitLab REST API v4 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/gitlab/ --- # Gmail > Gmail: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the messages carrying one Gmail label that you name, in a mailbox you name, so agents can answer from the correspondence a team filed there. The module also carries one tool that writes: a draft, never a send, refused unless a named person has approved it. ## At a glance | Collector | Gmail, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Reads | Google: Gmail ([the vendor's documentation](https://developers.google.com/gmail/api/guides)) | | Family | Communication | | Kind | Mail | | Ways to connect | Service account, OAuth approval | | Scopes | - Read: `https://www.googleapis.com/auth/gmail.readonly` - Read_write: `https://www.googleapis.com/auth/gmail.compose` | | Read only | No | | Vendor's API can move money | No | | Personal data | Contact, Identity, Content | | Hosts it may contact | `gmail.googleapis.com`, `mail.google.com` | | Vendor API versions | Gmail API v1 | | Lowest engine version | `0.45.0` | ## What it reads - Messages carrying the label you name (`mailbox_label`) as text: the plain-text part, or the HTML part with its tags removed, with subject, correspondents and date. - The cursor is the mailbox history id, kept with the ids of the messages written. A message that loses the label or is deleted is withdrawn. - Gmail keeps history for about a week. When the stored id has expired the API answers 404 and the collector lists the label again in full and withdraws what is no longer there, rather than staying broken until someone clears the cursor. - Never read: anything outside the label, and attachments. A document that matters belongs in a folder or drive the engine syncs, where it has an owner and a version. ## How to connect 1. Create a service account and, in your Google Workspace admin console, grant its client ID domain-wide delegation for `https://www.googleapis.com/auth/gmail.readonly` and no other scope. 2. In LightHouse, open **Connectors**, choose **Gmail**, name the **Read as** person, the **Mailbox label** (a whole mailbox cannot be asked for), the label for the corpus and how often to read, and attach the service-account key. LightHouse asks Google what the minted token carries and refuses a key whose token carries more than `gmail.readonly`. 3. In code, give the deployment an OAuth access token with the `gmail.readonly` scope as `GMAIL_TOKEN` and add a `kind: gmail` source card with `mailbox_label`, `label` and `requires`. ## Permissions The reader needs `https://www.googleapis.com/auth/gmail.readonly` only, and sends only `GET` requests to `gmail.googleapis.com`; nothing in a pull calls a send or drafts endpoint. Its read-only test proves it on every change. The module also holds `create_draft`, which makes one Gmail draft for a person to review and send. It is the only write, it posts to `/gmail/v1/users/me/drafts`, it can never send, and it is refused before any token is read unless a named person’s approval is in hand, the agent’s card is `effect: external` and lists the tool in `effect_tools`, and the tool policy allows it (never at autonomy 0). A token that can create drafts needs a wider scope, such as `gmail.compose`; the LightHouse connection asks for `gmail.readonly` only, so drafts need a token you mint yourself. ## Limits - You must name the label; a whole mailbox is never the default, and a label that does not exist is an error. - Attachments are not read. - Messages are read as text; formatting and inline images are lost. - The access token lasts about an hour; the collector holds no refresh token. ## Data handling - Message text is copied into the deployment’s corpus under the source’s `label`, normally a confidential one. Mail names people and holds personal data of any kind. - The token stays in your secret store, is never written to logs or run notes, and is sent only to Google. - Each draft is logged as an event with the agent, the approving person’s name and the count of recipients, never the text. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------- | | `name the mailbox label to read; a whole mailbox is never the default` | `mailbox_label` is empty | Name the label | | `the mailbox has no label` | The label does not exist in that mailbox | Check its name (case and slashes) and the Read as person | | `credential variable 'GMAIL_TOKEN' is not set` | No access token in the environment | Mint a token with the `gmail.readonly` scope and set it | | `not a Gmail message id` | A message id with characters other than letters and digits was returned or given | Report it; this should not happen | | `a draft needs a named person's approval` | `create_draft` was called without an approved decision | Approve the card in LightHouse first | | `list aal__gmail__create_draft in effect_tools on an external card` | The agent’s card does not declare the draft as an external effect | Add it to `effect_tools` on an `effect: external` card | | `POST ... /drafts: HTTP 403` | The token has no scope that allows drafts | Mint a token with `gmail.compose` | | Read succeeded, 0 written | Nothing changed since the history id | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Gmail API v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/gmail/ --- # HubSpot > HubSpot: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads companies, contacts, deals and tickets from a HubSpot account, so commercial and service agents can answer from the account and ticket history. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | HubSpot, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Reads | HubSpot: HubSpot CRM (CRM API v3) ([the vendor's documentation](https://developers.hubspot.com/docs/api/crm/understanding-the-crm)) | | Family | CRM | | Kind | CRM | | Ways to connect | Access token | | Scopes | - Read: `crm.objects.companies.read`, `crm.objects.contacts.read`, `crm.objects.deals.read`, `tickets` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `api.hubapi.com`, `app.hubspot.com`, `{host}` | | Vendor API versions | CRM API v3 | | Lowest engine version | `0.46.0` | ## What it reads - **Companies:** name, domain, industry, city, country, description. - **Contacts:** first and last name, email, job title, company. - **Deals:** name, stage, pipeline, amount, close date, description. - **Tickets:** subject, pipeline stage, priority, content. - Only the objects you name in `objects`. A whole portal is never the default. - Only the properties above, or the ones you name per object in `properties`, so a contact is not every field the portal holds about a person. - Changes only: each object is searched by `hs_lastmodifieddate`, oldest first, and paged by `after`. When a search reaches HubSpot’s 10,000-result ceiling, the query starts again from the newest change seen, so a first read of a large portal finishes rather than stopping at 10,000. HubSpot publishes no knowledge-base API, so articles are not read. Notes, emails, calls and attachments are not read. ## How to connect 1. In HubSpot, make a private app and give it the read scopes of the objects you will name (see Permissions). 2. In LightHouse, open **Setup and admin, Connectors**, choose **HubSpot**, and fill in `objects` and, if you want links back to HubSpot, `portal_id` (your account’s number). 3. Paste the private app’s access token. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`HUBSPOT_CREDENTIAL` by default) with one field, `token`. ## Permissions - **Scopes:** `crm.objects.companies.read`, `crm.objects.contacts.read`, `crm.objects.deals.read` and `tickets`, for the objects you name. HubSpot states a private app’s scopes, and the deployment’s check reports them. - **What the collector does:** `GET` requests, and the CRM search, which HubSpot only offers as a `POST` with the query in the body (`/crm/v3/objects//search`). Nothing is created, changed or deleted. Its read-only test proves that on every change. - **One host:** every call goes to `api.hubapi.com`, fixed in the code; nothing in the configuration or the credential names another. ## Limits - CRM API v3. - Search answers at most 10,000 results to one query; the restart described above handles this, and ids already read are skipped. - Deletions (archived records) are found by listing ids every six hours; an archived record is removed from the corpus then, not at once. - `portal_id`, when given, only builds the link kept with each record (`app.hubspot.com`); that address is never contacted. - Property names must be lower-case HubSpot internal names. ## Data handling - Contacts and companies hold personal data (names, email addresses, job titles). Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. ## Troubleshooting | What you see | What it means | What to do | | ----------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------- | | `credential variable 'HUBSPOT_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect HubSpot again in LightHouse | | `the hubspot credential has no token` | The credential lacks its `token` field | Re-enter the private app’s access token | | `not HubSpot property names for contacts: ...` | A property is not a lower-case internal name | Use HubSpot’s internal property names | | `portal_id is your HubSpot account's number` | `portal_id` is not a number | Give the account number, or leave it out | | `HTTP 401` or `HTTP 403` | The token is wrong, revoked, or lacks a scope | Check the private app’s scopes | | `HTTP 429` | HubSpot’s rate limit | Nothing; the collector backs off and the next run continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | CRM API v3 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/hubspot/ --- # Intelex > Intelex: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads incidents, audits, findings and actions from the Intelex objects you name, read-only, inside your deployment, with reporters left out. ## At a glance | Collector | Intelex, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------- | | Reads | Intelex Technologies: Intelex REST API (v2) ([the vendor's documentation](https://developers.intelex.com/)) | | Family | Aviation | | Kind | Quality | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | Intelex REST API v2 (/api/v2/object) | | Lowest engine version | `0.46.0` | ## What it reads - For each object you name (`objects`, such as `IncidentsObject`; each system’s names are listed in Intelex’s System Administration): its records modified since the last run (on the first run, within the last `days_back` days: 1 to 3650, default 365), through `GET /api/v2/object/{Object}` with `$filter=DateModified ge ...`. - One record per Intelex `Id`, keyed `/`, with its `DateModified`. - Pages of up to 500 (`page_size`) follow `@odata.nextLink`. ## How to connect 1. Create a dedicated integration user in Intelex, make an API key for it, and tell your Intelex Customer Success Manager about the integration first (Intelex asks this). 2. In LightHouse, open **Setup and admin, Connectors**, choose **Intelex**, and leave the access level at **Read**. 3. Name `base_url` (your Intelex system, https) and the `objects`. 4. Paste the API key. Your browser seals it to your deployment, which hands it to the collector as `INTELEX_API_KEY`. ## Permissions - `GET` only, with `Authorization: ApiKey `. The integration user’s rights in Intelex are the permission: give it read access to the objects you name. - Intelex asks that its API not be driven by autonomous agents. This is a scheduled, read-only sync on a dedicated integration user, not an agent; onboarding includes the conversation with your Customer Success Manager. - Your deployment refuses to store this credential at read and write. ## Limits - Intelex limits a tenant to 20 reads a second and 20,000 a day, shared with every other use of the tenant, and answers `429` with `Retry-After` beyond them. The default pace is two reads a second (`delay_s` 0.5). - Incremental by `DateModified`, from the previous run. - An object is read up to `max_pages` pages (400); more fails the run. - A `@odata.nextLink` to another host is refused. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never an incident or a reporter. - Reporters are protected by default: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details are left out of every record before it is written, as are travel document numbers and dates of birth. Just culture and data protection both need a reporter kept from anyone who does not need them. Names are matched whatever the case, spacing, `_` or `-`, so `reporterName` also catches an export’s `Reporter Name`. - `exclude_fields` adds paths (for example `**.contact`); `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. Free-text narratives are indexed as written and may still name people: add the fields that hold them to `exclude_fields`. - Nothing is cached raw, and a failure names the host and the status, never the URL. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------- | -------------------------------------------------- | --------------------------------------------------- | | `credential variable 'INTELEX_API_KEY' is not set` | The deployment has not been given the key | Connect the credential again | | `GET host: HTTP 401` | Intelex refused the key | Check the key belongs to an active integration user | | `GET host: HTTP 429` | The tenant’s rate limit, after the retries | Read fewer objects, or less often | | `GET host: a next page on another host was refused` | A next link pointed away from your Intelex | Report it to us; nothing was followed | | `intelex: more than 400 pages of X` | An object has more records than `max_pages` allows | Narrow `days_back`, or raise `max_pages` | | `base_url is the client's Intelex system, https` | `base_url` is not https | Use the https address | | `objects are Intelex object system names, at least one` | No object, or a name with a space | Use the object’s system name | | `page_size is 1 to 500 and days_back 1 to 3650` | A setting is out of range | Correct it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Intelex REST API v2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/intelex/ --- # Jeppesen > Jeppesen: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Jeppesen is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from the Jeppesen API references granted on developer.boeing.com (crew pairing and rostering, and FliteDeck chart and airport metadata), with an access credential that reads only. The API catalogue on developer.boeing.com is behind sign-in and access requests. Crew records name people, so crew names and contacts stay in your deployment and contact details are left out by default. ## At a glance | Collector | Jeppesen, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Jeppesen (Boeing): Jeppesen crew pairing and rostering, FliteDeck chart and airport metadata APIs ([the vendor's documentation](https://developer.boeing.com/Jeppesen-APIs)) | | Family | Aviation | | Kind | Crew | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: crew plans and chart metadata read in place; no roster is published. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need the Jeppesen API references granted on developer.boeing.com (crew pairing and rostering, and FliteDeck chart and airport metadata), with an access credential that reads only, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: jeppesen label: internal api: spec_ref: "Jeppesen API reference granted on developer.boeing.com, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Crew and operations} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Jeppesen (Boeing): needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/jeppesen/ --- # Atlassian Jira > Atlassian Jira: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the issues of the Jira projects you name, each with its description and every comment in one document, so a question about a case finds the discussion as well as the report. A deleted issue, or one moved out of the projects, leaves the knowledge base. ## At a glance | Collector | Atlassian Jira, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | Reads | Atlassian: Jira Cloud ([the vendor's documentation](https://developer.atlassian.com/cloud/jira/platform/rest/v3/intro/)) | | Family | ITSM | | Kind | Tickets | | Ways to connect | Access token | | Scopes | - Read: `read:jira-work` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `{tenant}.atlassian.net` | | Vendor API versions | Jira Cloud platform REST API v3 | | Lowest engine version | `0.45.0` | ## What it reads - Issues in the projects you name: the summary, the description and every comment, in one document, with the project, type, status and labels. - The cursor is UTC. Jira reads dates in the account’s profile time zone, which the collector cannot see, so the query starts a day before the cursor and drops what is not newer. - Deletions: every `reconcile_hours` (six by default) the collector lists the projects’ issue keys, with no other field, and removes every issue it holds that is no longer there. A project taken out of `projects` has its issues removed. - Never read: attachments, work logs and history. ## How to connect 1. Create or choose an integration account in your Atlassian site with browse access to the projects you name and nothing else. Do not use a site administrator. 2. Signed in as that account, create an API token at id.atlassian.com (Security, API tokens). 3. In LightHouse, open **Connectors**, choose **Jira**, name the site, the project keys, the label and how often to read, and paste the account’s email address and token. 4. In code, set `JIRA_BASE_URL`, `JIRA_EMAIL` and `JIRA_TOKEN` (the names can be changed with `site_env`, `email_env` and `credential_env`) and add a `kind: jira` source card with `projects`, `label` and `requires`. ## Permissions The collector signs in with the account’s email address and API token (HTTP Basic). Atlassian API tokens carry no scopes, so what the account can browse is what the collector can read; LightHouse’s card lists `read:jira-work` for a scoped token. Every request is a `GET`: `/rest/api/3/search/jql` (issues, and issue keys alone for deletions) and `/rest/api/3/issue/{key}/comment`. Its read-only test proves it on every change. ## Limits - You must name the projects; a whole site is never the default. Project keys may hold letters, digits and underscores only. - The base address must be `https://`. - The search returns only the first page of an issue’s comments; the rest are fetched a page at a time. - A deletion listing that Jira refuses fails the pull and removes nothing. - Requests are paced and back off when Jira asks (`Retry-After`). ## Data handling - Issue text and comments are copied into the deployment’s corpus under the source’s `label`. Comments carry their author’s display name; issues can hold personal data. - The token stays in your secret store; only the name of a missing variable is ever reported, never a value, and the token is never put in a URL. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | | `credential variable 'JIRA_EMAIL' is not set` | A variable the source names is missing (the name is shown, never a value) | Set it, or point `email_env`, `site_env` or `credential_env` at the right variable | | `JIRA_BASE_URL must be an https URL` | The site address is not https | Use the `https://.atlassian.net` address | | `name the projects to sync; a whole site is never the default` | `projects` is empty | Name the project keys | | `not Jira project keys` | A key holds characters other than letters, digits and underscores | Correct the key | | `HTTP 401` or `HTTP 403` | The token was revoked, or the email is not the token’s owner | Make a new token for the integration account | | Read succeeded, 0 written | No issue changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Jira Cloud platform REST API v3 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/jira/ --- # Kraken > Kraken: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Kraken account’s spot balances, ledger entries and trade history, so reconciliation and reporting agents can check them against the books. It is read-only, and it is built to refuse a key that can withdraw or trade. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Kraken, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------- | | Reads | Kraken: Kraken Spot REST API ([the vendor's documentation](https://docs.kraken.com/api/)) | | Family | Finance | | Kind | Exchange | | Ways to connect | Access token | | Scopes | - Read: `Query Funds`, `Query Ledger Entries`, `Query Closed Orders & Trades` | | Read only | Yes, except: \[object Object]; \[object Object]; \[object Object]; \[object Object] | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.kraken.com`, `{host}` | | Vendor API versions | Spot REST API (/0/private) | | Lowest engine version | `0.46.0` | ## What it reads - **Spot balances:** one record per asset, rewritten only when it changes and removed when the asset disappears. - **Ledger entries:** amount, fee and balance after, with the reference, type, sub-type and asset class. - **Trade history:** pair, side, order type, price, volume, cost and fee in the quote currency. - Ledgers and trades are read oldest first from the last cursor, paged by offset. The first read goes back `history_days` (default 90, at most 3,650). It does not read futures, open orders, staking or funding addresses. ## How to connect 1. In Kraken, make an API key with only **Query Funds**, **Query Ledger Entries** and **Query Closed Orders & Trades**, and an IP allowlist of your deployment’s egress addresses. 2. In LightHouse, open **Setup and admin, Connectors** and choose **Kraken**. 3. Paste the API key and the private key. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_KRAKEN` by default): `api_key` and `api_secret`. ## Permissions This collector is **read-only** in what it does. Kraken’s private endpoints accept only `POST`, so every request is a signed `POST`, but the collector makes exactly four calls, all of which read: `GetApiKeyInfo`, `Balance`, `Ledgers` and `TradesHistory` (the manifest lists them under `read_operations`; the read-only test fails on any other call). Nothing is placed, cancelled or withdrawn. - **Refused by the code:** Kraken states a key’s permissions (`POST /0/private/GetApiKeyInfo`, which needs no permission). Before every read, and in the health check, a key whose `permissions` include any of these six names is refused, naming it: `withdraw-funds`, `modify-trades`, `close-trades`, `earn-funds`, `add-withdraw-address`, `update-withdraw-address`. The error is `Kraken: refused: the credential can \; make a view-only one`. - **Not refused by the code:** every other permission name, because the code refuses only those six. A permission that moves funds or trades under a name not on that list would pass. Make the key with only the three query permissions above. - **IP allowlist:** the check reports whether the key has one; a key without one is told to pin it to your egress addresses (it is not refused). - **Signing:** each request carries HMAC-SHA512 of the path and the SHA-256 of nonce and body, under the base64-decoded secret; the nonce always increases. The secret never leaves your store. - **Hosts:** only `api.kraken.com`, over https; redirects are never followed. ## Limits - Spot only. - Requests are paced one second apart and retried on 429 and 5xx with back-off. - Amounts are exact decimals; a number that arrives as a float is refused. - Each record is keyed by Kraken’s own id, so one read twice is still one record. ## Data handling - Records hold financial data: balances, ledger amounts and trades. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------- | | `Kraken: refused: the credential can withdraw-funds; make a view-only one` | The key holds a fund-moving permission (the one named) | Make a key with only the three query permissions | | `Kraken answered HTTP 401 (the key or signature was refused)` | `EAPI:Invalid key` or a bad signature | Check the key and the private key | | `Kraken answered HTTP 403 (permission denied)` | The key lacks a query permission | Add Query Funds, Query Ledger Entries or Query Closed Orders & Trades | | `Kraken refused Balance: EService:Unavailable` | Kraken reported an error (its code is shown) | Try again later | | `Kraken answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Spot REST API (/0/private) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/kraken/ --- # Kyriba > Kyriba: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Kyriba tenant’s bank accounts, bank and cash balances, cash positions and forecasts, cash flows, payment status and third parties, so treasury agents can answer from the client’s own treasury system. It is read-only, and it is built to refuse an API client that can initiate or approve payments, where Kyriba states that. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Kyriba, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Kyriba: Kyriba treasury API (accounts, balances, cash flows, payments) ([the vendor's documentation](https://developer.kyriba.com/)) | | Family | Finance | | Kind | Treasury | | Ways to connect | OAuth approval | | Scopes | - Read: `account-scope`, `cash-balances-scope`, `bank-balances-scope`, `cash-flows-scope`, `payment-file-scope`, `payment-transaction-summary-scope`, `third-party-scope` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | Yes | | Personal data | Financial, Contact | | Hosts it may contact | `*.kyriba.com`, `{host}` | | Vendor API versions | Kyriba REST API v1, payment-transaction-summary-details v2 | | Lowest engine version | `0.46.0` | ## What it reads - **Bank accounts** that are open, with company, bank, IBAN and type. - **End-of-day bank balances** (yesterday’s) and **cash positions and forecasts** from today for `forecast_days` (default 30, at most 31), including actual, intraday, confirmed and estimated figures. - **Cash flows** (the reconciled actuals are the bank transactions), in windows of at most 31 days, as Kyriba requires, re-reading the last week. - **Payment status:** the payment transaction summary (status, UETR, last acknowledgement, counterparty, file, remittance) and payment-file status. - **Third parties:** code, name, type, creditor and debtor flags. - The first read goes back `history_days` (default 90, at most 3,650). It does not read FX rates (not in Kyriba’s public reference), and it does not call any payment initiation API. ## How to connect 1. Ask your Kyriba administrator for an API client by client credentials, with read permissions only (`account-scope`, `cash-balances-scope`, `bank-balances-scope`, `cash-flows-scope`, `payment-file-scope`, `payment-transaction-summary-scope`, `third-party-scope`), and the two URLs (for example `https://auth.demo.kyriba.com` and `https://api.demo.kyriba.com/api`). 2. In LightHouse, open **Setup and admin, Connectors** and choose **Kyriba**. 3. Paste the client id, client secret and the two URLs, and confirm the API client has only read permissions. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_KYRIBA` by default): `client_id`, `client_secret`, `auth_url`, `api_url`, and `view_only_confirmed` (`yes`). ## Permissions This collector is **read-only** in what it does: `GET` requests, and one `POST {auth_url}/oauth/token` for the access token. Its read-only test proves it on every change. Nothing is initiated, transferred or approved. - **Refused by the code:** where the token answer states permissions (its `scope`), an API client with any permission whose name contains `payment-initiation`, `payment-automation`, `transfer`, `approv` or `fraud-detection-spi` (case-insensitive) is refused, naming it. The error is `Kyriba: refused: the credential can ; make a view-only one`. - **Not detectable by the code:** Kyriba’s permissions are access permissions on the API client, not OAuth scopes, and the collector asks for no scope, so the token answer usually states none. The collector then reads only once you have confirmed the API client has only read permissions (`view_only_confirmed`); without it the error is `Kyriba does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read`. Have your Kyriba administrator make the API client read-only: that, not this code, is what stops it from initiating payments. - **Hosts:** the two URLs must be `https://.kyriba.com` addresses without a query (`auth_url and api_url are https://.kyriba.com addresses`); only those two hosts are contacted, and redirects are never followed. - **Token scheme:** the token is sent with the `token_type` Kyriba answers; on a 401 the collector tries once with the other scheme. ## Limits - 50 calls in 30 seconds and one at a time per API client, and a daily quota per environment. Requests are paced, and a 429 waits until `Kyriba-Customer-Rate-Limit-Reset`. - Pages of 100. Balances and cash flows are asked in windows of at most 31 days. - Amounts are exact decimals; a number that arrives as a float is refused. ## Data handling - Records hold financial data (balances, cash flows, payments) and the names of counterparties and third parties. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------ | | `Kyriba: refused: the credential can payment-initiation-spi-scope; make a view-only one` | The token states a fund-moving permission (named) | Ask your administrator for a read-only API client | | `Kyriba does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | Permissions are not stated and you have not confirmed | Confirm the API client has read permissions only | | `auth_url and api_url are https://.kyriba.com addresses` | A URL is not on kyriba.com, or has a query | Use the addresses your administrator gave | | `Kyriba answered no token` | The token endpoint answered without a token | Check the client id and secret | | `Kyriba answered HTTP 401` | The client was refused | Check the client id and secret | | `Kyriba answered HTTP 429` | Rate limit | Nothing; the collector waits until Kyriba’s reset time | | `forecast_days is 0 to 31` | The forecast window is out of range | Use 0 to 31 | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Kyriba REST API v1; payment-transaction-summary-details v2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/kyriba/ --- # monday.com > monday.com: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the items, column values and updates on the monday.com boards you name, so delivery agents can answer from the project’s own tracker. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | monday.com, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | Reads | monday.com: monday.com platform API (GraphQL) ([the vendor's documentation](https://developer.monday.com/api-reference/docs)) | | Family | Engineering | | Kind | Work management | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `api.monday.com` | | Vendor API versions | GraphQL API 2025-04 | | Lowest engine version | `0.46.0` | ## What it reads - For each board you name, every item: its name, group, board name, each column’s title and text value, and the latest updates (text, date, author name; `updates`, default 20, at most 100). - Only the boards you name, by id. A whole account is never the default. - **Each board is read whole on every pull; only what changed is written.** monday.com’s API cannot filter items by the time they changed, so the collector reads the board in pages of 100 (`items_page`, then `next_items_page` by cursor) and emits an item only when its `updated_at` is newer than the board’s cursor. An unchanged board writes nothing. It does not read other boards, users, files or documents. ## How to connect 1. In monday.com, make an API token: a person’s own, or better one made for an integration account added only to the boards you will name. 2. In LightHouse, open **Setup and admin, Connectors**, choose **monday.com**, and give the board ids. 3. Paste the token. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`MONDAY_CREDENTIAL` by default) with one field, `token`. ## Permissions - monday.com does not state a token’s permissions: a token carries **its user’s**, which is why the boards are named and the account should see no more than them. Give the integration account viewer access to those boards only. - **What the collector does:** monday.com’s API is GraphQL over `POST`, so every request is a `POST` to `/v2`, but the collector sends **query documents only**: its two queries are fixed text in the source, and none is a mutation. Its read-only test asserts that every request body is a `query` and none contains `mutation`. - **One host:** `api.monday.com` for every request. ## Limits - GraphQL API version `2025-04`. - Pages of 1 to 500 items (`page_size`, default 100). - Because each board is read whole, a very large board costs a full read on every pull. The cost is monday.com’s complexity budget, not a write. - **The rate limit is a complexity budget.** A query over budget answers with a `ComplexityException` (or 429) naming the seconds until it resets; the pull waits that long (at most a minute, three times) and asks again, and fails rather than return part of a board. - A full read is also the deletion check: an item no longer on the board is removed from the corpus on the same pull. ## Data handling - Items and updates name people and may hold personal data in their text. Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. - An error from monday.com is reported by its code only, never its message. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------ | | `credential variable 'MONDAY_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect monday.com again in LightHouse | | `name the boards to sync; a whole account is never the default` | No board ids were given | Name the boards | | `not monday.com board ids: [...]` | A board id is not numeric | Use the number in the board’s address | | `monday.com board 123 is not visible to this token` | The token’s user cannot see the board | Add the integration account to the board | | `monday.com refused the query: ...` | monday.com answered an error (its code is shown) | Check the token and the code in monday.com’s reference | | `monday.com's complexity budget did not reset in time` | The account is over its budget | Wait for the next run, or read fewer boards | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | GraphQL API 2025-04 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/monday/ --- # NetSuite > NetSuite: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads NetSuite customers, transactions, items and support cases by SuiteQL, so finance and service agents can answer from the ledger and the case history. It signs in with the client’s certificate, machine to machine, and sends only SELECT queries. ## At a glance | Collector | NetSuite, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Oracle: NetSuite (SuiteTalk REST, SuiteQL) ([the vendor's documentation](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_1540391670.html)) | | Family | ERP | | Kind | ERP | | Ways to connect | OAuth approval, Key pair | | Scopes | - Read: `rest_webservices` | | Read only | Yes, except: \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Financial, Identity, Content | | Hosts it may contact | `*.suitetalk.api.netsuite.com`, `*.app.netsuite.com`, `{host}` | | Vendor API versions | NetSuite REST web services (SuiteQL), OAuth 2.0 client credentials (M2M) | | Lowest engine version | `0.46.0` | ## What it reads - Four kinds, which you choose: `customers`, `transactions`, `items` and `cases`, with the business record’s columns (names, status, terms, totals, currency, memo, dates). A customer’s email and phone are not read. - Changes since the cursor: SuiteQL’s `lastmodifieddate` is in the account’s time zone with no offset, so the query starts a day before the cursor, the time is read as written (as UTC), and what is not newer is dropped. - SuiteQL’s offset paging stops at 100,000 rows, so a larger first pull starts again from the newest time it has read, skipping ids already read, until a restart brings nothing new. The listing for a reconcile pages by id. - Deletions: every six hours the ids are listed (ids only) and what has gone is withdrawn. A record type the role cannot read (400, 403) keeps its ids. ## How to connect 1. In NetSuite, create an integration record with the OAuth 2.0 client-credentials grant, generate a certificate, and upload it under **Setup, Integration, OAuth 2.0 Client Credentials (M2M) Setup**, mapped to a role that only views the records named. 2. In LightHouse, open **Connectors**, choose **NetSuite**, and give the client id, the certificate’s id and the certificate’s private key (PEM). They are sealed in your browser to your deployment’s key and kept in your own secrets store; LightHouse never opens them. 3. In code, set `NETSUITE_CREDENTIAL` to the credential’s JSON fields (`account_id`, `client_id`, `certificate_id`, `certificate`) and add a `kind: netsuite` source card with `objects`, `label` and `requires`. ## Permissions The `rest_webservices` scope, with a mapped role that has view permission on the records named and nothing that creates or edits; read and write is not offered. The deployment signs a five-minute assertion (PS256, the certificate’s id as `kid`) and NetSuite answers an hour’s token. No password and no token-based-authentication secret pair is asked for. Every request goes to the account’s own host, `.suitetalk.api.netsuite.com`, made from the sealed account id, and the fetcher refuses any other. The only POSTs are the token request and SuiteQL, which carries its query in a POST body; both are listed in the manifest’s `read_operations`, and the read-only test asserts they are the only paths used and that every query is a SELECT. ## Limits - `account_id` is the NetSuite account id (for example `1234567` or `1234567_SB1`). - Only the four kinds are read, with fixed columns. - Offset paging is capped at 100,000 rows by SuiteQL; the collector restarts from the newest time and skips ids read. - A re-read of a day’s changes is normal, because of the time-zone widening. - Requests are paced and back off when NetSuite asks (`Retry-After`). ## Data handling - Records are copied into the deployment’s corpus under the source’s `label`. They are financial records and name customers and suppliers (companies, and some people); a customer’s email and phone are not read. - The private key stays in the client’s store; only a five-minute assertion is signed and sent, and an hour’s token is held in memory. Neither is written to logs or run notes. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------- | | `account_id is your NetSuite account id, e.g. 1234567 or 1234567_SB1` | The account id is not NetSuite’s | Use the account id from Setup, Company, Company Information | | `the NetSuite certificate holds no readable private key` | The pasted PEM has no private key | Paste the private key and the certificate | | `NetSuite answered no access token` | The token request was accepted but gave no token | Check the integration record and the certificate mapping | | `HTTP 400` or `HTTP 401` on the token request | The client id, certificate id or mapped role is wrong | Check the M2M setup | | `HTTP 403` on a query | The role cannot view that record type | Grant view permission; its ids are kept meanwhile | | Read succeeded, 0 written | No record changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | NetSuite REST web services, SuiteQL, OAuth 2.0 client credentials (M2M) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/netsuite/ --- # Notion > Notion: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the pages and database rows that someone has shared with your Notion integration, so agents can answer from the team’s own wiki. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Notion, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------- | | Reads | Notion Labs: Notion API ([the vendor's documentation](https://developers.notion.com/reference/intro)) | | Family | Knowledge | | Kind | Wiki | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `api.notion.com`, `www.notion.so`, `{host}` | | Vendor API versions | Notion API 2022-06-28 | | Lowest engine version | `0.46.0` | ## What it reads - **Pages shared with the integration:** the title and the text of the page’s blocks (paragraphs, headings, lists, to-dos, quotes, callouts, toggles and code), read to `max_depth` levels of nesting (default 3, at most 10). A child page or child database is a page of its own and is not read twice. - **Database rows:** a row is a page, and comes in with its properties (text, selects, dates, numbers, checkboxes, people names, and so on). `databases` narrows rows to the databases you name; pages that are not rows are read whatever it says. - Changes only: the search for pages runs newest first and stops at the first page not edited after the cursor (`last_edited_time`). **Only what someone shares with the integration is read.** A person adds the integration to a page or database; that is the decision to let the agents read it. Images, files and embedded content are not read. ## How to connect 1. In Notion, make an internal integration in your workspace. 2. Share the pages or databases you want read with it. 3. In LightHouse, open **Setup and admin, Connectors**, choose **Notion**, and (optionally) name the databases. 4. Paste the integration’s secret. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`NOTION_CREDENTIAL` by default) with one field, `token`. ## Permissions - Notion states no capabilities for an integration, so **the sharing decides** what can be read. Give the integration the *read content* capability only. - **What the collector does:** `GET` requests for blocks, and Notion’s search, which is only offered as a `POST` with the query in the body (`/v1/search`). Nothing is created, edited or deleted. Its read-only test proves that on every change. - **One host:** `api.notion.com`. The collector sends the `Notion-Version` header `2022-06-28`. ## Limits - Notion allows about three requests a second, so the collector paces itself to that, and a 429 waits as long as Notion asks (`Retry-After`). - Search results are in pages of 100. - A page’s links are kept only when they are on `www.notion.so`; any other address is dropped (the address is never contacted). - A page moved to the trash, archived or no longer shared stops being found; every six hours every shared page’s id is listed and what has gone is removed from the corpus, not at once. ## Data handling - Pages and rows can hold personal data, and people’s names appear in people properties. Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the pages, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------- | | `credential variable 'NOTION_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect Notion again in LightHouse | | `the notion credential has no token` | The credential lacks its `token` field | Re-enter the integration secret | | `not Notion database ids: [...]` | A database id is not 32 hexadecimal characters | Copy the id from the database’s address | | Read succeeded, 0 written | Nothing is shared with the integration, or nothing changed | Share the pages with the integration in Notion | | `HTTP 401` | The secret is wrong or revoked | Make a new integration secret | | `HTTP 429` | Notion’s rate limit | Nothing; the collector waits as Notion asks | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | --------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Notion API 2022-06-28 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/notion/ --- # OAG Flight Info > OAG Flight Info: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads flight instances by departure airport and date from OAG’s Flight Info API, read-only, inside your deployment. ## At a glance | Collector | OAG Flight Info, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------- | | Reads | OAG Aviation Worldwide: OAG Flight Info API ([the vendor's documentation](https://developers.oag.com/)) | | Family | Aviation | | Kind | Flights | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `api.oag.com`, `{host}` | | Vendor API versions | Flight Info API v2 (query parameter version=v2) | | Lowest engine version | `0.46.0` | ## What it reads - For each airport you name (departure airport) and each date from `days_back` (0 to 7, default 0) to `days_ahead` (0 to 14, default 2): the flight instances OAG returns (`GET /flight-instances/`). - OAG’s item reference is behind sign-in, so **no field of an item is assumed**. A record is the item as served, with personal fields still left out. It is keyed by the field you name in `id_field` once onboarding has read OAG’s reference, and until then by a hash of the item within its airport and date. - A changed item is therefore a new record and the old one is withdrawn, so the index never holds both. ## How to connect 1. Make a developer account at OAG and a subscription key (the free tier allows 1,000 calls a month and 10 results a call). 2. In LightHouse, open **Setup and admin, Connectors**, choose **OAG Flight Info**, and leave the access level at **Read**. 3. Name the `airports`. Set `limit` (results per page, 1 to 1000; the free tier serves 10) and, once known, `id_field`. 4. Paste the subscription key. Your browser seals it to your deployment, which hands it to the collector as `OAG_SUBSCRIPTION_KEY`. If your key’s portal shows `Ocp-Apim-Subscription-Key`, set `key_header` to that. ## Permissions - `GET` only. The subscription key is sent in the header OAG’s sample uses, `Subscription-Key`; `key_header` can name `Ocp-Apim-Subscription-Key`, the only other value accepted. - A `paging.next` link to any other host is refused. - Your deployment refuses to store this credential at read and write. Only `api.oag.com` is contacted. ## Limits - OAG offers no changed-since: each run reads the window’s dates again, and unchanged items are not rewritten. - Pages follow `paging.next` up to `max_pages` (200); a listing that does not end fails rather than loops. - Rate limits are not published beyond the free tier’s monthly calls; the default pace is one request a second (`delay_s`). - Without `id_field`, a record’s id is a hash of the item, so it is stable only while the item is unchanged. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a flight record. - Nothing is cached raw, and a failure names the host and the status, never the URL. - Flight status carries no passenger data. The standard exclusions still apply to every record before it is written (travel document numbers, dates of birth, health or disability special service requests); `exclude_fields` adds paths and `keep_fields` takes a default back by its exact name. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------ | | `credential variable 'OAG_SUBSCRIPTION_KEY' is not set` | The deployment has not been given the key | Connect the credential again | | `GET api.oag.com: HTTP 401` | OAG refused the key | Check the key and which header your portal shows | | `GET api.oag.com: a next page on another host was refused` | A `paging.next` link pointed away from OAG | Report it to us; nothing was followed | | `oag: more than 200 pages; raise max_pages` | The listing did not end | Raise `limit`, or `max_pages`, after checking the airport and date | | `name the departure airports to read` | No airport was named | Name at least one | | `key_header is one of Subscription-Key, Ocp-Apim-Subscription-Key` | Any other header name | Use one of the two | | `days_back 0 to 7, days_ahead 0 to 14, limit 1 to 1000` | A setting is out of range | Correct it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Flight Info API v2 (query parameter version=v2) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/oag/ --- # Oracle Database > Oracle Database: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the Oracle Database tables and views you name, in place, through a read-only database user in the client’s own network, so agents can answer from a register or a ledger without it being copied to a vendor. Every statement it sends is a SELECT. ## At a glance | Collector | Oracle Database, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------- | | Reads | Oracle: Oracle Database ([the vendor's documentation](https://python-oracledb.readthedocs.io/en/latest/)) | | Family | Data | | Kind | Database | | Ways to connect | Access token | | Scopes | - Read: `CREATE SESSION`, `SELECT on the named tables and views` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Contact, Identity, Financial, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | python-oracledb 2.x and 3.x, thin mode (Oracle Net, TNS); SQL SELECT only | | Lowest engine version | `0.46.0` | ## What it reads - The tables and views you name (`SCHEMA.NAME`), with the key column, optionally an `updated` column, a `title` column and the `columns` to read (every column otherwise). A whole database is never the default. - With an `updated` column, a pull reads rows later than the cursor less `margin_minutes` (five by default: a row committed by a long transaction carries a time from before it became visible), ordered by it. Without one, the table is read whole on every pull and an unchanged row costs nothing to rewrite; say so to the client before naming a large table. - Deletions: every six hours the keys are listed (`SELECT ` only) and a row that has gone is withdrawn. A table the user can no longer see (ORA-00942, ORA-01031) keeps its rows until it can be listed again. A table taken out of the configuration has its rows withdrawn. - A LOB is read as text up to `max_chars` (100,000) and then marked truncated; a binary value is named by its size and never written to the corpus. ## How to connect 1. In the database, create a user that holds `CREATE SESSION` and `SELECT` on the named tables and views, and nothing else. 2. In LightHouse, open **Connectors**, choose **Oracle Database**, and give the three lines of the credential: the connect string (`host:port/service_name`), the user and its password. They are sealed in your browser to your deployment’s key and kept in your own secrets store; LightHouse never opens them. The deployment must be able to reach the database. 3. In code, set `ORACLE_DB_CREDENTIAL` to the credential’s JSON fields (`dsn`, `user`, `password`) and add a `kind: oracle-db` source card with `tables`, `label` and `requires`. Install the engine’s `oracle` extra (python-oracledb, thin mode: pure Python, no Oracle Instant Client). ## Permissions `CREATE SESSION` and `SELECT` on the named objects, and nothing else; read and write is not offered. The health check connects and lists the session’s privileges, so LightHouse can mark a connection failing whose user could change the database (any DML, DDL or administration privilege). This collector speaks Oracle Net through a database driver, not HTTP, so its read-only test is written its own honest way: it runs the real connect path against a fake `oracledb` driver that records every statement sent, over a first pull, a reconciling pull, the privilege listing and the health check, and asserts that every statement is a SELECT (or the `SET TRANSACTION READ ONLY` that opens each session) and that no write verb appears. In the code, every statement goes through one function that refuses anything but a SELECT, so even a bug cannot write; the database refuses DML in a read-only transaction, and the user’s grants refuse it again. ## Limits - Every identifier (schema, table, column) is checked against Oracle’s unquoted-identifier shape, upper-cased and quoted; a value is only ever a bind variable. A table named `X; DROP TABLE Y` is refused before a connection is opened. - A table is `SCHEMA.NAME`, named once; a row with a null key is skipped. - Pages are 50 to 5,000 rows (500 by default). - The `margin_minutes` margin means a row is read again a little after it is first seen; the contract writer makes an unchanged row free. - The hosts it contacts are the one in the connect string, inside the client’s network. ## Data handling - The columns you name are copied into the deployment’s corpus under the source’s `label`; whatever the tables hold (names, contact details, financial or employment records) is copied, so name the columns, not the table, where a table holds more than the question needs. - The credential is held in the client’s own store; the password is never written to logs, run notes or the corpus, and an error reports an ORA- code, never a message. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------- | | `name the tables to sync; a whole database is never the default` | `tables` is empty | Name the tables | | `not an Oracle identifier` | A schema, table or column name is not a plain Oracle identifier | Use the plain name; no quotes, spaces or punctuation | | `table is SCHEMA.NAME` | A table was named without its schema | Write `SCHEMA.NAME` | | `a table is named twice` | The same table appears twice | Remove the duplicate | | `only SELECT is ever run against a client's database` | A statement that is not a read was about to be sent | Report it; nothing was sent | | `Oracle Database needs the engine's `oracle` extra` | python-oracledb is not installed | Install `aal-engine[oracle]` | | `ORA-01017`, `ORA-28000` or `ORA-01045` | The user or password is wrong, the account is locked, or it lacks CREATE SESSION | Fix the user | | `ORA-00942` or `ORA-01031` when listing | The user cannot see the table | Grant `SELECT`; rows are kept meanwhile | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | python-oracledb 2.x and 3.x, thin mode | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/oracle-db/ --- # Oracle Fusion Cloud Applications > Oracle Fusion Cloud Applications: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the Oracle Fusion Cloud Applications REST resources you name (ERP, HCM and SCM), so finance, people and supply agents can answer from invoices, workers or orders. It signs in with a JWT assertion made with the client’s certificate for a read-only integration user, and sends only GETs. ## At a glance | Collector | Oracle Fusion Cloud Applications, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Oracle: Oracle Fusion Cloud Applications (ERP, HCM, SCM REST) ([the vendor's documentation](https://docs.oracle.com/en/cloud/saas/index.html)) | | Family | ERP | | Kind | ERP | | Ways to connect | Key pair | | Scopes | - Read: `view duties on the named REST resources (Fusion does not state a user's roles)` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Financial, Employment, Identity, Content | | Hosts it may contact | `{pod}.fa.{region}.oraclecloud.com` | | Vendor API versions | Oracle Fusion Cloud Applications REST API 11.13.18.05 and latest (fscmRestApi, hcmRestApi, crmRestApi) | | Lowest engine version | `0.46.0` | ## What it reads - The REST resources you name, each as `{path, key, updated, title, fields}` where `path` is `/resources//` and nothing else. A whole pod is never the default. - Changes by `LastUpdateDate` (or the field named), ordered ascending, paged by offset while `hasMore`. Fusion’s dates carry their offset, so no widening is needed. - Deletions: every six hours the keys are listed (`fields=`) and what has gone is withdrawn. A resource the user cannot read (403, 404) keeps its ids. - A record with a null key is skipped. ## How to connect 1. In Fusion’s Security Console, register the client’s certificate under API Authentication with a trusted issuer name, and create or choose an integration user whose roles hold the view duties of the resources named and nothing that creates or edits. 2. In LightHouse, open **Connectors**, choose **Oracle Fusion Cloud Applications**, and give the pod address, the issuer, the user name and the PEM of the private key and certificate. They are sealed in your browser to your deployment’s key and kept in your own secrets store; LightHouse never opens them. 3. In code, set `ORACLE_FUSION_CREDENTIAL` to the credential’s JSON fields (`pod_url`, `issuer`, `username`, `certificate`) and add a `kind: oracle-fusion` source card with `resources`, `label` and `requires`. ## Permissions Read-only is the integration user’s roles: give it the view duties of the resources named. Fusion does not state a user’s roles to the caller, so the health check reads one resource and the card says the roles were not stated. Fusion’s inbound JWT authentication takes the signed assertion itself as the bearer token: there is no token exchange, no password and no client secret, and the key never leaves the client’s account. Each assertion is valid ten minutes, held in memory and signed again a minute before it lapses. Every request is a `GET` to the sealed pod’s host; the fetcher refuses anything else, a `next` link included. Its read-only test proves it on every change. ## Limits - `pod_url` must be `https://.fa..oraclecloud.com`. - A resource path must match the three families and a version; field names are identifiers; a query value is never built from data. - A resource is named once. - Pages are capped by the pod (500 by default in the tests). - Requests are paced and back off when Fusion asks (`Retry-After`). ## Data handling - The fields you name are copied into the deployment’s corpus under the source’s `label`. Invoices and suppliers are financial records; HCM resources hold employment records and people’s names, so name the fields, not the resource, where a resource holds more than the question needs. - The private key stays in the client’s store; only the signed assertion is sent, and it is never written to logs or run notes. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------- | | `pod_url is https://.fa..oraclecloud.com` | The pod address is not Oracle’s | Use the pod’s address | | `not a Fusion REST resource path` | A resource path is not one of the three families and a version | Use `fscmRestApi/resources//` | | `name the resources to sync; a whole pod is never the default` | `resources` is empty | Name the resources | | `a resource is named twice` | The same resource appears twice | Remove the duplicate | | `HTTP 401` | The assertion was rejected: the certificate, issuer or user is wrong | Check the API Authentication registration | | `HTTP 403` on a resource | The user has no role that reads it | Grant the view duty; its ids are kept meanwhile | | Read succeeded, 0 written | No record changed since the cursor | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Oracle Fusion Cloud Applications REST API 11.13.18.05 and latest | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 1 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/oracle-fusion/ --- # Plusgrade > Plusgrade: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Plusgrade is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Plusgrade’s partner API reference or reporting export specification (bid offers, bid status, upgrade outcomes, revenue), issued to the airline through its account. Nothing about Plusgrade’s API is public (checked 6 November 2026): no developer portal, reference or integration guide. A bid names a passenger, so its record is personal data, read and indexed in your deployment only. ## At a glance | Collector | Plusgrade, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Reads | Plusgrade: Plusgrade upgrade and ancillary platform (partner API) ([the vendor's documentation](https://www.plusgrade.com)) | | Family | Aviation | | Kind | Ancillaries | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: upgrade bids, their status and outcomes, and revenue reporting, read in place; no bid is placed, changed, accepted or declined. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Plusgrade’s partner API reference or reporting export specification (bid offers, bid status, upgrade outcomes, revenue), issued to the airline through its account, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: plusgrade label: internal api: spec_ref: "Plusgrade partner API / reporting export specification, version" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Ancillaries and upgrades} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Plusgrade: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/plusgrade/ --- # Ideagen Q-Pulse > Ideagen Q-Pulse: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads occurrences, with their data fields, from your Q-Pulse through its web services, read-only, inside your deployment, with reporters left out. ## At a glance | Collector | Ideagen Q-Pulse, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------- | | Reads | Ideagen: Q-Pulse web services (SOAP) ([the vendor's documentation](https://www.ideagen.com/)) | | Family | Aviation | | Kind | Quality | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object]; \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | Q-Pulse Web Service APIs, API 2.100.7800.0 (namespace v1.2) | | Lowest engine version | `0.46.0` | ## What it reads - Occurrences reported in the last `days_back` days (1 to 3650, default 30; `first_days_back`, default 365, on the first run), listed by `GetOccurrenceIDs` with `ReportedOnOrAfter` and read one by one with `GetOccurrence`. - One record per occurrence: its number, title, report type, reported date and data fields. - Only those three operations are sent (`Authenticate`, `GetOccurrenceIDs`, `GetOccurrence`). The service also creates and accepts occurrences; no envelope for either exists here. ## How to connect 1. Create a dedicated integration user in Q-Pulse with read access to occurrences, and note the database name. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Ideagen Q-Pulse**, and leave the access level at **Read**. 3. Name `base_url` (the https service path of your Q-Pulse web services) and `database`. To leave a data field that names a person out, list its name in `exclude_data_fields`. 4. Paste the integration user and then its password. Your browser seals them to your deployment, which hands them to the collector as `QPULSE_USER` and `QPULSE_PASSWORD`. Q-Pulse signs in by a SOAP envelope, so your deployment checks the sign-in at the first sync. ## Permissions - The integration user’s own rights in Q-Pulse are the permission. Give it read access to occurrences only. - Every request is a SOAP `POST` to one of the three read operations in the manifest’s `read_operations`. https is required, because the user’s password travels in the Authenticate envelope (Ideagen’s examples use plain http). - Your deployment refuses to store this credential at read and write. ## Limits - Q-Pulse queries occurrences by reported date, not by change: each run re-reads the occurrences reported in the last `days_back` days; unchanged ones are not rewritten. An occurrence changed after its window closes is caught by a wider window, or one run with `days_back` raised. - Requests are paced at 0.5 s (`delay_s`). - The service path varies by installation; the manifest’s host is `*` for that reason. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never an occurrence. - Reporters are protected by default: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details are left out of every record before it is written, as are travel document numbers and dates of birth. Just culture and data protection both need a reporter kept from anyone who does not need them. Names are matched whatever the case, spacing, `_` or `-`, so `reporterName` also catches an export’s `Reporter Name`. - `exclude_fields` adds paths (for example `**.contact`); `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. Free-text narratives are indexed as written and may still name people: add the fields that hold them to `exclude_fields`. - Nothing is cached raw, and a failure names the host and the status, never the URL. - `ReportedByPersonName` and `RecordedByPersonName` are left out by name. A data field is a name and a value in a list, so a path cannot select it: name any that holds a person in `exclude_data_fields`. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------ | | `credential variable 'QPULSE_USER' is not set` | The deployment has not been given the user or password | Connect the credential again | | `POST host: Authenticate returned a fault` | Q-Pulse refused the user, password or database | Check the integration user and the database name | | `POST host: the response is not XML` | The address is not the web services path | Check `base_url` against Q-Pulse’s service path | | `POST host: no AuthenticateResult` | The response is not a Q-Pulse answer | As above | | `Q-Pulse returned no token` | The sign-in answered without a token | Check the database name and the user’s licence | | `base_url is the https service path of the Q-Pulse web services` | `base_url` is not https | Use the https address | | `name the Q-Pulse database` | No database was named | Name it | | `days_back and first_days_back are 1 to 3650` | A window is out of range | Correct it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Q-Pulse Web Service APIs, API 2.100.7800.0 (namespace v1.2) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/qpulse/ --- # QuickBooks Online > QuickBooks Online: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a QuickBooks Online company’s accounts, customers, vendors, invoices, bills, payments, bill payments, journal entries and reports, so finance agents can answer from the books. It only reads. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | QuickBooks Online, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Intuit: QuickBooks Online Accounting API ([the vendor's documentation](https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/account)) | | Family | Finance | | Kind | Accounting | | Ways to connect | OAuth approval | | Scopes | - Read: `com.intuit.quickbooks.accounting` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Financial, Contact | | Hosts it may contact | `quickbooks.api.intuit.com`, `sandbox-quickbooks.api.intuit.com`, `oauth.platform.intuit.com`, `{host}` | | Vendor API versions | Accounting API v3, minorversion 75 | | Lowest engine version | `0.46.0` | ## What it reads - **Company information.** - **Accounts, customers, vendors, invoices, bills, payments, bill payments and journal entries**, each with its amounts and currency (the company’s home currency where a record names none). - **Reports:** profit and loss, balance sheet, aged receivables, aged payables. - The first read queries each entity in pages of 1,000. Later reads ask change data capture (`/cdc`) for what changed since the last pull; a record marked `Deleted` is removed. CDC looks back at most 30 days, so a cursor older than 29 days reads everything again. It does not read attachments, payroll or inventory. ## How to connect 1. In Intuit’s developer portal, make your own app and connect your company to it, giving the `com.intuit.quickbooks.accounting` scope. 2. In LightHouse, open **Setup and admin, Connectors** and choose **QuickBooks Online**. 3. Paste the client id, client secret and refresh token, and give the company’s id (`realm_id`) and the environment (`production` or `sandbox`). Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_QUICKBOOKS` by default): `client_id`, `client_secret`, `refresh_token`, `realm_id`, `environment`. ## Permissions This collector is **read-only** in what it does: `GET` requests (queries, change data capture and reports), and one `POST` to Intuit’s token endpoint (`/oauth2/v1/tokens/bearer`). Its read-only test proves it on every change. - **The scope is not read-only.** Intuit offers one accounting scope, `com.intuit.quickbooks.accounting`, which can write; there is no read-only variant. The code cannot narrow it, and it does not refuse it: the health check states it as `Intuit's com.intuit.quickbooks.accounting scope can write and has no read-only variant; this connector only reads`. What stops a write is that the collector never sends one. - **Refused by the code:** nothing, by scope. - **Not a funds-moving system:** QuickBooks records payments in the ledger; its API does not move money. - **Refresh token:** Intuit rolls it; the new one is written back to your own secret store in your deployment at once (not to Intuit), and the previous one lapses a day later. - **Hosts:** `quickbooks.api.intuit.com` or `sandbox-quickbooks.api.intuit.com`, and `oauth.platform.intuit.com` for the token, over https. ## Limits - Accounting API v3 at `minorversion=75`. - Requests are paced (0.15 s apart) and retried on 429 and 5xx; Intuit allows 500 a minute per company. - `realm_id` must be digits, and `environment` `production` or `sandbox`. - Reports are as Intuit gives them: amounts as text. ## Data handling - Customers, vendors, invoices and bills hold personal and financial data. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------- | | `QuickBooks answered HTTP 401 (the app or its consent was refused)` | The client, secret or refresh token was refused | Check the app, or consent again | | `realm_id is the company's id, digits` | `realm_id` is not numeric | Use the company id from Intuit | | `environment is production or sandbox` | The environment is something else | Correct it | | `QuickBooks answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | | `QuickBooks answered HTTP 403` | The app or user lacks access to the company | Reconnect the company to the app | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Accounting API v3, minorversion 75 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/quickbooks/ --- # Ramco Aviation > Ramco Aviation: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Ramco Aviation is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Ramco’s aviation API documentation from its API store (signed in), with sandbox credentials, and the OAuth scopes that read only (work orders, task cards, defects and components). developer.ramco.com describes a sandbox after registration; its API store lists nothing until signed in. ## At a glance | Collector | Ramco Aviation, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Reads | Ramco Systems: Ramco Aviation maintenance and engineering APIs ([the vendor's documentation](https://developer.ramco.com)) | | Family | Aviation | | Kind | Maintenance | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: Ramco maintenance records read in place, sandbox first, then production. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Ramco’s aviation API documentation from its API store (signed in), with sandbox credentials, and the OAuth scopes that read only (work orders, task cards, defects and components), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: ramco label: internal api: spec_ref: "Ramco aviation API documentation, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Maintenance} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers and dates of birth, and health or disability special service requests. Contact details are not left out by default for a maintenance system, whose records name engineers and sign-offs; add the fields that hold them to `exclude_fields`. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Ramco Systems: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/ramco/ --- # Revolut Business > Revolut Business: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Revolut Business account’s accounts and balances, bank details, transactions, counterparties, expenses, FX rates and cards (never card numbers), so cash and reconciliation agents can check them against the books. It is read-only, and it is built to refuse a consent that can pay or read card numbers. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Revolut Business, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Reads | Revolut: Revolut Business API ([the vendor's documentation](https://developer.revolut.com/docs/business/business-api)) | | Family | Finance | | Kind | Bank | | Ways to connect | OAuth approval, Key pair | | Scopes | - Read: `READ` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | Yes | | Personal data | Financial, Contact | | Hosts it may contact | `b2b.revolut.com`, `sandbox-b2b.revolut.com`, `revolut.com`, `{host}` | | Vendor API versions | Business API 1.0 | | Lowest engine version | `0.46.0` | ## What it reads - **Accounts and balances:** balance per account, with name, state and the account’s bank details (IBAN, BIC, account number, sort code, beneficiary). A snapshot: rewritten only when it changes. - **FX rates** for the pairs you name in `fx_pairs` (for example `EUR/USD`). - **Counterparties:** name, type, state and their account identifiers. - **Cards:** only the id, last four digits, state, label, holder, product, whether virtual, and dates. A card number, CVV or expiry is never requested and never recorded. - **Transactions and expenses**, newest first in windows, from the last cursor less a week (so a transaction whose state moved on is read again). Each transaction’s legs carry amount, fee, currency, account, description and counterparty id. Expenses are skipped on plans that do not have them. - The first read goes back `history_days` (default 90, at most 3,650). ## How to connect 1. In Revolut Business, open Settings, APIs, Business API; upload the public key of a key pair you made, with your deployment’s redirect domain. 2. Consent with the **READ** scope only. 3. In LightHouse, open **Setup and admin, Connectors**, choose **Revolut Business**, and give the environment (`production` or `sandbox`) and any `fx_pairs`. 4. Paste the client id, the private key (PEM), the issuer (the redirect domain), and the refresh token (or the one-off authorisation code), and confirm the consent was READ only. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_REVOLUT` by default): `client_id`, `private_key`, `issuer`, `environment`, and `refresh_token` or `authorization_code`, and `view_only_confirmed` when needed. ## Permissions This collector is **read-only** in what it does: `GET` requests, and one `POST /api/1.0/auth/token` to exchange the token. Its read-only test proves it on every change. Nothing is paid, transferred or changed. - **Refused by the code:** where Revolut’s token answer states the granted `scope`, a consent that includes **WRITE**, **PAY** or **READ_SENSITIVE_CARD_DATA** is refused, naming it. The error is, for example, `Revolut: refused: the credential can pay (PAY scope), read card numbers (READ_SENSITIVE_CARD_DATA); make a view-only one` (naming whichever apply). - **Not detectable by the code:** if the token answer carries no `scope`, Revolut does not state what was consented. The collector then reads only once you have confirmed the certificate was consented with READ only (`view_only_confirmed`); without it the error is `Revolut does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read`. - **Signing:** each access token is minted with a client assertion, a JWT signed here with your private key (RS256; `iss` the issuer, `sub` the client id, `aud` `https://revolut.com`, five minutes). The private key never leaves your store. `revolut.com` is only the audience; it is never contacted. - **Refresh token:** Revolut documents it as not expiring, but a withdrawn consent ends it. When a one-off authorisation code is exchanged, the new refresh token is written back to your own secret store in your deployment (not to Revolut) and the code is dropped. - **Hosts:** only `b2b.revolut.com` or `sandbox-b2b.revolut.com`, over https; redirects are never followed. ## Limits - Business API 1.0. - Requests are paced one second apart and retried on 429 and 5xx with back-off. - Transactions are paged down by `to` date, 1,000 a page; expenses 500. - The access token lasts 40 minutes and is minted again as needed. - Amounts are exact decimals; a number that arrives as a float is refused. ## Data handling - Records hold financial and personal data: balances, bank details, transactions, counterparties’ names and account identifiers, and cardholders’ ids. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------- | | `Revolut: refused: the credential can pay (PAY scope); make a view-only one` | The consent includes a scope that moves money or reads card numbers (named) | Consent again with READ only | | `Revolut does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | The consent’s scope is not stated and you have not confirmed | Confirm it was READ only | | `Revolut answered HTTP 401 (consent again in Revolut Business)` | The refresh token was refused (withdrawn or expired consent) | Consent again in Revolut Business | | `Revolut: neither a refresh token nor an authorisation code` | The credential has neither | Re-enter the credential | | `fx_pairs are currency pairs, e.g. EUR/USD` | A pair is not two 3-letter codes | Correct the pair | | `environment is production or sandbox` | The environment is something else | Correct it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Business API 1.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/revolut/ --- # Amazon S3 > Amazon S3: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the objects under a bucket and prefix of Amazon S3, in place, by ETag, so agents can answer from the documents a team keeps there. Access is by an IAM role the client’s own account grants, never an access key. ## At a glance | Collector | Amazon S3, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Reads | Amazon Web Services: Amazon S3 ([the vendor's documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)) | | Family | Storage | | Kind | Files | | Ways to connect | Service account | | Scopes | - Read: `s3:ListBucket`, `s3:GetObject`, `sts:AssumeRole` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Content | | Hosts it may contact | `*.amazonaws.com`, `s3.console.aws.amazon.com` | | Vendor API versions | Amazon S3 REST API (ListObjectsV2, GetObject), AWS STS AssumeRole | | Lowest engine version | `0.45.0` | ## What it reads - Objects under the bucket (and `prefix`, if given): text, Markdown, CSV, PDF, Word (`.docx`), PowerPoint (`.pptx`) and Excel (`.xlsx`), as the folder and SharePoint collectors read them. - The cursor is each object’s ETag: an unchanged object is never fetched again, and one that has gone (deleted, or moved out of the prefix) is withdrawn. - Skipped and counted: any other format, an object over `max_mb` (50 by default) and a document that will not open. - Names starting with `.` and keys ending in `/` are ignored. ## How to connect 1. In the account that owns the bucket, create an IAM role that grants `s3:ListBucket` on the bucket (for the prefix) and `s3:GetObject` on its objects, and whose trust policy lets the deployment’s identity assume it, with an external ID if you want one. 2. In LightHouse, open **Connectors**, choose **Amazon S3**, give the bucket, prefix, region, role ARN and external ID, a label and how often to read. No access key is ever pasted, stored or sealed: the ARN and external ID are identifiers, and the trust policy is the permission. 3. In code, add a `kind: s3` source card with `bucket`, `prefix`, `region`, `role_arn`, `external_id`, `label` and `requires`. Without `role_arn` the deployment’s own identity reads the bucket, for a bucket in the same account. ## Permissions `s3:ListBucket` on the prefix and `s3:GetObject` on its objects, through `sts:AssumeRole`. The collector only reads: it calls `ListObjectsV2` and `GetObject`, and `AssumeRole` to take on the role for an hour; it never puts, copies, deletes or changes an ACL. S3 is reached through the AWS SDK (boto3), not an HTTP client the network recorder can see, so its read-only test replaces `boto3.client` with a recorder and asserts that every operation is one of those three and that no `put_`, `delete_`, `copy_` or `create_` call appears. The manifest’s `read_operations` lists the STS call, which is a POST that changes nothing in the bucket. ## Limits - Objects over `max_mb` (50 by default) and unsupported formats are skipped and counted. - `bucket` must be an S3 bucket name, `role_arn` an IAM role’s ARN, `external_id` 2 to 1224 letters, digits and `+=,.@:/-`, and `region` an AWS region such as `eu-west-1`. - PDFs need `pdftotext` in the image. - The assumed role’s credentials last an hour. - Each record links to the object in the AWS console; the console address is a link only, never contacted. ## Data handling - Object text is copied into the deployment’s corpus under the source’s `label`. Documents can hold personal data of any kind. - No access key is held. The assumed role’s temporary credentials exist in memory for the run and are never written to logs or run notes. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------- | | `bucket is an S3 bucket name` | The bucket is not a valid S3 bucket name | Use the bucket’s name, not its address | | `role_arn is an IAM role's ARN` | The role is not given as an ARN | Use `arn:aws:iam:::role/` | | `external_id is 2 to 1224 letters, digits and +=,.@:/-` | The external ID has other characters | Correct it | | `region is an AWS region, e.g. eu-west-1` | The region is malformed | Use a region name | | `AccessDenied` when assuming the role | The trust policy does not allow the deployment’s identity, or the external ID differs | Fix the trust policy | | `AccessDenied` on list or get | The role lacks `s3:ListBucket` or `s3:GetObject` | Grant them on the prefix | | Read succeeded, 0 written | No object’s ETag changed | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Amazon S3 REST API (ListObjectsV2, GetObject); AWS STS AssumeRole | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/s3/ --- # Sabre airline-hosted > Sabre airline-hosted: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. ![](/_astro/sabre.BwCnXmzW.png)Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Sabre airline-hosted is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Sabre’s airline-hosted API reference (SabreSonic Res and Check-in and Digital Connect: reservation retrieve, flight status and passenger list reads), issued with the airline’s Sabre agreement. These APIs need an airline relationship with Sabre. No booking, ticketing or check-in call exists in the adapter. ## At a glance | Collector | Sabre airline-hosted, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Reads | Sabre: SabreSonic and Digital Connect airline-hosted APIs ([the vendor's documentation](https://developer.sabre.com/)) | | Family | Aviation | | Kind | Reservations | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: the airline’s own reservations and departure lists read in place; no booking, ticketing or check-in call exists in the adapter. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Sabre’s airline-hosted API reference (SabreSonic Res and Check-in and Digital Connect: reservation retrieve, flight status and passenger list reads), issued with the airline’s Sabre agreement, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: sabre-airline label: internal api: spec_ref: "Sabre airline-hosted API reference (SabreSonic / Digital Connect), release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Reservations} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Sabre (airline-hosted): needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sabre-airline/ --- # Sabre > Sabre: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. ![](/_astro/sabre.BwCnXmzW.png)Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the bookings you name, by confirmation id, from Sabre’s Get Booking API, read-only, inside your deployment. Travel documents are left out. ## At a glance | Collector | Sabre, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------- | | Reads | Sabre: Sabre Get Booking (REST) ([the vendor's documentation](https://developer.sabre.com/)) | | Family | Aviation | | Kind | Reservations | | Ways to connect | OAuth approval | | Scopes | - Read: | | Read only | Yes, except: \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | `api.platform.sabre.com`, `api-crt.cert.havail.sabre.com`, `{environment}` | | Vendor API versions | Auth token v2 (/v2/auth/token), Get Booking (/v1/trip/orders/getBooking) | | Lowest engine version | `0.46.0` | ## What it reads - For each confirmation id you name: the booking, from `POST /v1/trip/orders/getBooking`. Sabre defines this retrieval as a `POST`; it is a read. - One record per booking, with the booking’s traveller count in its metadata. The rest of the response is indexed as served, minus the excluded fields. - A booking that answers 404 is gone: its record is withdrawn. - It never searches or lists: you name the bookings. The airline-hosted reservation APIs are a separate collector that needs onboarding. ## How to connect 1. Make a Dev Studio application at Sabre for certification credentials; production credentials come through your Sabre account manager (an EPR). 2. In LightHouse, open **Setup and admin, Connectors**, choose **Sabre**, and leave the access level at **Read**. 3. Name the `environment` (`cert` or `production`) and the `confirmations` (5 to 8 letters and digits). 4. Paste the EPR credential (`V1:::`) and then its password. Your browser seals them to your deployment, which hands them to the collector as `SABRE_CLIENT_ID` and `SABRE_CLIENT_SECRET`. ## Permissions - The collector asks for no scope and refuses a token whose granted scope names a write. - It sends two `POST`s and nothing else: the token request (`/v2/auth/token`) and Get Booking (`/v1/trip/orders/getBooking`), both listed in the manifest’s `read_operations`. The path of the second is fixed in code. - Your deployment refuses to store this credential at read and write. The environment you choose picks the host; a certification token works only in certification. ## Limits - Sabre publishes no paging, rate limit or change feed for this call: the named bookings are read again each run and unchanged ones are not rewritten. - The host and token facts come from Sabre’s own pages as search indexes them (developer.sabre.com no longer serves pages to an automated reader); confirm them in Dev Studio when connecting. - The default pace is one request a second (`delay_s`); `429` and `5xx` are retried with backoff and `Retry-After`. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a booking or a traveller. - Nothing is cached raw: a raw cache would keep on disk the fields the exclusion removes. A failure names the host and the status, never the URL, because a URL can carry a record locator or a bag tag. - By default travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set) are left out before a record is written. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------- | | `credential variable 'SABRE_CLIENT_ID' is not set` | The deployment has not been given the credential | Connect it again | | `the Sabre client id is V1:::` | The EPR credential is not in Sabre’s form | Paste the full `V1:...` string | | `POST api-crt.cert.havail.sabre.com: HTTP 401` | Sabre refused the credential | Check the environment (a certification credential does not work on production) and the password | | `POST api-crt.cert.havail.sabre.com: no access token` | The token response held no token | Check the credential and the environment | | `environment is cert or production` | Any other value | Choose one of the two | | `name the bookings to read by confirmation id` | No confirmation id | Name at least one | | `N confirmation ids are not 5 to 8 letters and digits` | A confirmation id is malformed | Correct the ids | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Auth token v2, Get Booking (/v1/trip/orders/getBooking) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sabre/ --- # Vistair SafetyNet > Vistair SafetyNet: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Vistair SafetyNet is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from SafetyNet’s API or integration guide from Vistair or Comply365 (reports, investigations, risks and actions, read-only). There is no public reference; Vistair’s product page now redirects to Comply365’s site. ## At a glance | Collector | Vistair SafetyNet, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------- | | Reads | Vistair (now part of Comply365): Vistair SafetyNet ([the vendor's documentation](https://www.comply365.com/)) | | Family | Aviation | | Kind | Safety | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: SafetyNet’s reports and investigations read in place, reporters left out. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need SafetyNet’s API or integration guide from Vistair or Comply365 (reports, investigations, risks and actions, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: safetynet label: internal api: spec_ref: "SafetyNet API / integration guide, version, as issued by the vendor" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Safety management} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Vistair (now part of Comply365): needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/safetynet/ --- # Salesforce > Salesforce: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads accounts, opportunities, cases (with their comments) and published Knowledge articles from a Salesforce org, so commercial and service agents can answer from the account and case history. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Salesforce, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Salesforce: Sales Cloud and Service Cloud (REST API, SOQL) ([the vendor's documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_what_is_rest_api.htm)) | | Family | CRM | | Kind | CRM | | Ways to connect | OAuth approval | | Scopes | - Read: `api` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `{org}.my.salesforce.com`, `{org}.sandbox.my.salesforce.com`, `login.salesforce.com`, `test.salesforce.com` | | Vendor API versions | REST API v61.0 | | Lowest engine version | `0.46.0` | ## What it reads - **Accounts:** name, type, industry, website, billing city and country, description. - **Opportunities:** name, account name, stage, amount, close date, probability, type, next step, description. - **Cases:** case number, subject, account name, status, priority, origin, type, description, and every comment on the case. - **Knowledge articles:** published (`Online`) versions only: title, article number, summary, URL name, language, last published date, and any rich-text fields you name in `knowledge_fields`. One document per article; a new version replaces the old one. - Only the objects you name in `objects` (`accounts`, `opportunities`, `cases`, `knowledge`). A whole org is never the default. - Changes only: each object is queried by `SystemModstamp` after the last cursor, oldest first, and paged by `nextRecordsUrl`. It does not read attachments, files, or any object you do not name. ## How to connect 1. In Salesforce, make a connected app with a digital certificate and the `api` scope, and pre-authorise the integration user for it. 2. Give that user a read-only permission set over Account, Opportunity, Case and your Knowledge object. 3. In LightHouse, open **Setup and admin, Connectors**, choose **Salesforce**, and give `instance_url` (your My Domain, `https://.my.salesforce.com`; a sandbox is `https://.sandbox.my.salesforce.com`), `username` and `objects`. 4. Paste the connected app’s consumer key, then the PEM of the private key. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`SALESFORCE_CREDENTIAL` by default) with `instance_url`, `client_id`, `username` and `certificate`. The deployment signs a two-minute assertion with the key (the OAuth 2.0 JWT bearer flow, RFC 7523) and Salesforce answers a session token. No client secret and no password exist anywhere, and the key never leaves your account. ## Permissions - **Scope requested:** `api`. Salesforce has no read-only OAuth scope: `api` lets the user’s own permissions decide, so **read-only is the integration user’s profile**, not something the scope can enforce. - **What the collector does:** `GET` queries, plus one `POST` to `/services/oauth2/token` for the session token. It issues SOQL `SELECT` statements only. Its read-only test proves that on every change. - **One host:** the token is asked for at the org’s own My Domain and every read goes there. An answer that names another instance is refused before anything is read, and the fetcher refuses any URL off that host. The two Salesforce login addresses (`login.salesforce.com`, `test.salesforce.com`) appear only as the audience of the signed assertion and are never contacted. ## Limits - `instance_url` must be a My Domain: `https://.my.salesforce.com` (optionally `.sandbox.`, `.develop.` or `.scratch.` before `.my.`). - Targets REST API v61.0. - Batches of 200 to 2,000 records (`page_size`, default 2,000). Reads count against your org’s daily API allowance. - Deletions are found by listing ids every six hours; a deleted record or an archived article is removed from the corpus then, not at once. - A refused or failed page fails the pull, which tries again on the next run and never advances the cursor past what it did not read. - Knowledge: set `knowledge_object` if yours is not `Knowledge__kav`. ## Data handling - Records contain personal data (people’s names, account and case text). Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. - The private key is used only to sign the assertion. It is never put in a request, a log line or an error message. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------- | | `credential variable 'SALESFORCE_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect Salesforce again in LightHouse | | `the salesforce credential has no client_id` | The credential lacks a field (named in the message) | Re-enter it with all four fields | | `instance_url is https://.my.salesforce.com` | The URL is not a My Domain | Use your My Domain, not `login.salesforce.com` | | `the Salesforce certificate holds no readable private key` | The PEM is not an unencrypted private key | Paste the PEM of the key, without a passphrase | | `Salesforce answered no session token` | The connected app or user was refused | Check the certificate on the connected app and the user’s pre-authorisation | | `Salesforce answered for another instance; nothing was read` | The token came from a different org | Check `instance_url` is the org the app belongs to | | `HTTP 403` or `HTTP 404` on a listing | The user cannot see that object | Give the user read access; the deletion check is skipped meanwhile | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | REST API v61.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/salesforce/ --- # SAP S/4HANA > SAP S/4HANA: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 0.1.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the business records of an SAP S/4HANA system through SAP’s released OData v2 APIs: orders, invoices, stock movements, products, journal entries, cost centres and organisations. Each record becomes one document in the knowledge base. It reads; it never writes, and it does not read personal data. Status: **Built, not certified** (needs an SAP S/4HANA sandbox). ## At a glance | Collector | SAP S/4HANA, version `0.1.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | SAP: SAP S/4HANA (OData v2 released APIs) ([the vendor's documentation](https://api.sap.com/products/SAPS4HANACloud/apis/ODATAV2)) | | Family | ERP | | Kind | ERP | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: `API_SALES_ORDER_SRV`, `API_PURCHASEORDER_PROCESS_SRV`, `API_SUPPLIERINVOICE_PROCESS_SRV`, `API_MATERIAL_DOCUMENT_SRV`, `API_PRODUCT_SRV`, `API_JOURNALENTRYITEMBASIC_SRV`, `API_COSTCENTER_SRV`, `API_BUSINESS_PARTNER` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `*.s4hana.cloud.sap`, `*.s4hana.ondemand.com`, `*.hana.ondemand.com`, `*.accounts.ondemand.com`, `*.accounts.cloud.sap` | | Vendor API versions | OData v2 (released APIs) | | Lowest engine version | `0.47.0` | ## What it reads You choose which of these to read; a whole system is never the default. | Object | API and entity | Notes | | -------------------- | ------------------------------------------------------ | ----------------------------------------------------- | | `sales_orders` | API_SALES_ORDER_SRV, A_SalesOrder | order headers | | `purchase_orders` | API_PURCHASEORDER_PROCESS_SRV, A_PurchaseOrder | order headers | | `supplier_invoices` | API_SUPPLIERINVOICE_PROCESS_SRV, A_SupplierInvoice | invoice headers | | `material_documents` | API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader | stock movement headers | | `products` | API_PRODUCT_SRV, A_Product | product master | | `journal_entries` | API_JOURNALENTRYITEMBASIC_SRV, A_JournalEntryItemBasic | ledger line items, without item text | | `cost_centres` | API_COSTCENTER_SRV, A_CostCenter | with the cost centre’s name | | `business_partners` | API_BUSINESS_PARTNER, A_BusinessPartner | organisations only (`BusinessPartnerCategory eq '2'`) | Fields are selected by name. Changes are found by the entity’s change field (`LastChangeDateTime` or `LastChangeDate`); an entity with none is read in full each time, and only what changed is rewritten. **What it never reads.** Business partners who are people, employees, contacts and addresses; payroll and employee cost postings; bank details and tax ids. As a last guard, any field whose name matches the personal-data deny-list (compensation, salary, pay, bonus, national and tax ids, bank, birth, home address, personal email and phone, ethnicity, gender, marital status, disability, medical, health, religion, visa, benefits, and any reference to a person, employee or worker) is dropped before a record is written, and only the number dropped is noted on the record. ## How to connect 1. In S/4HANA, create a **communication user** and a **communication arrangement** for the services above (Cloud public edition: the communication scenarios for those APIs), or an **OAuth 2.0 client** with the client-credentials grant. Give it read on those services only. 2. In LightHouse, open **Connectors** and choose **SAP S/4HANA**. 3. Enter the API address (`https://` and the host, nothing after it), and either the OAuth token address, client id and client secret, or the communication user and password. Give exactly one of the two. 4. Choose a label for what the records are (for example `internal`), the objects to read, and how often. Nothing reads on a schedule until you choose one. The secrets are sealed in your deployment and never shown again. ## Permissions Read on the named services, and nothing that creates or changes. The collector sends only `GET` requests to the entity sets; the one `POST` is the OAuth token request. It never uses `$batch`, function imports or a CSRF token (those exist to write). Its read-only test proves it on every change. This release takes read-only credentials only. ## Limits - One system per source. - The hosts it contacts are the API host and, for OAuth, the token host in your credential, and no others. A redirect is never followed. The manifest lists SAP’s cloud domains; a gateway host you name yourself is also read, pinned by the sealed credential. - Cost centres have no change field, so they are read in full each time. - Journal entries use the posting date as their change field and look back 35 days each time, so a posting back-dated further than that is not seen until a first read is repeated. - Entity and field names follow SAP’s published API descriptions; a system with different releases may lack a field. A missing field is left out. - Deletions are found by listing keys every six hours. - Requests are paced and back off when the system asks. ## Data handling - No personal data is read by default (see “What it reads”). - The responses are not cached; only the records written are kept, in your deployment. - Nothing leaves your deployment: the collector runs inside it, and only the counts of items read reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | `auth_failed` | The client or user was refused (401, or an invalid client at the token address) | Check the secret and the token address; create a new one if it was rotated | | `scope_missing` | The user or client may not read the service (403) | Add the communication scenario or role for that API | | `unreachable` | The system did not answer, or answered with an error | Check the API address and that the system is up | | `HostNotAllowed` | A request went to a host that is not in your credential | Correct the credential; the collector does not read elsewhere | | Read succeeded, 0 written | Nothing changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `0.1.0` | `0.47.0` | OData v2 (released APIs) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sap-s4hana/ --- # SAP SuccessFactors > SAP SuccessFactors: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 0.1.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the structure of an organisation from SAP SuccessFactors through its OData v2 API: departments, locations, job codes, positions and job requisitions. Each record becomes one document in the knowledge base. It reads; it never writes, and it does not read any employee’s record. Status: **Built, not certified** (needs an SAP SuccessFactors sandbox). ## At a glance | Collector | SAP SuccessFactors, version `0.1.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | SAP: SAP SuccessFactors (OData v2 API) ([the vendor's documentation](https://help.sap.com/docs/successfactors-platform/sap-successfactors-api-reference-guide-odata-v2)) | | Family | ERP | | Kind | Hr | | Ways to connect | OAuth approval | | Scopes | - Read: `FODepartment`, `FOLocation`, `FOJobCode`, `Position`, `JobRequisition` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `*.successfactors.com`, `*.successfactors.eu`, `*.successfactors.cn`, `*.sapsf.com`, `*.sapsf.eu`, `*.sapsf.cn`, `*.accounts.ondemand.com`, `*.accounts.cloud.sap`, `*.hana.ondemand.com` | | Vendor API versions | OData v2 | | Lowest engine version | `0.47.0` | ## What it reads | Object | Entity | | ------------------ | --------------------------------------------------- | | `departments` | FODepartment | | `locations` | FOLocation (without street addresses) | | `job_codes` | FOJobCode | | `positions` | Position (without the person in it) | | `job_requisitions` | JobRequisition (without recruiter and salary range) | You choose which to read; a whole tenant is never the default. Changes are found by `lastModifiedDateTime`. **What it never reads.** Employee records and payroll: PerPerson, PerPersonal, EmpJob, EmpEmployment, EmpCompensation, EmpPayCompRecurring, PerNationalId, PerEmail, PerPhone, PerAddress, bank details, benefits, performance and health data. No object in this release reads them. As a last guard, any field whose name matches the personal-data deny-list (compensation, salary, pay, bonus, national and tax ids, bank, birth, home address, personal email and phone, ethnicity, gender, marital status, disability, medical, health, religion, visa, benefits, and any reference to a person, employee, manager or recruiter) is dropped before a record is written, and only the number dropped is noted on the record. ## How to connect 1. In your SAP Cloud Identity Services tenant (or the OAuth client registration your SuccessFactors tenant uses), register an **OAuth 2.0 client** for client credentials and note the token address, client id and client secret. 2. Give the API user behind it **read** on the entities above and nothing else (role-based permissions, with no employee data). 3. In LightHouse, open **Connectors** and choose **SAP SuccessFactors**. 4. Enter the data centre’s API address (for example `https://api55.sapsf.eu`), your company id, the token address, client id and client secret. 5. Choose a label, the objects to read, and how often. The secrets are sealed in your deployment and never shown again. ## Permissions Read on the entities above. The collector sends only `GET` requests; the one `POST` is the OAuth token request. Its read-only test proves it on every change. This release takes read-only credentials only. ## Limits - OAuth 2.0 client credentials only. SAML bearer assertions are not supported in this release, and there is no Basic fallback. - The API address must be a SuccessFactors data-centre host (`api*.successfactors.com`, `.eu`, `.cn`, or `api*.sapsf.com`, `.eu`, `.cn`). The token host in your credential is the only other host contacted. A redirect is never followed. - Effective-dated entities are read as the API returns them; a record that changes its start date appears as a new record. - Deletions are found by listing keys every six hours. - Entity and field names follow SAP’s published API descriptions; a field a tenant lacks is left out. - Requests are paced and back off when the API asks. ## Data handling - No personal data is read (see “What it reads”). - The responses are not cached; only the records written are kept, in your deployment. - Nothing leaves your deployment: the collector runs inside it, and only the counts of items read reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------- | | `auth_failed` | The client was refused at the token address (invalid client or grant), or the API returned 401 | Check the client id, secret, company id and token address | | `scope_missing` | The API user may not read the entity (403) | Grant read on that entity in role-based permissions | | `unreachable` | The API did not answer, or answered with an error | Check the data-centre address and that the tenant is up | | `HostNotAllowed` | A request went to a host that is not in your credential | Correct the credential | | Read succeeded, 0 written | Nothing changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------- | ----------------------------------- | -------------- | | 10 November 2026 | `0.1.0` | `0.47.0` | OData v2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sap-successfactors/ --- # ServiceNow > ServiceNow: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads incidents, changes, CMDB configuration items and published Knowledge articles from one ServiceNow instance, so operations agents can answer from the incident and change history. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | ServiceNow, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | ServiceNow: ServiceNow Table API (incidents, changes, CMDB, Knowledge) ([the vendor's documentation](https://developer.servicenow.com/dev.do#!/reference/api/latest/rest/c_TableAPI)) | | Family | ITSM | | Kind | Tickets | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: `snc_read_only` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `{instance}.service-now.com` | | Vendor API versions | Table API (/api/now/table) | | Lowest engine version | `0.46.0` | ## What it reads - **Incidents** (`incident`): number, short description, state, priority, impact, urgency, category, assignment group, configuration item, opened and resolved dates, close code, description, close notes. - **Changes** (`change_request`): type, state, risk, impact, assignment group, configuration item, start and end dates, and the description fields. - **CMDB** configuration items: `cmdb_ci`, or the one class you name in `cmdb_class` (for example `cmdb_ci_server`). - **Knowledge** (`kb_knowledge`): published articles only, the HTML body as text. - Only the objects you name in `objects` (`incidents`, `changes`, `cmdb`, `knowledge`). A whole instance is never the default. - Changes only: records are read by `sys_updated_on`, oldest first, paged by `sysparm_offset`, and only the fields named are asked for (`sysparm_fields`). ## How to connect 1. In ServiceNow, make either an OAuth client (the client-credentials grant, which the instance must allow) or an integration user holding `snc_read_only` and the read roles of the tables you will name. 2. In LightHouse, open **Setup and admin, Connectors**, choose **ServiceNow**, and fill in `objects` (and `cmdb_class` if needed). 3. Paste either the client id and secret, or the user name and password. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`SERVICENOW_CREDENTIAL` by default): `instance_url` (`https://.service-now.com`) and either `client_id` and `client_secret`, or `username` and `password`. ## Permissions - **A read-only integration user** (`snc_read_only` and read roles on the tables named), or **an OAuth client** whose service account is read-only. ServiceNow does not tell a credential its own roles, so read-only is decided by those roles, not by anything the collector can check; the connection check says so. - **What the collector does:** `GET` requests to `/api/now/table/
`, plus, for an OAuth client, one `POST` to `/oauth_token.do` for the access token. Its read-only test proves that on every change. - **One host:** every request goes to your instance and nowhere else. ## Limits - `instance_url` must be `https://.service-now.com`. - The query’s date is read in the user’s own time zone, which the collector cannot see, so the query is widened by a day and anything not newer than the cursor is dropped. A busy instance therefore re-reads up to a day of records on each pull; unchanged ones are not rewritten. - Pages of 1 to 10,000 rows (`page_size`, default 500). - References are read as display names for the few fields asked for; the rest of a record is not read. - Deletions are found by listing `sys_id`s every six hours; a deleted record is removed from the corpus then, not at once. ## Data handling - Incidents and changes name people (callers, assignees) and may hold personal data in their text. Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | | `credential variable 'SERVICENOW_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect ServiceNow again in LightHouse | | `instance_url is https://.service-now.com` | The URL is not a ServiceNow instance address | Use the instance’s own address | | `the servicenow credential has neither an OAuth client nor a user` | Neither pair of fields is complete | Give `client_id` and `client_secret`, or `username` and `password` | | `ServiceNow: no token (...)` | The OAuth client was refused, or the instance could not be reached | Check the client, and that the grant is allowed on the instance | | `cmdb_class is a CMDB table, cmdb_ci or cmdb_ci_` | `cmdb_class` names some other table | Name a CMDB class | | `HTTP 401` or `HTTP 403` | The user lacks a role on a table | Give the user the read role for that table | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Table API (/api/now/table) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/servicenow/ --- # SharePoint and OneDrive > SharePoint and OneDrive: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the document libraries of the SharePoint sites you name, and the OneDrives of the people you name, so agents can answer from the team’s documents. It follows each drive’s delta, so an unchanged file is never fetched again, and what the owner deletes is withdrawn from the knowledge base. ## At a glance | Collector | SharePoint and OneDrive, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Microsoft: SharePoint and OneDrive (Microsoft Graph) ([the vendor's documentation](https://learn.microsoft.com/en-us/graph/api/resources/onedrive)) | | Family | Storage | | Kind | Files | | Ways to connect | OAuth approval, Key pair | | Scopes | - Read: `Sites.Read.All`, `Files.Read.All` | | Read only | Yes, except: \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `graph.microsoft.com`, `login.microsoftonline.com`, `*.sharepoint.com`, `*.atlanticagenticlabs.com` | | Vendor API versions | Microsoft Graph v1.0 (drives, delta) | | Lowest engine version | `0.45.0` | ## What it reads - Files in the sites (`:/sites/`, or a Graph site id) and libraries (by name; every library of the site otherwise), the drives (by id) and the OneDrives (by user principal name) you name. A whole tenant is never the default. - Text, Markdown, CSV, PDF, Word (`.docx`), PowerPoint (`.pptx`) and Excel (`.xlsx`). Each keeps its site, library and path. PDFs go through `pdftotext` (the engine’s folder reader), the Office formats through the engine’s Office reader. - The cursor is each drive’s delta link, kept with the ids written. A file added, changed, moved or deleted is reported by Graph; a deletion is withdrawn. A delta link Graph no longer honours (410, `resyncRequired`) re-reads the drive whole and withdraws what is no longer there. - A drive that leaves the scope (a site or library taken out of the configuration) has its files withdrawn; a site that cannot be seen at the moment (403, 404) keeps them. - Skipped and counted, never fatal: any other format, a file over `max_mb` (50 by default) and a document that will not open. A library always holds an image. ## How to connect 1. Choose how to sign in. **Approve in Microsoft**: a Microsoft Entra administrator consents for the organisation to Atlantic’s Microsoft app, and the deployment asks LightHouse for an hour’s token each time it reads (nothing secret is stored). **Your own app, by certificate**: register an app in your tenant, add the Graph application permissions below, grant admin consent, upload a certificate (RSA, 2048 bits or more) and keep the private key and certificate together in one PEM file. 2. In LightHouse, open **Connectors**, choose **SharePoint and OneDrive**, name the sites, libraries, drives and users, a label and how often to read, and approve or paste the tenant ID, client ID and PEM. Where your deployment keeps credentials in your own store, the PEM is sealed in your browser and LightHouse never sees it. 3. In code, set `SHAREPOINT_CREDENTIAL` (or the variable `credential_env` names) to the credential’s fields as JSON (`tenant_id`, `client_id`, `certificate`; or `{"tenant_id": ..., "app": "atlantic"}` for Atlantic’s app) and add a `kind: sharepoint` source card, or name the connection with `credential_secret`. Both ways produce a one-hour app-only token, and a client secret is never accepted: a certificate cannot be copied from a log or a screenshot the way a password can. ## Permissions Microsoft Graph application permissions, read only: `Sites.Read.All` for site libraries and `Files.Read.All` for OneDrive. The collector sends `GET` requests to `graph.microsoft.com` and to the pre-authenticated download links Graph returns (on `*.sharepoint.com` only, with no Authorization header; any other host is refused and never named in the error). The only other requests are the sign-in POSTs the manifest lists under `read_operations`: the certificate sign-in to `login.microsoftonline.com`, or, with Atlantic’s app, a signed request to LightHouse for a one-hour token. Its read-only test proves it on every change. ## Limits - You must name sites, drives or users; the site form is `.sharepoint.com:/sites/` (or `/teams/`), a user is a principal name. - Files over `max_mb` (50 by default) and unsupported formats are skipped and counted. - The token lasts an hour and is refreshed five minutes early. - PDFs need `pdftotext` in the image; a PDF that will not convert is counted by class, not fatal. - Graph’s delta can expire; the whole drive is then read again, which costs nothing for unchanged files. ## Data handling - Document text is copied into the deployment’s corpus under the source’s `label`. Documents can name people and hold personal data of any kind. - The certificate stays in your secret store (or is never held, with Atlantic’s app); only a one-hour token exists, and it is never written to logs, run notes or the raw cache. A download link’s temporary authorisation is never cached or named in an error. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------ | ----------------------------------------------------------------- | -------------------------------------------- | | `name the sites, drives or users to sync; a whole tenant is never the default` | No scope was named | Name sites, drives or users | | `not SharePoint sites` | A site is not `.sharepoint.com:/sites/` or a Graph id | Correct the site | | `not user principal names` | A OneDrive user is not an address | Use the account’s principal name | | `credential variable 'SHAREPOINT_CREDENTIAL' is not set` | The credential variable is empty | Set it to the credential’s JSON fields | | `has no tenant_id` | The credential JSON lacks the directory’s id | Add `tenant_id`, a GUID | | `Microsoft refused the app's credential` | The app, certificate or consent is wrong or revoked | Check the app registration and admin consent | | `a download link that is not SharePoint's was refused` | A download link pointed at another host | Report it; nothing was fetched | | Read succeeded, 0 written | No file changed since the delta link | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Microsoft Graph v1.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sharepoint/ --- # SITA BagJourney > SITA BagJourney: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the bags of the flights you name, with their loading status, from SITA’s BagJourney API, read-only, inside your deployment. ## At a glance | Collector | SITA BagJourney, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------- | | Reads | SITA: SITA BagJourney API ([the vendor's documentation](https://www.developer.aero/)) | | Family | Aviation | | Kind | Baggage | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Travel, Identity | | Hosts it may contact | `bagjourney.sita.aero`, `{host}` | | Vendor API versions | BagJourney API (bagsforflight v1.0) | | Lowest engine version | `0.46.0` | ## What it reads - For each flight you name (airport, direction `A` or `D`, airline, number) and each date from `days_back` (0 to 7, default 1) to today: the flight’s bags (`GET /bagsforflight/v1.0/...`). - One record per bag tag and date, with the flight, airport, loading status and rush indicator. - BagJourney has no read without a flight, so you must name flights. ## How to connect 1. Make an application at developer.aero and request access to BagJourney. 2. In LightHouse, open **Setup and admin, Connectors**, choose **SITA BagJourney**, and leave the access level at **Read**. 3. Name the `flights`, for example `{airport: DUB, direction: D, airline: XX, number: "101"}`. To leave passenger names out, set `exclude_fields` to `["**.passenger_first_name", "**.passenger_last_name"]`. 4. Paste the API key. Your browser seals it to your deployment, which hands it to the collector as `SITA_BAGS_API_KEY`. Because there is no read without a flight, your deployment checks the key at the first sync. ## Permissions - `GET` only, with the key in the `api_key` header. The API also documents a `POST` that creates a delayed bag report; nothing here calls it. - Your deployment refuses to store this credential at read and write. Only `bagjourney.sita.aero` is contacted. ## Limits - No paging or changed-since is documented: the named flights are read for each date in the window on every run. - A bag with no bag tag is skipped. - The default pace is one request a second (`delay_s`); `429` and `5xx` are retried with backoff and `Retry-After`. ## Data handling - A bag record is personal data: the passenger’s name, PNR and seat. It is read and indexed in your deployment only; LightHouse receives ids, hashes and counts, never a bag or a passenger. - Nothing is cached raw, and a failure names the host and the status, never the URL (which carries the flight). - Travel document numbers, dates of birth and health or disability special service requests are left out by default. Passenger names are not, unless you add them to `exclude_fields`; `keep_fields` takes a default back by its exact name. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------- | ----------------------------------------- | ----------------------------------- | | `credential variable 'SITA_BAGS_API_KEY' is not set` | The deployment has not been given the key | Connect the credential again | | `GET bagjourney.sita.aero: HTTP 401` | SITA refused the key | Check it is approved for BagJourney | | \`a flight is {airport, direction: A | D, airline, number}\` | A flight is malformed | | `name the flights whose bags to read` | No flights were named | Name at least one | | `days_back is 0 to 7` | A longer look-back | Use 7 or fewer | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | BagJourney API (bagsforflight v1.0) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sita-bags/ --- # SITA Flight Status > SITA Flight Status: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads flight status at the airports you name from SITA’s Flight Status API (FLIFO), kept current from SITA’s change feed, read-only, inside your deployment. ## At a glance | Collector | SITA Flight Status, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------ | | Reads | SITA: SITA Flight Status API (FLIFO) ([the vendor's documentation](https://www.developer.aero/)) | | Family | Aviation | | Kind | Flights | | Ways to connect | Access token, OAuth approval | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `sitaopen.api.aero`, `{host}` | | Vendor API versions | Flight Status API (flightinfo v2) | | Lowest engine version | `0.46.0` | ## What it reads - **First run:** each airport’s departures and arrivals for the day (`GET /flightinfo/v2/flights/airport/{airport}/direction/{D|A}`), optionally one airline’s only. - **Every run after:** only what changed, from the previous run’s end to a minute ago (`GET /flightinfo/v2/flights/updates/airport/{airport}[/airline/{airline}]` with `from` and `to`), in windows of at most `window_minutes` (1 to 240, default 60). - One record per flight, keyed by SITA’s `flightId`, with its route and status text. ## How to connect 1. Make an application at developer.aero and request access to the Flight Status API (SITA approves each API; some are charged). 2. In LightHouse, open **Setup and admin, Connectors**, choose **SITA Flight Status**, and leave the access level at **Read**. 3. Name the `airports` (IATA codes) and, optionally, one `airline`. 4. Paste the API key. For OAuth, add the client id and secret on a second and third line and set `oauth: true`. Your browser seals them to your deployment, which hands them to the collector as `SITA_API_KEY`, or `SITA_CLIENT_ID` and `SITA_CLIENT_SECRET`. ## Permissions - `GET` only. The API key goes in `x-apikey`; with OAuth the one `POST` is the token request to `/flifo/oauth/token`, listed in the manifest’s `read_operations`. - A token whose granted scope names a write is refused before it is used; the credential check says so. - Your deployment refuses to store this credential at read and write. Only `sitaopen.api.aero` is contacted. ## Limits - Rate limits are SITA’s, stated in `X-RateLimit-*` headers; once exceeded, `retry-after` is an epoch time. The backoff reads both (capped at two minutes). - A flight is rewritten only when its content changes. - The default pace is one request a second (`delay_s`). - The first run reads the day only; the change feed carries the rest. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a flight record. - Flight status carries no passenger data. The standard exclusions still apply to every record before it is written; `exclude_fields` adds paths and `keep_fields` takes a default back by its exact name. - Nothing is cached raw, and a failure names the host and the status, never the URL. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------ | ----------------------------------------------- | --------------------------------------------------- | | `credential variable 'SITA_API_KEY' is not set` | The deployment has not been given the key | Connect the credential again | | `GET sitaopen.api.aero: HTTP 401` | SITA refused the key or token | Check the key is approved for the Flight Status API | | `GET sitaopen.api.aero: HTTP 429` | SITA’s rate limit, after the retries | Read less often, or name fewer airports | | `the credential grants writes; this release reads only: ...` | An OAuth token’s scope names a write | Ask SITA for a read-only client | | `airports are IATA airport codes, at least one` | No airport, or a code that is not three letters | Name airports as IATA codes | | `airline is a two-character IATA airline code` | Any other airline value | Use the two-character code | | `window_minutes is 1 to 240` | A window outside the range | Choose between 1 and 240 | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | --------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | Flight Status API (flightinfo v2) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/sita-flights/ --- # Slack > Slack: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the public Slack channels that the LightHouse app has been added to, a thread at a time, so agents can answer from what the team has already said. A person adding the app to a channel is the decision to let the agents read it. ## At a glance | Collector | Slack, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------- | | Reads | Slack: Slack Web API ([the vendor's documentation](https://api.slack.com/web)) | | Family | Communication | | Kind | Chat | | Ways to connect | Access token, OAuth approval | | Scopes | - Read: `channels:read`, `channels:history`, `users:read`, `team:read` | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `slack.com` | | Vendor API versions | Slack Web API (auth.test, conversations.list, conversations.history, conversations.replies) | | Lowest engine version | `0.45.0` | ## What it reads - Public channels the app is a member of (by name with `channels`, or every such channel). Private channels, direct messages and group messages are never read; the scopes asked for cannot reach them. - A thread is one record: the first message and its replies, in order, with the channel and who wrote it. Slack’s mentions and links are turned into readable text. - Each pull reads the last `recent_days` (seven by default) of every channel, which catches new messages and replies to recent threads. Every `reconcile_hours` (six by default) the whole `history_days` window (365 by default) is listed and held to what the cursor knows: a thread that has gone is withdrawn, one whose replies changed is read again, and one older than the window leaves the corpus. - A channel the app has left, that was archived, or that you take out of `channels` has its threads withdrawn. - Never read: files, joins and other channel events. ## How to connect 1. A workspace administrator installs the LightHouse Slack app (or your own app, which can be the one Octy answers in) with the bot scopes below. The bot token begins `xoxb-`. 2. A person adds the app to each public channel to be read. 3. In LightHouse, open **Connectors**, choose **Slack**, name the channels (optional), the label and how often to read, and approve the install or paste the bot token. 4. In code, give the deployment the bot token as `SLACK_TOKEN` from your secret store and add a `kind: slack` source card with `label`, optional `channels`, `history_days` and `requires`. ## Permissions Bot scopes `channels:read` (which public channels the app is in), `channels:history` (their messages and threads), `users:read` and `team:read`. The collector sends only `GET` requests to `slack.com`: `auth.test`, `conversations.list` (public channels only), `conversations.history` and `conversations.replies`. It never posts. Its read-only test proves it on every change. ## Limits - `history_days` is 1 to 3650 and `recent_days` 1 to `history_days`; channel names are lower-case letters, digits, `_` and `-`. - A channel the app is not a member of is not read. - A thread older than the window leaves the corpus. - Slack’s `ok: false` answers are reported by code only (for example `not_in_channel`, `missing_scope`). - Requests are paced and back off when Slack asks (`Retry-After`). ## Data handling - Message text is copied into the deployment’s corpus under the source’s `label`, with the sender’s display name. Chat names people and holds personal data of any kind. - The bot token stays in your secret store and is never written to logs or run notes; the error reports Slack’s error code, never a body. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------- | | `not Slack channel names` | A channel is not written as a lower-case Slack name | Use the channel’s name without `#` | | `history_days is 1 to 3650, and recent_days 1 to history_days` | A window is out of range | Correct the numbers | | `credential variable 'SLACK_TOKEN' is not set` | The bot token variable is empty | Set it to the bot token | | `Slack refused: invalid_auth` | The token is wrong or revoked | Reinstall the app and use its new bot token | | `Slack refused: missing_scope` | The app lacks `channels:read` or `channels:history` | Add the scope and reinstall | | `Slack refused: not_in_channel` | The app is not in the channel | Add the app to the channel | | Read succeeded, 0 written | Nothing new in the recent window | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Slack Web API | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/slack/ --- # Stripe > Stripe: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Stripe account’s balance and its balance transactions, so finance and support agents can reconcile payouts, fees and refunds against the books. It is read-only, and it refuses a secret key. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Stripe, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Reads | Stripe: Stripe API (balance, balance transactions) ([the vendor's documentation](https://docs.stripe.com/api/balance)) | | Family | Finance | | Kind | Payments | | Ways to connect | Access token | | Scopes | - Read: `Balance Read` | | Read only | Yes | | Vendor's API can move money | Yes | | Personal data | Financial | | Hosts it may contact | `api.stripe.com`, `{host}` | | Vendor API versions | Stripe API v1 | | Lowest engine version | `0.46.0` | ## What it reads - **The balance:** the available and pending amounts, one record per currency, rewritten only when it changes and removed when the currency disappears. - **Balance transactions:** amount, fee and net, with type, reporting category, status, source and the date the funds become available. - Balance transactions are read from the last `created` time, 100 a page, following `starting_after`. The first read goes back `history_days` (default 90, at most 3,650). - Amounts are integers in the currency’s minor unit and are scaled exactly by the currency’s exponent: zero-decimal (such as JPY), two-decimal, and three-decimal (BHD, JOD, KWD, OMR, TND) currencies as Stripe lists them. It does not read customers, charges, payment methods or payouts’ bank details. ## How to connect 1. In Stripe, make a **restricted key** (`rk_live_` or `rk_test_`) with **Read** on **Balance** and nothing else, restricted to your deployment’s egress addresses. 2. In LightHouse, open **Setup and admin, Connectors** and choose **Stripe**. 3. Paste the key and confirm it is read-only. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_STRIPE` by default): `api_key` and `view_only_confirmed` (`yes`). ## Permissions This collector is **read-only**: it sends `GET` requests only (`/v1/balance` and `/v1/balance_transactions`), and its read-only test proves it on every change. - **Refused by the code:** a key that begins `sk_` (a secret key, live or test), by its prefix, before it is used and before any request is made. A secret key can do anything the account can. The error is `Stripe: refused: the credential can do anything the account can (a secret key; use a restricted key); make a view-only one`. - **Not detectable by the code:** Stripe does not state a restricted key’s permissions to it. Any key that does not begin `sk_` passes the prefix check, including a restricted key that has write permissions. The collector reads only once you have confirmed the key has Read on Balance only (`view_only_confirmed`); without it the error is `Stripe does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read`. Make the key read-only in Stripe: that, not this code, is what stops a restricted key from writing. - **Hosts:** only `api.stripe.com`, over https; redirects are never followed. ## Limits - Stripe API v1. - Requests are paced (0.05 s apart) and retried on 429 and 5xx with back-off. - The `source` of a balance transaction is Stripe’s id for what caused the movement; the collector does not look it up. - Amounts are exact decimals; a number that arrives as a float is refused. ## Data handling - Records hold financial data: balances and balance-transaction amounts. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------- | | `Stripe: refused: the credential can do anything the account can (a secret key; use a restricted key); make a view-only one` | The key is a secret key (`sk_`) | Make a restricted key with Read on Balance only | | `Stripe does not state this key's permissions; confirm the key is view-only (view_only_confirmed) before it is read` | You have not confirmed the key is read-only | Confirm it, after checking the key in Stripe | | `Stripe answered HTTP 401` | The key is wrong or revoked | Make a new restricted key | | `Stripe answered HTTP 403` | The key lacks Read on Balance | Add Read on Balance | | `Stripe answered HTTP 429` | Rate limit | Nothing; the collector backs off and continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Stripe API v1 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/stripe/ --- # Microsoft Teams > Microsoft Teams: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the channel messages of the Microsoft Teams teams you name, a thread at a time, so agents can answer from what the team has already said. A thread is the first message and its replies, in order, as one document. ## At a glance | Collector | Microsoft Teams, version `1.0.0` | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Microsoft: Microsoft Teams (Microsoft Graph) ([the vendor's documentation](https://learn.microsoft.com/en-us/graph/api/resources/teams-api-overview)) | | Family | Communication | | Kind | Chat | | Ways to connect | OAuth approval, Key pair | | Scopes | - Read: `ChannelMessage.Read.All`, `Channel.ReadBasic.All`, `Team.ReadBasic.All` | | Read only | Yes, except: \[object Object]; \[object Object] | | Vendor's API can move money | No | | Personal data | Content, Identity | | Hosts it may contact | `graph.microsoft.com`, `login.microsoftonline.com`, `teams.microsoft.com`, `*.atlanticagenticlabs.com` | | Vendor API versions | Microsoft Graph v1.0 (teams, channels, messages delta) | | Lowest engine version | `0.45.0` | ## What it reads - The channels (by name; every channel otherwise) of the teams you name (by team id). A whole tenant is never the default. - A thread is one record: the first message and its replies, with the team, channel, sender and reply count. A reply is never indexed without its question. - The cursor is each channel’s delta link, kept with the threads written. A new or edited message, or a reply that moves the first message’s modified time, brings the thread back; a message deleted in Teams is withdrawn. A channel taken out of the configuration has its threads withdrawn; a team that cannot be seen at the moment keeps them. A delta link Graph no longer honours (410) re-reads the channel. - Never read: chats, meeting chats, files shared in channels (connect SharePoint for those) and system messages. ## How to connect 1. Choose how to sign in, as for SharePoint: **Approve in Microsoft** (a Microsoft Entra administrator consents to Atlantic’s Microsoft app; an hour’s token is minted for your tenant each time) or **your own app, by certificate** (an app registration in your tenant with a certificate credential, never a client secret). 2. Channel messages are a Microsoft *protected API*: an app reads them only once Microsoft has approved it for that use. Atlantic’s app goes through that approval; for your own app, request it from Microsoft before you connect. 3. In LightHouse, open **Connectors**, choose **Microsoft Teams**, name the team ids, optionally the channels, a label and how often to read, and approve or paste the tenant ID, client ID and PEM. 4. In code, set the credential’s JSON fields in `SHAREPOINT_CREDENTIAL` (or the variable `credential_env` names) and add a `kind: teams` source card with `teams`, `channels`, `label` and `requires`. Both ways produce a one-hour app-only token, and a client secret is never accepted: a certificate cannot be copied from a log or a screenshot the way a password can. ## Permissions Microsoft Graph application permissions: `ChannelMessage.Read.All`, `Channel.ReadBasic.All` and `Team.ReadBasic.All`. LightHouse offers no write access for Teams. The collector sends `GET` requests to `graph.microsoft.com`; the only other requests are the sign-in POSTs the manifest lists under `read_operations` (the certificate sign-in to `login.microsoftonline.com`, or a signed request to LightHouse for a one-hour token with Atlantic’s app). Its read-only test proves it on every change. ## Limits - You must name teams, by their id (a GUID); a team name is refused. - Chats and meeting chats are not read. - A thread is read again whole when it changes. - Channel messages need Microsoft’s protected-API approval for the app. - The token lasts an hour and is refreshed five minutes early. ## Data handling - Message text is copied into the deployment’s corpus under the source’s `label`, with the sender’s display name. Messages name people and hold personal data of any kind. - The certificate stays in your secret store (or is never held, with Atlantic’s app); only a one-hour token exists, and it is never written to logs or run notes. - Nothing leaves the deployment: only counts reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------ | | `name the teams to sync; a whole tenant is never the default` | `teams` is empty | Name the team ids | | `not team ids` | A team was named by name, not by id | Use the team’s id (a GUID) | | `credential variable 'SHAREPOINT_CREDENTIAL' is not set` | The credential variable is empty | Set it to the credential’s JSON fields | | `Microsoft refused the app's credential` | The app, certificate or consent is wrong or revoked | Check the app registration and admin consent | | `HTTP 403` on channel messages | The app has not been approved for Microsoft’s protected API, or lacks `ChannelMessage.Read.All` | Request the approval; grant the permission and consent | | Read succeeded, 0 written | No message changed since the delta link | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Microsoft Graph v1.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/teams/ --- # Training exports > Training exports: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads training records exported by your learning management system, row by row, from a bucket prefix or a drop folder your deployment mounts, read-only. ## At a glance | Collector | Training exports, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | Reads | Any learning management system: LMS training-record exports ([the vendor's documentation](https://www.imsglobal.org/)) | | Family | Aviation | | Kind | Training | | Ways to connect | None (no credential), Service account | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | CSV and JSON exports (no vendor API) | | Lowest engine version | `0.46.0` | ## What it reads - Every `.csv` file (and `.json` list of objects) under the prefix you name: each row is one record, keyed by `id_columns` and titled by `title_columns`. - An LMS exports completions as files; this collector reads those files and never connects to the LMS. For xAPI learning record stores see the `xapi` collector. ## How to connect 1. Make the export write to a bucket prefix, or to an SFTP server whose landing directory the deployment mounts. 2. Your engineer sets this source up in the source card (there is no key to paste): `store` (`s3://bucket/prefix/`, `gs://`, `azblob://` or `file:/path`), `id_columns` (what identifies a row), `title_columns` (the fields joined for the title), and for S3 a `role_arn` (and `external_id`, `region`). 3. Give the role read access to that prefix only. In LightHouse the card reads **Read**. ## Permissions - No credential is stored. The deployment’s identity, or the role it assumes, is the permission; grant list and get on the one prefix and nothing else. - The collector only lists and reads objects (and, for a `file:` store, reads files). It never writes, moves or deletes an export. Its read-only test uses a stub S3 client that records every operation and fails on any but list and get, and checks that a drop folder is byte-for-byte unchanged afterwards; there is no HTTP to record. - Nothing here connects to the system that produced the export, so nothing here could change it. ## Limits - Only files ending `.csv` or `.json` (a list of objects) are read; others are ignored. - A file is read again only when its ETag changes. Files larger than `max_mb` (50 by default) are skipped and counted. - Column names are the export’s own and none is assumed: set `id_columns` (otherwise a row’s hash is its id, so an edited row becomes a new record and the old one is withdrawn) and `title_columns`. - Rows that leave a file, and files that are removed, become withdrawals. - Google Cloud Storage and Azure Blob stores are read through the engine’s adapters, which need their own identity libraries in the deployment. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a row. - Training exports name the trainee. Leave the name out (`exclude_fields`) where records are read for trends rather than people. - Contact fields and reporter names are left out by default, as are travel document numbers and dates of birth. `exclude_fields` adds columns (for example `**.Captain`); `keep_fields` takes a default back by its exact name. Nothing is cached raw. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------- | --------------------------------------------------------- | ------------------------------------ | | `a source needs its label` | No label was given | Give the source a label | | `the store's prefix is a plain path` | The prefix holds characters a path cannot | Use a plain prefix | | Read succeeded, nothing written | No file’s ETag has changed since the last read | Nothing to do | | Fewer rows than expected | A file over `max_mb` was skipped (the source counts them) | Raise `max_mb`, or split the export | | A title of the form `: #` | `title_columns` is not set, or its columns were empty | Name the columns for the title | | Rows reappear as new records | `id_columns` is not set, so ids are row hashes | Name the columns that identify a row | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | -------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | CSV and JSON exports | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/training-csv/ --- # TRAX > TRAX: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. TRAX is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from TRAX’s eMRO web services specification from its integration team (work orders, task cards, defects and components, read-only). TRAX links its maintenance web services through its integration team; no reference is public. ## At a glance | Collector | TRAX, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------- | | Reads | TRAX: TRAX eMRO web services ([the vendor's documentation](https://www.trax.aero/services/)) | | Family | Aviation | | Kind | Maintenance | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: TRAX maintenance records read in place. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need TRAX’s eMRO web services specification from its integration team (work orders, task cards, defects and components, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: trax label: internal api: spec_ref: "TRAX eMRO web services specification, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Maintenance} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers and dates of birth, and health or disability special service requests. Contact details are not left out by default for a maintenance system, whose records name engineers and sign-offs; add the fields that hold them to `exclude_fields`. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``TRAX: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/trax/ --- # LightHouse uploads > LightHouse uploads: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the files people uploaded through LightHouse, from the uploads store of the deployment itself. The files go straight from the person’s browser or the command line to the store; LightHouse never sees their content. This collector then indexes them, for a knowledge base with no system behind it. ## At a glance | Collector | LightHouse uploads, version `1.0.0` | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Atlantic Agentic Labs: LightHouse uploads (the deployment's uploads store) ([the vendor's documentation](https://docs.atlanticagenticlabs.com/connect/upload/)) | | Family | Storage | | Kind | Files | | Ways to connect | Service account | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Content | | Hosts it may contact | `*.amazonaws.com`, `storage.googleapis.com`, `oauth2.googleapis.com`, `{account}.blob.core.windows.net`, `login.microsoftonline.com` | | Vendor API versions | Amazon S3 ListObjectsV2 and GetObject, Google Cloud Storage JSON API v1, Azure Blob service REST API 2023-11-03, local directory (file:) | | Lowest engine version | `0.45.0` | ## What it reads - Every readable object under the uploads store’s prefix: `.md`, `.markdown`, `.txt`, `.csv`, `.vtt`, `.json`, `.pdf`, `.docx`, `.pptx` and `.xlsx`. - The store is the one in `AAL_UPLOADS`: `s3://bucket/prefix`, `gs://bucket/prefix`, `azblob://account/container/prefix`, or `file:/path` on premises. - The change test is each object’s ETag. An object deleted from the store becomes a tombstone. - Names starting with `.` and keys ending in `/` are ignored. ## How to connect 1. Set `AAL_UPLOADS` in the deployment to the store the deployment mints upload links for. 2. Switch on `upload.prepare` in LightHouse’s command settings and in the deployment’s command policy; it is off until both say so. 3. Add an `uploads` source card with a `label` and the `requires` block. Optionally set `max_mb` (the largest file read, 100 by default). The deployment’s own identity reads the store (an instance role on AWS, the service account on Google Cloud, a managed identity on Azure). No credential is given to LightHouse. ## Permissions List and read on the one bucket, container or directory, and nothing else. The collector lists keys and gets objects; it never writes, overwrites or deletes in the store. (Writing is done by the person’s browser with a link of at most fifteen minutes, minted by the deployment, outside this collector.) Its read-only test replaces the store client with a recorder and checks every operation is a list, a get or the creation of a read link. ## Limits - Objects over `max_mb` (100 by default) are skipped and counted as `too-large`; formats the collector cannot read are counted as `format`; a corrupt document is counted as `unreadable`. - Skipped files are counted, not fatal, and logged by count only. - A file is indexed at the first scheduler tick after its upload link expires, within about half an hour. ## Data handling - The files stay in your own store; the corpus written from them stays in the deployment. LightHouse relays an upload link and nothing else. - Each record carries a link back to the object where the store gives one. - Uploaded documents may hold personal data of any kind; they are handled under the source’s `label`. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------------- | | `the uploads source needs AAL_UPLOADS, the deployment's uploads store` | The environment variable is not set | Set `AAL_UPLOADS` to the deployment’s uploads store | | `an object store is s3://bucket/prefix, gs://bucket/prefix, azblob://account/container/prefix or file:/path` | `AAL_UPLOADS` is not one of the accepted forms | Correct the address | | `that key is outside the uploads directory` | A key tried to leave the uploads directory | Check the store; keys are made by the deployment, not by file names | | Read succeeded, 0 written | No object changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.45.0` | Amazon S3; Google Cloud Storage JSON API v1; Azure Blob service REST API 2023-11-03; local directory | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/uploads/ --- # Web Manuals > Web Manuals: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. Web Manuals is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from Web Manuals’ API or integration specification (manuals, their revisions and revision status, read-only). There is no public API reference. ## At a glance | Collector | Web Manuals, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | Reads | Web Manuals International: Web Manuals document management system ([the vendor's documentation](https://webmanuals.aero/)) | | Family | Aviation | | Kind | Documents | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: operations manuals and their revisions read in place, by revision. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need Web Manuals’ API or integration specification (manuals, their revisions and revision status, read-only), a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: webmanuals label: internal api: spec_ref: "Web Manuals API / integration specification, version, as issued by the vendor" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Documents and manuals} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details, as well as travel document numbers and dates of birth. `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``Web Manuals International: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/webmanuals/ --- # Workday > Workday: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 0.1.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads the structure of an organisation from Workday: organisations, job profiles, locations, job requisitions, and reports you name. Each record becomes one document in the knowledge base. It reads; it never writes, and it does not read workers, compensation or payroll. Status: **Built, not certified** (needs a Workday implementation tenant). ## At a glance | Collector | Workday, version `0.1.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Workday: Workday REST API and Reports-as-a-Service ([the vendor's documentation](https://community.workday.com/sites/default/files/file-hosting/restapi/index.html)) | | Family | ERP | | Kind | Hr | | Ways to connect | OAuth approval | | Scopes | - Read: `Organizations and Roles`, `Jobs and Positions`, `Recruiting`, `Reports as a Service (named reports)` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | None | | Hosts it may contact | `*.workday.com`, `*.myworkday.com` | | Vendor API versions | REST v1, RaaS (customreport2) | | Lowest engine version | `0.47.0` | ## What it reads | Object | Source | | ------------------ | ------------------------------------------------------------------------------ | | `organisations` | supervisory organisations and cost centres (REST) | | `job_profiles` | job profiles (REST) | | `locations` | locations (REST) | | `job_requisitions` | job requisitions (REST) | | `reports` | named Reports-as-a-Service reports, as `owner/report`, that you write and name | You choose which to read; a whole tenant is never the default, and a report is read only if you name it. **What it never reads.** Workers, compensation and payroll: no object reads them. A report is written by you, so before anything is stored the collector drops every column whose name matches the personal-data deny-list (compensation, salary, pay, bonus, national id, tax id, passport, bank, IBAN, account number, date of birth, home address, personal email and phone, ethnicity, gender, marital status, disability, medical, health, religion, visa, benefits, and any reference to a worker, manager or recruiter) and counts them in the record’s metadata (`dropped_columns`: the count, never a value). The same guard applies to every field of every object. Build your reports without those columns anyway; the guard is a last line. ## How to connect 1. In Workday, register an **API Client for Integrations** with a refresh token, and give its integration system user **read** on the functional areas for the objects above (Organizations and Roles, Jobs and Positions, Recruiting) and on any report you name. Nothing that writes. 2. In LightHouse, open **Connectors** and choose **Workday**. 3. Enter the host (for example `wd2-impl-services1.workday.com`, no `https://`), the tenant name, the client id, client secret and refresh token. 4. Choose a label, the objects to read, the reports (as `owner/report`), and how often. The secrets are sealed in your deployment and never shown again. ## Permissions Read on the named functional areas and reports. The collector sends only `GET` requests; the one `POST` is the OAuth token request. Its read-only test proves it on every change. This release takes read-only credentials only. ## Limits - The host must be a `*.workday.com` or `*.myworkday.com` host, and it is the only host contacted. A redirect is never followed. - REST resources and reports have no change feed the collector relies on, so each is read in full and only what changed is rewritten. Large reports should be filtered in Workday. - A report row with no id-like column is keyed by its content, so an edited row is a new record and the old one is removed at the next listing. - Deletions are found by listing every six hours. - REST paths follow Workday’s published API descriptions (version 1 under `/ccx/api/v1/{tenant}/`); a resource a tenant does not expose is refused and the read fails with `scope_missing`. - Requests are paced and back off when Workday asks. ## Data handling - No personal data is read by default (see “What it reads”). Dropped report columns are counted, never stored. - The responses are not cached; only the records written are kept, in your deployment. - Nothing leaves your deployment: the collector runs inside it, and only the counts of items read reach LightHouse. ## Troubleshooting | What you see | What it means | What to do | | ------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- | | `auth_failed` | The API Client or refresh token was refused (invalid client or grant) | Check the client; issue a new refresh token if it was revoked | | `scope_missing` | The integration user may not read the resource or report (403) | Grant the functional area, or share the report with the user | | `unreachable` | Workday did not answer, or answered with an error | Check the host and tenant | | `HostNotAllowed` | A request went to a host that is not your sealed host | Correct the credential | | Read succeeded, 0 written | Nothing changed since the last read | Nothing to do | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ----------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `0.1.0` | `0.47.0` | REST v1; RaaS (customreport2) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/workday/ --- # SITA WorldTracer > SITA WorldTracer: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Needs onboarding Needs a partner agreement with the vendor, or a client's environment, before it can be built or certified. SITA WorldTracer is **built and waiting for onboarding**. Its reference is not public, so the collector is complete (sign-in, read-only reading, four paging styles, changed-since) but refuses to run until our certified forward-deployed engineers map it from SITA’s WorldTracer web services reference (delayed, damaged and pilfered bag file reads and on-hand reads), issued under the WorldTracer agreement. WorldTracer is not in SITA’s public catalogue; SITA offers its web services to customers under agreement. A file names a passenger, so it is personal data, read and indexed in your deployment only. ## At a glance | Collector | SITA WorldTracer, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------ | | Reads | SITA: SITA WorldTracer web services ([the vendor's documentation](https://www.sita.aero/)) | | Family | Aviation | | Kind | Baggage | | Ways to connect | OAuth approval, Access token | | Scopes | - Read: | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Travel, Identity, Contact | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | the licensed reference named in the source's api.spec_ref | | Lowest engine version | `0.46.0` | ## What it reads - Once onboarded: the airline’s WorldTracer files read in place: file status, bag descriptions and tracing history, with passenger contacts left out on request. - Only the lists the mapping names, each as a *collection*: a path, the field that is the record’s id, the list’s key in the response, the fields joined for the title, the change-time field, and how the API pages (`none`, `next_link`, `offset`, `cursor` or `page`). - Each item becomes one record, keyed `/`. Items with no id are skipped. - Before onboarding it reads nothing: the source fails at once with a message naming the reference it needs and what onboarding unlocks. ## How to connect 1. Ask us to onboard it. We need SITA’s WorldTracer web services reference (delayed, damaged and pilfered bag file reads and on-hand reads), issued under the WorldTracer agreement, a credential that can only read, and the host it is served on. 2. We write the `api` block from that reference. The block names the reference (`spec_ref`), the https `base_url`, one sign-in (`api_key_header`, or `token_url` for OAuth client credentials) and the collections. Example, with invented values: ```yaml source: kind: worldtracer label: internal api: spec_ref: "SITA WorldTracer web services reference, release and section, as licensed" base_url: https://api.example-operator.aero/v1 # the client's own host api_key_header: X-Api-Key # or token_url: https://login.example-operator.aero/token collections: - {path: /items, items: data, id: id, title: [number, title], updated: modified, since_param: modifiedSince, paging: offset, page_param: offset, size_param: limit, size: 200, kind: Baggage} ``` 3. The credential reaches the collector as environment variables named in the source (`api_key_env`, or `client_id_env` and `client_secret_env`); your deployment fills them from its own secrets store, so neither the credential nor the records pass through LightHouse. 4. In LightHouse the card reads **Needs onboarding** until the mapping is in; connect it as **Read**. ## Permissions - `GET` only. The one `POST` is the OAuth token request to the `token_url` you name, listed in the manifest’s `read_operations`; an API-key source sends no `POST`. - A token whose granted scope names a write (create, update, delete, cancel, book, issue, ticket, check-in, manage, admin, `*`) is refused before it is used, and the credential check says so. - Your deployment refuses to store this credential at read and write, whatever its policy allows. - Give the vendor a credential that can only read; this collector does not depend on that, but the vendor’s audit trail will. ## Limits - Inert without `api`; the mapping is checked before anything runs (`api.spec_ref`, an https `base_url`, one sign-in, at least one collection, an absolute path and id for each). - Changed-since reading exists only where the reference gives a `since_param`; without one every run reads the whole list again. - A list is read up to `max_pages` pages (500 by default); a listing that does not end fails rather than loops. - Requests are paced (`delay_s`, one second by default); `429` and `5xx` are retried with backoff and `Retry-After`. - It is built from the engine’s generic adapter. Nothing about the vendor’s payload is assumed until the licensed reference is in hand. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a record. - Nothing is cached raw, and a failure names the host, never the URL (a URL can carry a record locator). - By default these are left out of every record: travel document numbers, dates of birth and health or disability special service requests (MEDA, WCHR, BLND and the rest of the IATA health set). `exclude_fields` adds paths; `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. - The spec reference is stored on each record’s metadata (`spec_ref`), so a question can be traced to the document the mapping came from. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------------------------------- | | ``SITA: needs onboarding. Supply `api` from ...`` | No `api` block yet | Ask us to onboard it | | `unknown api keys: [...]` | The `api` block has a key the adapter does not know | Use only `spec_ref`, `base_url`, `token_url`, `scope`, `api_key_header`, `collections` | | `api.spec_ref names the licensed reference the mapping is from` | No reference is named | Name the reference and its release | | `api names one of token_url (OAuth client credentials) or api_key_header` | Both or neither sign-in is given | Give exactly one | | `credential variable 'X' is not set` | The deployment has not filled the variable the source names | Set it from your secrets store | | `the credential grants writes; this release reads only: ...` | The token’s scope names a write | Issue a credential limited to reading | | `GET host: HTTP 401` | The vendor refused the credential | Check it has not expired or been revoked | | `more than N pages; raise max_pages` | The listing did not end | Check the paging fields in the mapping | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------------------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | the licensed reference named at onboarding (api.spec_ref); none is public | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/worldtracer/ --- # xAPI learning records > xAPI learning records: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. ![](/_astro/adl.XRNMaUb9.png)Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads training statements from any xAPI Learning Record Store, read-only, inside your deployment, with learners’ contacts left out. ## At a glance | Collector | xAPI learning records, version `1.0.0` | | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | Reads | ADL Initiative / IEEE: xAPI (Experience API) Learning Record Store ([the vendor's documentation](https://github.com/adlnet/xAPI-Spec)) | | Family | Aviation | | Kind | Training | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Identity, Contact, Employment | | Hosts it may contact | Only the hosts on your deployment's allow-list (`*`: the host is the one you give it) | | Vendor API versions | xAPI 1.0.3, xAPI 2.0.0 (IEEE 9274.1.1) | | Lowest engine version | `0.46.0` | ## What it reads - Statements stored since the last run (`GET {endpoint}/statements` with `since`, `ascending` and `limit`, 1 to 10000, default 500), following the `more` link until it is empty. - Optionally only the verbs you list (`verbs`, one query each). - One record per statement, keyed by its id, titled with its verb and activity, with the verb, activity and result success in its metadata. - A statement that voids another arrives as a new statement; the voided one is then withdrawn. ## How to connect 1. In your LRS, make a client (a key and secret) with read-only access to statements. 2. In LightHouse, open **Setup and admin, Connectors**, choose **xAPI learning records**, and leave the access level at **Read**. 3. Name `endpoint` (the LRS’s https xAPI endpoint), `version` (`1.0.3` or `2.0.0`) and, optionally, `verbs`. 4. Paste the key and then the secret. Your browser seals them to your deployment, which hands them to the collector as `XAPI_KEY` and `XAPI_SECRET`. ## Permissions - `GET` only, with HTTP Basic and `X-Experience-API-Version`. The statements API is also writable on most LRSs; this collector never sends `PUT`, `POST` or `DELETE`. - The LRS’s rights for the client are the permission: give it read-only access. - Your deployment refuses to store this credential at read and write. ## Limits - Incremental: the cursor is the newest `stored` time seen. - Rate limits are the LRS’s own; `429` is retried with `Retry-After`. The default pace is two requests a second (`delay_s` 0.5). - More than `max_pages` (1000) pages fails the run; a `more` link to another host is refused. - Statements are immutable, so a changed statement never reappears. ## Data handling - Records are read and indexed inside your deployment. LightHouse receives ids, hashes and counts, never a learner or a statement. - Reporters are protected by default: reporters’ names, who submitted or created a record, and everyone’s email, phone and contact details are left out of every record before it is written, as are travel document numbers and dates of birth. Just culture and data protection both need a reporter kept from anyone who does not need them. Names are matched whatever the case, spacing, `_` or `-`, so `reporterName` also catches an export’s `Reporter Name`. - `exclude_fields` adds paths (for example `**.contact`); `keep_fields` takes a default back by its exact name, and that choice is your record of the decision. Free-text narratives are indexed as written and may still name people: add the fields that hold them to `exclude_fields`. - Nothing is cached raw, and a failure names the host and the status, never the URL. - Learners are personal data. The actor’s contacts (`mbox`, `mbox_sha1sum`, `openid`) are left out by default; the actor’s name is not. Add `**.actor.name` or `**.actor.account.name` to `exclude_fields` where training records are read for trends rather than people. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------ | | `credential variable 'XAPI_KEY' is not set` | The deployment has not been given the key or secret | Connect the credential again | | `GET host: HTTP 401` | The LRS refused the credential | Check the client and that it may read statements | | ``GET host: a `more` link to another host was refused`` | The LRS pointed away from itself | Report it to us; nothing was followed | | `xapi: more than 1000 pages` | A very long result | Add a `verbs` filter, or raise `max_pages` | | `endpoint is the LRS's https xAPI endpoint` | `endpoint` is not https | Use the https endpoint | | `version is 1.0.3 or 2.0.0` | Any other version | Choose one of the two | | `limit is 1 to 10000` | A page size out of range | Correct it | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.47.0` | xAPI 1.0.3 and 2.0.0 (IEEE 9274.1.1) | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/xapi/ --- # Xero > Xero: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads a Xero organisation’s chart of accounts, contacts, invoices and bills, bank transactions, payments, manual journals, journals and reports, so finance agents can answer from the books. It only reads. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Xero, version `1.0.0` | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Reads | Xero: Xero Accounting API ([the vendor's documentation](https://developer.xero.com/documentation/api/accounting/overview)) | | Family | Finance | | Kind | Accounting | | Ways to connect | OAuth approval | | Scopes | - Read: `accounting.contacts.read`, `accounting.settings.read`, `accounting.invoices.read`, `accounting.payments.read`, `accounting.banktransactions.read`, `accounting.manualjournals.read`, `accounting.reports.profitandloss.read`, `accounting.reports.balancesheet.read`, `accounting.reports.aged.read`, `accounting.journals.read`, `accounting.transactions.read`, `accounting.reports.read` | | Read only | Yes, except: \[object Object] | | Vendor's API can move money | No | | Personal data | Financial, Contact | | Hosts it may contact | `api.xero.com`, `identity.xero.com` | | Vendor API versions | Accounting API 2.0 (api.xro/2.0) | | Lowest engine version | `0.46.0` | ## What it reads For each organisation you name (`tenants`, Xero’s tenant ids; with one connected organisation it can be left out): - **The organisation:** name, legal name, base currency, country, type, financial year end, short code. - **Chart of accounts, contacts, invoices and bills, bank transactions, payments and manual journals**, each with its amounts and currency. - **Journals** (where Xero has approved your app for them), by journal number. - **Reports:** profit and loss, balance sheet, and aged receivables and payables for the contacts you name in `aged_contacts`. - Changes only: each list is asked `If-Modified-Since` the start of the last successful pull, per organisation. It does not read attachments, payroll or files. ## How to connect 1. In Xero, make your own app: a web app (consent gives a refresh token) or a custom connection (client credentials, one organisation). 2. Grant it Xero’s `.read` scopes only (below). 3. In LightHouse, open **Setup and admin, Connectors**, choose **Xero**, and name the organisations. 4. Paste the client id, client secret and (for a web app) the refresh token. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`AAL_XERO` by default): `client_id`, `client_secret`, and `refresh_token` for a web app. ## Permissions This collector is **read-only**: it sends `GET` requests, and one `POST https://identity.xero.com/connect/token` to ask for an access token. Its read-only test proves it on every change. - **Scopes it expects:** for apps made since 2 March 2026 the granular ones: `accounting.invoices.read`, `accounting.payments.read`, `accounting.banktransactions.read`, `accounting.manualjournals.read`, `accounting.reports.profitandloss.read`, `accounting.reports.balancesheet.read`, `accounting.reports.aged.read`; for older apps `accounting.transactions.read` and `accounting.reports.read`; with `accounting.contacts.read`, `accounting.settings.read` and, where Xero has approved the app, `accounting.journals.read`. - **Refused by the code:** nothing. The check lists the scopes in the access token and names any that is not a `.read` scope (other than `openid`, `profile`, `email` and `offline_access`), with the words `granted scopes that write (...); this connector only reads: narrow the app to .read scopes`. It still reads. The collector never sends anything but `GET` to Xero, so a wider scope is not used, but only narrowing the app removes it. - **Not a funds-moving system:** Xero records payments and bank transactions in the ledger; its API does not move money. - **Refresh token:** Xero rotates it on every use and forgets an unused one after 60 days. The new one is written back to your own secret store in your deployment at once (not to Xero). - **Hosts:** only `api.xero.com` and `identity.xero.com`, over https. ## Limits - Accounting API 2.0. - Xero allows 60 calls a minute and 5,000 a day per organisation. Requests are paced a second apart, a 429 waits for `Retry-After`, and a pull stops early, keeping what it has, when the day’s remaining calls fall under 100. - Lists are paged 100 at a time. - A report whose scope is not granted is skipped, and so are journals if the app is not approved for them. - With more than one organisation connected, `tenants` is required (`Xero: name the organisations to read (tenants)`). ## Data handling - Contacts, invoices and bills hold personal and financial data. Documents carry the `label` you give the source (default `confidential`). - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - Errors carry a status and fixed text, never a provider’s body. - The data is audit-ready for your own agents; nothing here certifies anyone against any regulation. ## Troubleshooting | What you see | What it means | What to do | | -------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----------------------------------------- | | `Xero answered HTTP 401 (the app or its consent was refused)` | The client, secret or refresh token was refused | Check the app, or consent again | | `granted scopes that write (...); this connector only reads: narrow the app to .read scopes` | The app holds a write scope | Narrow the app in Xero | | `Xero: name the organisations to read (tenants)` | More than one organisation is connected | Name them in `tenants` | | `Xero: 1 named organisation(s) are not connected to this app` | A tenant id is not connected | Connect the organisation to the app | | `tenants and aged_contacts are Xero ids (GUIDs)` | An id is not a GUID | Use Xero’s tenant or contact id | | `Xero answered HTTP 429` | Rate limit | Nothing; the collector waits as Xero asks | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ------------------ | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Accounting API 2.0 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/xero/ --- # Zendesk > Zendesk: what the collector reads, how to connect it, its permissions, its certification by Atlantic Agentic Labs and its security posture. Built, not certified Built and tested against recorded and synthetic responses (version 1.0.0, 10 November 2026). Not yet run against the vendor's sandbox or a client environment. Reads tickets (with their comments and internal notes) and Help Centre articles from one Zendesk account, so service agents can answer from past tickets and the help centre. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse. ## At a glance | Collector | Zendesk, version `1.0.0` | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | Reads | Zendesk: Zendesk Support and Help Center (API v2) ([the vendor's documentation](https://developer.zendesk.com/api-reference/)) | | Family | ITSM | | Kind | Tickets | | Ways to connect | Access token | | Scopes | - Read: | | Read only | Yes | | Vendor's API can move money | No | | Personal data | Contact, Content | | Hosts it may contact | `{subdomain}.zendesk.com`, `{host}` | | Vendor API versions | Support API v2, Help Center API v2 | | Lowest engine version | `0.46.0` | ## What it reads - **Tickets:** number and subject, status, priority, type, tags, description, and (unless you turn `comments` off) every comment, each marked as a public comment or an internal note. - **Articles:** published Help Centre articles: title, body as text, link, section and locale. Drafts are skipped. - Only the objects you name in `objects` (`tickets`, `articles`). - Changes only. Tickets come from the search export, which an agent may use and which pages by cursor without the plain search’s 1,000-result limit. Search is indexed a little after a change, so the query starts five minutes before the cursor and anything not newer than it is dropped. Articles come from the Help Centre’s listing, newest first, stopping at the first one not newer than the cursor. It does not read attachments, users, organisations or satisfaction ratings. ## How to connect 1. In Zendesk, make an API token on an agent’s account. Use a light agent, or an agent with only the groups the source should read. 2. In LightHouse, open **Setup and admin, Connectors**, choose **Zendesk**, and fill in `objects`. 3. Give the subdomain (`.zendesk.com`), the agent’s email address and the token. Your browser seals it to your deployment; LightHouse never sees it. The credential is JSON in the variable the source names (`ZENDESK_CREDENTIAL` by default) with `subdomain`, `email` and `token`. They are sent as HTTP Basic authentication with the user name `/token`. ## Permissions - Zendesk states no scope for an API token: it is **the agent’s own access**, so read-only is the agent’s role and groups. A light agent that can read tickets is enough. The collector does not use the administrators-only incremental export, so it never needs an administrator’s token. - **What the collector does:** `GET` requests only, to the Support API and the Help Center API. Its read-only test proves that on every change. - **One host:** `https://.zendesk.com`, from the sealed credential and checked to be a plain Zendesk name. A next-page link to any other host is refused before the credential could be sent to it. ## Limits - Support API v2 and Help Center API v2. - The subdomain must be lower-case letters, digits and hyphens. - Pages of 10 to 1,000 (`page_size`, default 100). - Deletions are found by listing ids every six hours; a deleted ticket or an archived article is removed from the corpus then, not at once. - A token that cannot list tickets or articles (403 or 404) skips the deletion check for that object rather than failing the read. ## Data handling - Tickets hold personal data: requesters’ and agents’ names and whatever they wrote. Internal notes are marked as such in the document. Documents carry the `label` you give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential. - The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served. ## Troubleshooting | What you see | What it means | What to do | | ------------------------------------------------------ | -------------------------------------------------- | ----------------------------------------------------------- | | `credential variable 'ZENDESK_CREDENTIAL' is not set` | The deployment holds no credential for this source | Connect Zendesk again in LightHouse | | `the zendesk credential has no token` | A field (named in the message) is missing | Re-enter subdomain, email and token | | `subdomain is your Zendesk's name, .zendesk.com` | The subdomain is not a plain name | Give the name only, not a URL | | `HostNotAllowed` (`... is not an allowed host`) | A next-page link named another host | Report it; nothing was sent there | | `HTTP 401` | The email or token is wrong, or API access is off | Check the token and that token access is enabled | | `HTTP 429` | Zendesk’s rate limit | Nothing; the collector backs off and the next run continues | ## Certification Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See [How collectors are certified](/collectors/certification/). | Date | Collector | Engine | Vendor API | Method | Expires | | ---------------- | --------- | -------- | ---------------------------------- | ----------------------------------- | -------------- | | 10 November 2026 | `1.0.0` | `0.46.0` | Support API v2; Help Center API v2 | Fixtures only: built, not certified | Not applicable | ## Security posture From the collector’s last scan on the default branch. What each line means, and what blocks a release: [Security posture](/collectors/security/). | Last scanned | 10 November 2026 | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Critical findings | 0 | | High findings | 0 | | Medium findings | 0 | | Low findings | 0 | | Info findings | 0 | | Release blocked | No | | Network allow-list check | Pass | | Read-only behavioural test | Pass | | SBOM (CycloneDX) | Produced | | Dependency licences | Pass | | Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only | Source: https://docs.atlanticagenticlabs.com/collectors/catalogue/zendesk/ --- # Clouds > Where the engine runs: your AWS, Azure or Google Cloud account, your own servers, or Atlantic-hosted. The engine runs where you choose: in your own AWS, Azure or Google Cloud account, on your own servers, or in a dedicated account Atlantic runs for you. LightHouse is the same in every case. ## Choosing where it runs In LightHouse, **Setup and admin → Where agents run** (`client_admin`): choose the cloud, the region and the [deployment profile](/concepts/deployment-profiles/). LightHouse shows the estimated saving of ephemeral against always-on, then: - **for your own cloud or servers**, gives you the files to apply: a bootstrap that creates the identity your pipeline deploys with, and the stack itself as Terraform (Compose on your own servers). **Your own pipeline applies them, as a reviewed merge request. LightHouse never applies infrastructure in your account**, and the bootstrap grants Atlantic no access to it; - **for Atlantic-hosted**, records your request for Atlantic to review. See [Atlantic-hosted](/clouds/atlantic-hosted/). The files are checked against Atlantic’s infrastructure modules and the engine in LightHouse’s own build, with each cloud’s tools. A full apply in a real account has not yet been run by Atlantic on any of them: each cloud’s page says exactly what is proved, and we recommend a first apply in a sandbox account with one of our certified forward-deployed engineers. **Getting module access.** The stack’s Terraform reads Atlantic’s infrastructure modules as a package for the release. Atlantic issues each organisation a read-only token at onboarding, scoped to that package registry alone and revocable at any time; each cloud’s page says how your pipeline uses it. Changing your choice later moves nothing: the old deployment keeps running until your own pipeline takes it down. The same choice by API: `GET` and `PUT /api/v1/run-targets`, and `GET /api/v1/run-targets/stack` for the files. See the [Read reference](/api/reference/read/#get-targets). ## What is the same everywhere - The engine’s components: the gateway, the orchestrator and jobs, the telemetry relay, the content reader and the command channel. - The [telemetry contract](/concepts/telemetry-contract/): counts and timings to LightHouse only; content is not transmitted. - Every component dials out to LightHouse over HTTPS; nothing in your account listens for Atlantic. - Your content, your index and your model calls stay in your account and region. See [Data sovereignty](/data-sovereignty/). - The stack is a pinned release of Atlantic’s infrastructure modules, upgraded by a reviewed change. See [Upgrades](/operations/upgrades/). ## At a glance - [AWS](/clouds/aws/) - Runs on ECS on Fargate; Lambda when ephemeral - Models Amazon Bedrock - Secrets Secrets Manager - Database and index RDS PostgreSQL or Aurora Serverless v2 - Logs CloudWatch Logs, CloudTrail - Network VPC, NAT - [Azure](/clouds/azure/) - Runs on Container Apps, scaling to zero when ephemeral - Models Azure OpenAI - Secrets Key Vault - Database and index PostgreSQL Flexible Server - Logs Log Analytics - Network Virtual network, private endpoints, NAT gateway - [Google Cloud](/clouds/google-cloud/) - Runs on Cloud Run, scaling to zero when ephemeral - Models Vertex AI - Secrets Secret Manager - Database and index Cloud SQL for PostgreSQL - Logs Cloud Logging - Network VPC, Private Service Connect, Cloud NAT - [On-premises](/clouds/on-premises/) - Runs on Docker or Podman, with Compose - Models Your GPUs (vLLM, NIM) or a provider's API - Secrets Secret files - Database and index PostgreSQL with pgvector - Logs Volumes on your servers - Network Yours; outbound only, or air-gapped The same on all four: the engine's components, and one outbound path - **To LightHouse, over HTTPS** (downward): telemetry out, reads in place and signed commands, each on a connection opened from your side **LightHouse** your tenant, in Atlantic's account, the same whichever you choose The same engine on each target, on that platform's own services. Your content, your index and your model calls stay where the engine runs. | | [AWS](/clouds/aws/) | [Azure](/clouds/azure/) | [Google Cloud](/clouds/google-cloud/) | [On-premises](/clouds/on-premises/) | [Atlantic-hosted](/clouds/atlantic-hosted/) | | --------------------------- | -------------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------- | --------------------------------------------- | | Bootstrap | CloudFormation | Bicep (two files) | Terraform | None: the key is a secret file | Atlantic | | Stack | Terraform | Terraform | Terraform | Compose | Atlantic | | Regions in LightHouse | eu-west-1, eu-west-2, eu-central-1, us-east-1, us-west-2 | westeurope, northeurope, uksouth, eastus, westus2 | europe-west2, europe-west1, europe-west4, us-east4, us-central1 | Yours | eu-west-1, eu-west-2, eu-central-1, us-east-1 | | Models | Amazon Bedrock | Azure OpenAI | Vertex AI | Any backend the gateway supports | Amazon Bedrock | | Profiles | Both | Both | Both | Both | Both | | Estimated saving, ephemeral | around 95% | around 72% | around 87% | No cloud bill to compare | Quoted as managed infrastructure | The first region listed is LightHouse’s default. Savings are for a small deployment at list prices in the first region, and are **estimated**: see [Deployment profiles](/concepts/deployment-profiles/#estimated-savings-against-always-on). Source: https://docs.atlanticagenticlabs.com/clouds/ --- # AWS > Run the Atlantic Agentic Engine on AWS: the stack LightHouse generates, what it creates, the permissions it takes, regions, deployment profiles, and how to remove it. The engine runs in an AWS account of yours, as Terraform your own GitLab pipeline applies. Models are called through Amazon Bedrock, in your account and region, by the gateway’s role alone. LightHouse never applies anything in your account. ## The stack LightHouse generates In LightHouse, **Setup and admin → Where agents run**, choose **AWS**, a region and a profile, then **Get my stack**. LightHouse shows two files in full, each with a **Copy** button: 1. **`lighthouse-bootstrap.json`**, a CloudFormation template that a person creates once. **Open your Amazon Web Services console** opens CloudFormation’s create page in your region; upload the template there. It creates the role your pipeline deploys with, the permission boundary every role the stack creates must carry, and the Terraform state bucket. It creates no part of the engine itself. 2. **`main.tf`**, which calls three of Atlantic’s AWS modules, pinned to infrastructure release `v0.2.0` and read from that release’s module package: the stack itself, the telemetry relay and the content reader. Commit it to your own infrastructure repository; your pipeline plans and applies it from `main`, as a reviewed merge request. The template is copied from LightHouse, not linked to a template Atlantic hosts, so Atlantic cannot change what you applied after you read it. ### The bootstrap’s parameters and outputs | Parameter | What to give | | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | `GitLabProjectPath` | The full path of the gitlab.com project that applies the Terraform, for example `your-group/your-infra` | | `ExistingGitLabOidcProviderArn` | Empty, to create gitlab.com’s OIDC provider. An account has at most one per address: if yours already has one, give its ARN | A rule refuses to create the stack in any region but the one you chose in LightHouse. | Output | Use | | ------------------------ | -------------------------------------------------------------------------------------- | | `DeploymentRoleArn` | Your pipeline assumes it as `AWS_ROLE_ARN`, with GitLab’s ID token as the web identity | | `StateBucket` | `terraform init -backend-config="bucket="` | | `PermissionsBoundaryArn` | Carried by every role `main.tf` creates; `main.tf` already names it | ### What to have ready - An AWS account for the deployment, with the Bedrock models you want enabled in your region. - A gitlab.com project whose CI can request an ID token. - A module access token from Atlantic: a per-tenant, read-only deploy token whose scope is the package registry read only, revocable per client. Your Terraform job reads the modules with it through a netrc file, stored as a masked, file-type CI/CD variable, with `NETRC` set to that variable. The file holds one line, and Atlantic’s stack files say the same in a comment: ```text machine gitlab.com login password ``` - For `main.tf`’s variables: the account ID; the gateway’s image by digest in your ECR; an image carrying the engine (the gateway image will do) for the relay and the reader; the gateway policy (which models, caps and pacing); the Bedrock model IDs; an ACM certificate in your region; the address ranges allowed in; the monthly budget and the addresses for its alerts. Your own product’s image is optional: without it the stack runs the gateway alone. - For the ephemeral profile, also the gateway’s Lambda image, by digest. ### After the first apply Terraform creates the empty slots; a person fills them, and Terraform never holds the values: - `/lighthouse-deployment-key`: the deployment’s Ed25519 private key, made in your account. Only its public half is registered with LightHouse. - `aal-/content-reader-aal-public-key`: Atlantic’s reader public key. Empty it to stop Atlantic reading. - `aal-/content-reader-stores`: the read-only database addresses the reader may use. - Your product’s own secret key, when you set a product image. Every secret to fill is listed in the `fill_after_apply` output of `main.tf`, by what goes in each. ## What it creates **Your AWS account**: one region you choose, in a private network (VPC) Way in - **Load balancer**, Application Load Balancer, AWS WAF: open to your address ranges only your people and systems, from your address ranges Engine - **Gateway**, ECS on Fargate · AWS Lambda: the only path to a model: policy, caps, kill switch - **Your product and agents**, ECS on Fargate: runs your agents through the gateway - **Telemetry relay**, ECS on Fargate · Amazon SQS and a function: signs content-free records - **Content reader**, ECS on Fargate · a function every minute: answers reads signed by Atlantic - **Command channel**, ECS on Fargate · a function every minute: applies signed commands your policy allows - **Connector-schedule tick**, EventBridge Scheduler, an ECS task: every 15 minutes, syncs your sources model calls, from the gateway's role alone Models - **Amazon Bedrock**, in your account and region: a Bedrock guardrail on every call Kept in your account - **Secrets**, Secrets Manager, SSM: the deployment key, tokens, connector credentials - **Database and index**, RDS PostgreSQL · Aurora Serverless v2: the gateway's store and your index - **Files**, Amazon EFS: the deployment's files - **Keys**, AWS KMS: one key for data, logs and trail - **Logs**, CloudWatch Logs, CloudTrail: every content read, recorded One outbound path, through your NAT, over HTTPS - **Operational telemetry** (downward): counts, costs and timings from the relay, signed by your deployment. Never content - **Content, read in place** (both ways): a read signed by Atlantic, answered by your reader on the connection it opened - **Signed commands** (upward): pause, approve, set a cap: checked by your command channel against your policy **LightHouse**: your tenant, in Atlantic's account: intake, API, MCP and portal The stack your pipeline applies on AWS. Every component runs in your account; the gateway's role alone may call Amazon Bedrock; the relay, the content reader and the command channel each dial out to LightHouse, and nothing listens for Atlantic. Where two services are named, the second is the ephemeral profile's. - Amazon ECS - AWS Fargate - AWS Lambda - Amazon RDS - Amazon Aurora - Amazon S3 - AWS Secrets Manager - AWS Key Management Service - Amazon CloudWatch - Amazon VPC - Amazon ECR - Amazon Bedrock Every resource is named `aal-…`, where `` is your organisation’s short name in LightHouse, and tagged. | Area | Resources | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Keys | A KMS key and alias for the deployment’s data, logs and trail | | Network | A VPC (10.40.0.0/16) with the default security group closed, private and public subnets in two availability zones, and flow logs. Always-on: a NAT gateway and seven interface endpoints (Bedrock, ECR twice, CloudWatch Logs, Secrets Manager, KMS, EFS). Ephemeral: one NAT instance (t4g.nano) instead. An S3 gateway endpoint under both | | Logs and audit | CloudWatch log groups (400 days); a multi-region CloudTrail with log file validation, into its own bucket | | Database | Always-on: RDS PostgreSQL, Multi-AZ. Ephemeral: Aurora Serverless v2, pausing after five idle minutes. Both with deletion protection, 14 days of backups and a final snapshot | | Files | EFS, encrypted with the key, with access points | | Budget | An AWS Budget emailing at 80% forecast and 100% actual | | Secrets | The gateway’s token and the product’s secret key in Secrets Manager; the gateway policy in SSM, as a SecureString | | Compute | An ECS cluster on Fargate (ARM64) with service discovery. Always-on: the gateway as two tasks. Ephemeral: the gateway as an AWS Lambda function. Your product, if given, as one task | | Edge | An internet-facing Application Load Balancer with deletion protection and a web firewall, open to your address ranges only | | Guardrail | A Bedrock guardrail on every model call | | Telemetry | The relay, which signs content-free records with the deployment’s key and sends them to LightHouse. Always-on: an ECS service beside an OpenTelemetry Collector that also sends content-free traces to X-Ray in your account. Ephemeral: an encrypted SQS queue and a relay function, with no X-Ray traces | | Content reader | The read-only reader, which dials out to LightHouse and answers only reads signed with Atlantic’s reader key; every read is logged in your account. Always-on: an ECS service. Ephemeral: a function started every minute | **The command channel, the connector-schedule tick and the sealing key are in the generated stack**. `main.tf` adds the command channel (`aws-handler-commands`, with a prefix in Secrets Manager for connector credentials in your own account) and a job that runs the connector-schedule tick every 15 minutes. A new file beside it, `handler-commands.yaml`, is your deployment’s policy, with every command type off until you switch it on. The command key from Atlantic, the channel’s store URL and the sealing key are filled in after the apply, the sealing key made in AWS CloudShell in your own account. ## Permissions ### The deployment role The bootstrap creates one role, `lighthouse-deploy-`, that only your GitLab project’s `main` branch can assume (a merge request’s pipeline cannot), for at most an hour. No long-lived key exists. It holds AWS’s `PowerUserAccess`, which allows no IAM, and one policy of its own: | Statement | Effect | | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | One region only | Denies anything outside your region, except the global services the stack calls: IAM, STS, Budgets (the account budget), Route 53 (service discovery’s private zone), and Organizations’ and Support’s read calls | | The stack’s roles and no others | Allows managing and passing IAM roles named `aal--*`, and the instance profile of the same name, and nothing else in IAM | | Every role carries the boundary | Denies creating a role, or setting a boundary, without the bootstrap’s permission boundary; removing a boundary is denied outright | | Never itself | Denies any IAM action on its own role or on the boundary | | The state stays | Denies deleting the state bucket or changing its policy or versioning | | No users, no keys | Denies creating IAM users, access keys or console passwords, and leaving the organisation | | The trail stays | Denies stopping or deleting any CloudTrail trail but the stack’s own | **The permission boundary**, `lighthouse-boundary-`, allows the workload what its own policies give it and denies all of IAM, Organizations and Account. So no role the pipeline creates can do more in IAM than the pipeline itself. The template grants Atlantic no access to your account. Atlantic cannot assume the role. ### The workload’s roles | Role | Holds | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Gateway (the only role that may call a model) | `bedrock:InvokeModel`, `InvokeModelWithResponseStream`, `Converse` and `ConverseStream` on the listed models only; `ApplyGuardrail` | | Product | No Bedrock at all. On the ephemeral profile, invoking the gateway’s function, and nothing else of it | | Relay, reader | Each its own role, reading its own secrets | Setting `models_enabled = false` attaches an explicit deny on `bedrock:*` to the gateway’s role: a second kill switch, below the gateway’s own. See [Suspension](/operations/suspension/). ## Regions LightHouse offers eu-west-1 (the default), eu-west-2, eu-central-1, us-east-1 and us-west-2. The bootstrap must be created in the region you chose, its role is denied every other region, and `main.tf` pins every resource, the endpoints and the model calls to it. Global cross-region inference profiles are refused. See [Regions](/data-sovereignty/regions/). ## Deployment profiles The modules default to `always_on`; LightHouse proposes `ephemeral`, and writes the profile you chose into `main.tf`. | | Always-on (`always_on`) | Ephemeral (`ephemeral`) | | ----------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | Gateway | Two Fargate tasks, always warm | A Lambda function (ARM64) behind a function URL with IAM authentication; the product reaches it through a local forwarder | | Relay | Two Fargate tasks, with the collector | A queue and a function; no X-Ray traces | | Content reader | A Fargate task holding its connection | A function every minute; a read waits up to about a minute while it wakes | | Database | RDS PostgreSQL, Multi-AZ | Aurora Serverless v2; about 15 seconds to resume after a pause | | Network | NAT gateway and interface endpoints | One NAT instance | | Product | One task | One task | | Estimated saving on the lines that differ (eu-west-1) | — | around 95% | The estimated saving on those lines is around 95%, from the modules’ cost model at list prices before credits and free tiers. It is given as a proportion because the amount depends on your region, your currency, any committed-use or reserved pricing and the size you run. Your own figures appear in LightHouse once your deployment reports its infrastructure cost. The lines both profiles share (the load balancer, the product, EFS, the key, logs, the trail, secrets) are left out of both, so it is understated. To switch, change `deployment_profile` (and, for ephemeral, add `gateway_lambda_image`), then plan and apply. No data moves: the key, the database, the file system and the secrets are kept. `main.tf` sets the database and network to suit the profile it was generated for; changing the database is a separate migration. See [Deployment profiles](/concepts/deployment-profiles/). Scheduled (`scheduled`, with `wake_schedule`) is built as ephemeral, and inside its [wake window](/concepts/deployment-profiles/#the-wake-window) Application Auto Scaling scheduled actions, in the window’s time zone, keep provisioned concurrency on the gateway function so it answers at once. Switching from ephemeral to scheduled publishes a function version behind an alias, so the function URL’s address changes; the forwarders take the new address in the same apply. ## Upgrading and removing the stack - **Upgrade**: change the release version in the module package’s address (`https://gitlab.com/api/v4/projects//packages/generic/lighthouse-modules//lighthouse-modules.tar.gz`), changed by getting the stack again for the new release, in a reviewed merge request. Images are pinned by digest. See [Upgrades](/operations/upgrades/). - **Remove**: see Remove my stack, below. ### Remove my stack As a client administrator, open **Setup and admin → Run → Remove my stack**. LightHouse generates a step-by-step guide (`lighthouse-removal.md`) and a pipeline job file (`lighthouse-removal.gitlab-ci.yml`) for this stack. It changes nothing itself, and nothing runs automatically: the jobs are manual, run on your main branch only, and refuse to run until the CI/CD variable `LIGHTHOUSE_REMOVE` names the deployment. 1. **Lift deletion protection**, in an apply of its own. The database and the load balancer are protected, and the job lifts both before anything is destroyed. It refuses any plan that does more than that, and reads the load balancer’s protection back from AWS before it goes on, because a destroy that meets the protection stops half way with the services already gone. 2. **Destroy** the stack with `terraform destroy`. 3. **Delete the bootstrap**, a person’s step: its CloudFormation stack. The state bucket is kept until a person empties and deletes it. 4. **Deregister in LightHouse**, a person’s step. Deregistering is the last step. You sign in as a person with a second factor (a machine key or a delegated token is refused), type the deployment’s name again and give a reason. LightHouse then refuses the deployment’s signatures from that moment and records it in the audit log. Only Atlantic can reinstate it, within 30 days. Source: https://docs.atlanticagenticlabs.com/clouds/aws/ --- # Azure > Run the Atlantic Agentic Engine on Azure: the stack LightHouse generates, what it creates, the permissions it takes, regions, deployment profiles, and how to remove it. The engine runs in an Azure subscription of yours, as Terraform your own GitLab pipeline applies. Models are called through Azure OpenAI, in your subscription and region, by the gateway’s identity alone. LightHouse never applies anything in your subscription. ## The stack LightHouse generates In LightHouse, **Setup and admin → Where agents run**, choose **Azure**, a region and a profile, then **Get my stack**. LightHouse shows three files in full, each with a **Copy** button: 1. **`lighthouse-bootstrap.bicep`**, a subscription-scope deployment that a person runs once, and 2. **`lighthouse-bootstrap-identity.bicep`**, its resource group’s half, which the first file deploys. Keep the two side by side. 3. **`main.tf`**, which calls Atlantic’s Azure module, pinned to infrastructure release `v0.2.0`, with the telemetry relay and the content reader turned on. Commit it to your own infrastructure repository; your pipeline plans and applies it from `main`, as a reviewed merge request. There is no portal button: the portal’s custom deployment takes ARM templates, not Bicep. The bootstrap’s first lines give the command, run by a person with rights to assign roles on the subscription: ```sh az deployment sub create --location \ --template-file lighthouse-bootstrap.bicep \ --parameters gitlabProjectPath= ``` Its outputs are `deployClientId` (your pipeline’s `ARM_CLIENT_ID`, with `ARM_USE_OIDC=true`), `stateResourceGroup` and `stateStorageAccount` (`terraform init -backend-config="storage_account_name="`). ### What to have ready - A subscription, and the Azure OpenAI model deployments you are allowed to create in your region. - A gitlab.com project whose CI can request an ID token. - A module access token from Atlantic: a per-tenant, read-only deploy token whose scope is the package registry read only, revocable per client. Your Terraform job reads the modules with it through a netrc file, stored as a masked, file-type CI/CD variable, with `NETRC` set to that variable. The file holds one line, and Atlantic’s stack files say the same in a comment: ```text machine gitlab.com login password ``` - A runner inside your network, or your runners’ address ranges for `deployer_cidrs`: the Key Vault’s data plane is private, and the apply must reach it. - For `main.tf`’s variables: the subscription ID; the product’s and the gateway’s images by digest; an image carrying the engine (the gateway image will do) for the relay and the reader; your registry, if it is private (a person grants the runtime identity AcrPull on it: the pipeline cannot); the model deployments; the gateway policy; the address ranges allowed in; the monthly budget, its start date and the addresses for alerts. ### After the first apply Terraform creates the Key Vault’s slots empty; a person fills them. The `fill_after_apply` output of `main.tf` lists the secrets to fill, by what goes in each. ## What it creates **Your Azure subscription**: one region you choose, in its own resource group and virtual network Way in - **Container Apps ingress**, HTTPS: open to your address ranges only your people and systems, from your address ranges Engine - **Gateway**, Container Apps, warm or scaled to zero: the only path to a model: policy, caps, kill switch - **Your product and agents**, Container Apps: runs your agents through the gateway - **Telemetry relay**, Container Apps, internal ingress: signs content-free records - **Content reader**, Container Apps · a job every minute: no ingress; answers reads signed by Atlantic - **Command channel**, Container Apps · a job every minute: applies signed commands your policy allows - **Connector-schedule tick**, a Container Apps job: every 15 minutes, syncs your sources model calls, from the gateway's identity alone, over a private endpoint Models - **Azure OpenAI**, in your subscription, no public access: a content filter on every deployment Kept in your subscription - **Secrets and keys**, Key Vault (premium, private endpoint): the deployment key, tokens, connector credentials - **Database and index**, PostgreSQL Flexible Server: on a private address - **Logs**, Log Analytics: activity, vault and database; every content read One outbound path, through your NAT gateway, over HTTPS - **Operational telemetry** (downward): counts, costs and timings from the relay, signed by your deployment. Never content - **Content, read in place** (both ways): a read signed by Atlantic, answered by your reader on the connection it opened - **Signed commands** (upward): pause, approve, set a cap: checked by your command channel against your policy **LightHouse**: your tenant, in Atlantic's account: intake, API, MCP and portal The stack your pipeline applies on Azure. Every component runs in your subscription; Azure OpenAI has no public access and answers the gateway's identity alone; the relay, the content reader and the command channel each dial out to LightHouse, and nothing listens for Atlantic. Where two forms are named, the second is the ephemeral profile's. - Azure Container Apps - Azure Database for PostgreSQL - Azure Key Vault - Azure Monitor - Azure Blob Storage - Azure OpenAI The bootstrap, in a resource group of its own, `lighthouse--bootstrap`: | Resource | What it is | | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `lighthouse-deploy-` | A user-assigned identity, with one federated credential that only your GitLab project’s `main` branch can use. No secret is created | | The state account | A zone-redundant storage account for the Terraform state: Entra ID sign-in only (shared keys off), TLS 1.2, no public blob access, versioned, with 30 days’ soft delete of blobs and containers. The identity holds Storage Blob Data Contributor on its `tfstate` container only | | A read-only lock | On the bootstrap’s group, so the pipeline cannot add a credential for another branch. Contributor cannot lift it; a person changes the bootstrap | The engine, from `main.tf`, in its own resource group `aal-`: | Area | Resources | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Network | A virtual network with subnets for the apps (delegated to Container Apps), private endpoints and the database, with default outbound access off; network security groups; a NAT gateway; private DNS zones | | Keys and secrets | A premium Key Vault (RBAC, purge protection, private endpoint); the data key; the gateway’s token, policy and the product’s key as secrets | | Logs | A Log Analytics workspace, with diagnostics for the subscription’s activity log, the vault and the database | | Database | Azure Database for PostgreSQL Flexible Server on a private address | | Budget | A subscription budget alerting at 80% forecast and 100% actual | | Compute | A Container Apps environment with the `gateway` and `app` container apps | | Models | An Azure OpenAI account with no public access and no keys, a content filter on every deployment, and your model deployments | | Telemetry and reads | The relay (internal ingress only) and the content reader (no ingress; it dials out to LightHouse and answers only reads signed with Atlantic’s reader key) | **The command channel, the connector-schedule tick and the sealing key are in the generated stack**: the command channel with every command type off, connector credentials kept in your own Key Vault, a slot for the sealing key, and the tick every 15 minutes, on both profiles. ## Permissions | Identity | Holds | Why | | ------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `lighthouse-deploy-` (your pipeline) | Contributor on the subscription | The module creates its own resource group, a subscription budget and the activity log’s diagnostic setting | | | Role Based Access Control Administrator on the subscription, with a condition | It may create or delete an assignment of only the module’s five roles: Cognitive Services OpenAI User, Key Vault Crypto Officer, Key Vault Secrets Officer, Key Vault Secrets User and Key Vault Crypto Service Encryption User. Never Owner, Contributor, or more for itself | | | Storage Blob Data Contributor on the state container | The Terraform state | | Gateway (the only identity that may call a model) | Cognitive Services OpenAI User on the model account | | | Product | No role | | | Runtime | Key Vault Secrets User | Its own secrets | | Keys | Key Vault Crypto Service Encryption User | Encryption with your key | The bootstrap grants Atlantic no access to your subscription. Turning `models_enabled` off removes the gateway’s model role: a second kill switch, which Azure applies within minutes rather than instantly. See [Suspension](/operations/suspension/). ## Regions LightHouse offers westeurope (the default), northeurope, uksouth, eastus and westus2. Every resource is in the location you choose; geography-wide names (`europe`, `uk`, `global`) are refused. Model deployments may be only `Standard` or `ProvisionedManaged`: Global and DataZone deployments, which can process in other regions, are refused. See [Regions](/data-sovereignty/regions/). ## Deployment profiles The module defaults to `always_on`; LightHouse proposes `ephemeral`, and writes the profile you chose into `main.tf`. | | Always-on | Ephemeral | | ------------------------------------------------------ | -------------------------------------- | -------------------------------------------------------------------- | | Gateway | Two warm replicas | Scales to zero; the first request wakes a replica and waits for it | | Relay | One replica | Zero, woken by the first post | | Content reader | A container app holding its connection | A Container Apps job every minute; a read waits up to about a minute | | Product | One replica | One replica | | Database | General Purpose, with a standby | Burstable (`B_Standard_B1ms`), no standby | | Estimated saving on the lines that differ (westeurope) | — | around 72% | The estimated saving on those lines is around 72%, from the module’s cost model at list prices before free grants and discounts. Most of it comes from the database: for an ephemeral deployment, the generated `main.tf` sets a burstable server (`db_sku_name = "B_Standard_B1ms"`, no standby) instead of the module’s general-purpose default. The `deployment_profile` variable itself does not resize the database, and Azure’s PostgreSQL Flexible Server cannot pause when idle, which is why the saving is the lowest of the three clouds. It is given as a proportion because the amount depends on your region, your currency, any committed-use or reserved pricing and the size you run. Your own figures appear in LightHouse once your deployment reports its infrastructure cost. The lines both profiles share (the product, Key Vault, Log Analytics, private endpoints, the Container Apps environment) are left out of both. Wake times on Azure are estimates, not yet measured in a client subscription. To switch, change `deployment_profile`, plan and apply: nothing holding data is replaced. Resizing the database is a separate change. See [Deployment profiles](/concepts/deployment-profiles/). Scheduled (`scheduled`, with `wake_schedule`) is built as ephemeral, and inside its [wake window](/concepts/deployment-profiles/#the-wake-window) a cron scale rule per window keeps warm gateway replicas running; the HTTP rule still adds replicas under load. ## Upgrading and removing the stack - **Upgrade**: change the release version in the module package’s address (`https://gitlab.com/api/v4/projects//packages/generic/lighthouse-modules//lighthouse-modules.tar.gz`), changed by getting the stack again for the new release, in a reviewed merge request. See [Upgrades](/operations/upgrades/). - **Remove**: see Remove my stack, below. ### Remove my stack As a client administrator, open **Setup and admin → Run → Remove my stack**. LightHouse generates a step-by-step guide (`lighthouse-removal.md`) and a pipeline job file (`lighthouse-removal.gitlab-ci.yml`) for this stack. It changes nothing itself, and nothing runs automatically: the jobs are manual, run on your main branch only, and refuse to run until the CI/CD variable `LIGHTHOUSE_REMOVE` names the deployment. 1. **Destroy** the stack with `terraform destroy`. The Key Vault has purge protection, so its name is held for its soft-delete period. 2. **Delete the bootstrap**, a person’s step: lift its read-only lock, remove the identity’s two role assignments on the subscription, and delete the bootstrap’s resource group, with the state in it. 3. **Deregister in LightHouse**, a person’s step. Deregistering is the last step. You sign in as a person with a second factor (a machine key or a delegated token is refused), type the deployment’s name again and give a reason. LightHouse then refuses the deployment’s signatures from that moment and records it in the audit log. Only Atlantic can reinstate it, within 30 days. Source: https://docs.atlanticagenticlabs.com/clouds/azure/ --- # Google Cloud > Run the Atlantic Agentic Engine on Google Cloud: the stack LightHouse generates, what it creates, the permissions it takes, regions, deployment profiles, and how to remove it. The engine runs in a Google Cloud project of yours, as Terraform your own GitLab pipeline applies. Models are called through Vertex AI, in your project and region, by the gateway’s service account alone. LightHouse never applies anything in your projects. ## The stack LightHouse generates In LightHouse, **Setup and admin → Where agents run**, choose **Google Cloud**, a region and a profile, then **Get my stack**. LightHouse shows two Terraform files in full, each with a **Copy** button: 1. **`bootstrap.tf`**, which a person applies once, in a small bootstrap project of its own beside your workload project, so no workload apply can reach what applies it. It calls Atlantic’s `gcp-bootstrap` module, pinned to infrastructure release `v0.2.0`. 2. **`main.tf`**, which calls Atlantic’s Google Cloud module at the same release, with the telemetry relay and the content reader turned on. Commit it to your own infrastructure repository; your pipeline plans and applies it, as a reviewed merge request. There is no console link for Google Cloud. ### The bootstrap’s variables and outputs | Variable | What to give | | ---------------------- | ------------------------------------------------------------------ | | `bootstrap_project_id` | The bootstrap’s own project (the module’s `project_id`) | | `workload_project_id` | Your workload project, where `main.tf` is applied | | `gitlab_project_path` | The full path of the gitlab.com project that applies the Terraform | Its outputs are `state_bucket` (`terraform init -backend-config="bucket="`), `workload_identity_provider`, `plan_service_account` and `apply_service_account`, for your pipeline’s workload identity configuration. Your organisation’s short name in LightHouse names the resources, and Google Cloud’s modules take at most 18 characters, starting with a letter. If yours is longer, LightHouse says so instead of generating a stack that would fail at plan; ask Atlantic. ### What to have ready - A workload project, and a bootstrap project beside it. - A gitlab.com project whose CI can request an ID token, with a protected `production` environment for the apply job. - A module access token from Atlantic: a per-tenant, read-only deploy token whose scope is the package registry read only, revocable per client. Your Terraform job reads the modules with it through a netrc file, stored as a masked, file-type CI/CD variable, with `NETRC` set to that variable; a person applying `bootstrap.tf` needs the same token. The file holds one line: ```text machine gitlab.com login password ``` - For `main.tf`’s variables: the workload project ID; the product’s and the gateway’s images by digest; an image carrying the engine (the gateway image will do) for the relay and the reader; the gateway policy; the address ranges allowed in; a regional SSL certificate; the monthly budget and the billing account. With no billing account, no budget is created and the budget is set on the billing account by hand: the apply account has no billing rights. ### After the first apply Terraform creates the secrets empty; a person fills them. The `fill_after_apply` output of `main.tf` lists them, by what goes in each, including the product’s secret key. ## What it creates **Your Google Cloud project**: one region you choose, in a VPC that denies ingress Way in - **Load balancer**, regional HTTPS load balancer, Cloud Armor: open to your address ranges only your people and systems, from your address ranges Engine - **Gateway**, Cloud Run, warm or scaled to zero: the only path to a model: policy, caps, kill switch - **Your product and agents**, Cloud Run: runs your agents through the gateway - **Telemetry relay**, Cloud Run, internal ingress: signs content-free records - **Content reader**, Cloud Run worker pool · a job every minute: no endpoint; answers reads signed by Atlantic - **Command channel**, Cloud Run worker pool · a job every minute: applies signed commands your policy allows - **Connector-schedule tick**, a Cloud Run job, Cloud Scheduler: every 15 minutes, syncs your sources model calls, from the gateway's service account alone, over Private Service Connect Models - **Vertex AI**, in your project and region: Model Armor screens every call Kept in your project - **Secrets**, Secret Manager, in-region: the deployment key, tokens, connector credentials - **Database and index**, Cloud SQL for PostgreSQL: on a private address - **Logs**, Cloud Logging, a regional bucket: every content read, recorded One outbound path, through Cloud NAT, over HTTPS - **Operational telemetry** (downward): counts, costs and timings from the relay, signed by your deployment. Never content - **Content, read in place** (both ways): a read signed by Atlantic, answered by your reader on the connection it opened - **Signed commands** (upward): pause, approve, set a cap: checked by your command channel against your policy **LightHouse**: your tenant, in Atlantic's account: intake, API, MCP and portal The stack your pipeline applies on Google Cloud. Every component runs in your project; Vertex AI answers the gateway's service account alone, with Model Armor on every call; the relay, the content reader and the command channel each dial out to LightHouse, and nothing listens for Atlantic. Where two forms are named, the second is the ephemeral profile's. - Cloud Run - Cloud SQL - Secret Manager - Cloud Storage - Cloud Scheduler - Vertex AI | Area | Resources | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bootstrap (its own project) | A state bucket in your region (versioned, uniform access, public access prevented, never force-destroyed, every read and write in the audit log); a workload identity pool and provider that accept tokens from your one GitLab project only; the plan and apply service accounts | | Network | A VPC with service and proxy subnets, a deny-ingress firewall, Private Service Connect for Google’s APIs, private DNS, Cloud Router and NAT | | Logs | A regional log bucket and sink, with the default bucket excluded | | Database | Cloud SQL for PostgreSQL on a private address, with deletion protection | | Budget | A billing budget, if you give the billing account | | Compute | Cloud Run services for the `gateway` and the `app`, behind a regional HTTPS load balancer with Cloud Armor, open to your address ranges only | | Models | Vertex AI access for the gateway alone, and Model Armor screening every call | | Secrets | Secret Manager, replicated within the region | | Telemetry and reads | The relay (Cloud Run, internal ingress) and the content reader (no endpoint; it dials out to LightHouse and answers only reads signed with Atlantic’s reader key) | **The command channel, the connector-schedule tick and the sealing key are in the generated stack**: the command channel with every command type off, connector credentials kept in your own Secret Manager, a slot for the sealing key, and the tick every 15 minutes, on both profiles. ## Permissions | Identity | Holds | Why | | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Plan service account | `roles/viewer` and `roles/iam.securityReviewer` on the workload project | Read-only, for plans from any branch of your GitLab project | | Apply service account | `roles/editor`, `roles/secretmanager.admin`, `roles/modelarmor.admin` and `roles/servicenetworking.networksAdmin` on the workload project | What the stack creates. Usable only from `main`, in your protected `production` environment | | | `roles/resourcemanager.projectIamAdmin`, with a condition | It may grant or remove only the stack’s four roles (Vertex AI user, Cloud SQL client, Cloud SQL instance user, Model Armor user); never Owner or an admin role | | | A custom role, `lighthouseCloudRunIam_`, on the workload project (added by `bootstrap.tf`), with exactly four permissions: `run.services.getIamPolicy`, `run.services.setIamPolicy`, `run.jobs.getIamPolicy` and `run.jobs.setIamPolicy` | Terraform must set who may invoke the Cloud Run services and jobs it creates, and the module’s apply roles do not include that. The role can change who may invoke a Cloud Run resource and nothing else. No condition yet limits it by resource name | | Gateway (the only identity that may call a model) | `roles/aiplatform.user`, Cloud SQL client, Model Armor user, and its own secrets | | | Product | Its own secrets only | | No service account key is created, and the bootstrap grants Atlantic no access to either project. Turning `models_enabled` off removes the gateway’s Vertex AI role: a second kill switch. See [Suspension](/operations/suspension/). ## Regions LightHouse offers europe-west2 (the default), europe-west1, europe-west4, us-east4 and us-central1. Every resource, and the state bucket, is in the region you choose. Vertex AI regions must be named; there is no global endpoint. Model Armor’s location is set separately. See [Regions](/data-sovereignty/regions/). ## Deployment profiles The module defaults to `always_on`; LightHouse proposes `ephemeral`, and writes the profile you chose into `main.tf`. | | Always-on | Ephemeral | | -------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | | Gateway | Cloud Run, two minimum instances | No minimum instances; the first request starts one and waits for it | | Relay | One instance, CPU always allocated | Scales to zero, woken by the first post | | Content reader | A worker pool holding its connection | A Cloud Run job every minute, started by Cloud Scheduler; a read waits up to about a minute | | Product | One minimum instance | One minimum instance | | Database | `db-custom-2-7680` | `db-f1-micro`, zonal (shared core, outside Cloud SQL’s SLA) | | Estimated saving on the lines that differ (europe-west2) | — | around 87% | The estimated saving on those lines is around 87%, from the module’s cost model at list prices before free tiers and discounts (Cloud SQL at its us-central1 list price, so a floor for London). It is given as a proportion because the amount depends on your region, your currency, any committed-use or reserved pricing and the size you run. Your own figures appear in LightHouse once your deployment reports its infrastructure cost. The lines both profiles share (the product, the load balancer and Cloud Armor, Secret Manager, logging) are left out of both. To switch, change `deployment_profile`, plan and apply: nothing holding data is replaced. Resizing the database is a separate change. See [Deployment profiles](/concepts/deployment-profiles/). Scheduled (`scheduled`, with `wake_schedule`) is built as ephemeral, and Cloud Scheduler sets the gateway service’s minimum instances at the start of each [wake window](/concepts/deployment-profiles/#the-wake-window) and returns them to zero at its end, without making a new revision. ## Upgrading and removing the stack - **Upgrade**: change the release version in the module package’s address (`https://gitlab.com/api/v4/projects//packages/generic/lighthouse-modules//lighthouse-modules.tar.gz`), changed by getting the stack again for the new release, in a reviewed merge request. After an apply, `fill_after_apply` lists any secrets to fill. See [Upgrades](/operations/upgrades/). - **Remove**: see Remove my stack, below. ### Remove my stack As a client administrator, open **Setup and admin → Run → Remove my stack**. LightHouse generates a step-by-step guide (`lighthouse-removal.md`) and a pipeline job file (`lighthouse-removal.gitlab-ci.yml`) for this stack. It changes nothing itself, and nothing runs automatically: the jobs are manual, run on your main branch only, and refuse to run until the CI/CD variable `LIGHTHOUSE_REMOVE` names the deployment. 1. **Lift deletion protection**, in an apply of its own. The Cloud SQL instance, both Cloud Run services and the Filestore share are protected, and the job lifts them before anything is destroyed. It refuses any plan that does more than that. 2. **Destroy** the stack with `terraform destroy`. 3. **Delete the bootstrap**, a person’s step. Its state bucket is emptied first, never force-destroyed. 4. **Deregister in LightHouse**, a person’s step. Deregistering is the last step. You sign in as a person with a second factor (a machine key or a delegated token is refused), type the deployment’s name again and give a reason. LightHouse then refuses the deployment’s signatures from that moment and records it in the audit log. Only Atlantic can reinstate it, within 30 days. Source: https://docs.atlanticagenticlabs.com/clouds/google-cloud/ --- # Your own servers (Docker or Podman) > Run the Atlantic Agentic Engine on your own servers with Docker or Podman: the Compose file LightHouse generates, setting up each runtime, what it runs, what it may reach, and how to remove it. On your own servers, or on a single virtual machine in any cloud, the engine’s relay and content reader run as containers beside your product’s own Compose stack. You can run them with Docker or with Podman. Nothing listens for Atlantic: every connection to LightHouse is outbound, and the file publishes no port. ## Docker or Podman Both runtimes run the same file. Pick the one your servers already run. | | Docker | Podman | | ----------------- | ----------------------------- | -------------------------------------------------------------------- | | Version | Docker Engine with Compose v2 | Podman 5, with Docker’s Compose as the provider for `podman compose` | | Command | `docker compose …` | `podman compose …` with the same arguments | | Always-on profile | Supported | Supported | | Ephemeral profile | Supported | Supported. The generated file carries the two settings Podman needs | **If you have a choice, use rootless Podman.** There is no daemon running as root, and every container runs as an ordinary user on the host. Under the ephemeral profile, the one container that controls other containers can then reach only that user’s containers. With Docker, or with Podman run as root, it can reach every container on the host. ### Set up the host **Podman (rootless)** Run these as the user who will own the stack, on RHEL 9 or later, Fedora, or any distribution with Podman 5: ```sh sudo loginctl enable-linger "$USER" # the user's services keep running after logout, and start at boot systemctl --user enable --now podman.socket # the Docker-compatible API the ephemeral scheduler uses systemctl --user enable podman-restart.service # restarts the stack's containers at boot echo "$XDG_RUNTIME_DIR/podman/podman.sock" # your CONTAINER_SOCKET, below ``` Install Docker’s Compose binary from Docker’s releases (RHEL does not package it), in a directory on your `PATH`, such as `.local/bin` in your home directory, named `docker-compose`. `podman compose` finds it there and uses it. For the ephemeral profile, add to `.env`: ```sh CONTAINER_SOCKET=/run/user/1000/podman/podman.sock # the path the last command printed SOCKET_PROXY_USER=0:0 ``` `0:0` looks like root but is not. In a rootless container, uid 0 is the host user who owns the socket. Podman’s socket can be opened only by its owner, so the proxy has to run as that user. **Podman (rootful)** ```sh sudo systemctl enable --now podman.socket # the Docker-compatible API, at /run/podman/podman.sock sudo systemctl enable podman-restart.service # restarts the stack's containers at boot ``` Install Docker’s Compose binary from Docker’s releases, for example at `/usr/local/bin/docker-compose`. For the ephemeral profile, add to `.env`: ```sh CONTAINER_SOCKET=/run/podman/podman.sock SOCKET_PROXY_USER=0:0 ``` Here `0:0` is root, with every Linux capability dropped, no new privileges and a read-only file system. Any process that can open the runtime’s socket can control the host, with Docker as with Podman. What limits the proxy is its allowlist, described under [Permissions](#permissions). **Docker** Docker Engine and its Compose plugin, from your distribution or from Docker. For the ephemeral profile, add the group that owns Docker’s socket to `.env`: ```sh stat -c %g /var/run/docker.sock # for example 999 ``` ```sh DOCKER_GID=999 ``` The proxy then runs as `nobody` in that group, because Docker’s socket can be opened by its group. ### Hosts with SELinux enforcing RHEL and its relatives enforce SELinux by default, under either runtime. The secret files are mounted by Compose, which cannot label them, so label them once: ```sh chcon -R -t container_file_t secrets ``` The socket proxy runs with SELinux labelling turned off for itself only, so that it can reach the socket. No other container needs it, and on a host without SELinux the setting has no effect. ### Ports below 1024 under rootless Podman The generated file publishes no port, so this matters only if your own front door runs in the same rootless Podman. A rootless user cannot bind port 443 unless the host allows it (`sysctl net.ipv4.ip_unprivileged_port_start=443`, persisted in `/etc/sysctl.d/`). Otherwise, bind a higher port and forward 443 to it at the host’s firewall. ## Get my stack: the bundle 1. In LightHouse, go to **Setup and admin → Where agents run** and choose **Your own servers**. The card covers Docker and Podman. 2. Choose a profile, then **Get my stack**. LightHouse shows every file in full, with **Copy** on each. Or, with the LightHouse CLI and your own portal session, write them all into a directory at once: ```sh lighthouse-ai stack --cloud onprem --out ./lighthouse ``` A tenant with more than one deployment adds `--deployment ` (`?deployment=` on the API): the files sign and answer as that deployment only. 3. Fill in the two choices that are yours, in `.env`, then the model’s credentials, then run `./lighthouse-start.sh`. There is no cloud bootstrap and no console link. What the bundle holds: | File | What it is | | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `compose.yaml` | The stack: the containers that connect your deployment to LightHouse, and your product’s side (the gateway, the knowledge database and Octy) | | `.env` | Every setting, filled in for your deployment: the engine’s images by digest, the deployment’s name, the network. Two are marked **FILL IN**: the model provider and how Octy signs your people in. No secrets | | `lighthouse-start.sh` | One command to start. Safe to run again | | `lighthouse-check.sh` | Checks every part, and asks Octy one question | | `handler-commands.yaml` | Your policy for commands from LightHouse: every type off until you switch it on | | `gateway/policy.yaml` | Your gateway’s allow-list and prices. A model with no price is refused | | `octy/octy.yaml` | Octy’s configuration: her models through your gateway, your documents, your identity provider | | `documents/welcome.md` | A first document. Add your own Markdown beside it | | `catalogs/knowledge.yaml` | The catalogue of your source cards, which the sync tick pulls when LightHouse schedules a source. Empty until you add one | | `database/init.sh`, `database/grants.sql` | The knowledge database’s set-up: a database for Octy with pgvector, and a user for each part with only the rights it needs | | `secrets/aal-reader-public-key`, `secrets/aal-command-public-key` | Atlantic’s two public keys. Empty either file to stop Atlantic reading, or acting | | `gateway-local-model.yaml` | Only with a model on your own GPUs: see [Self-hosted models](#self-hosted-models) | ### The engine’s images Atlantic publishes the engine’s two images with every engine release, to its private registry on GitLab (`registry.gitlab.com`): the **engine** image (the gateway, the relay, the content reader, the command channel and the sync tick) and the **Octy** image (Octy and her widget). `.env` names both in full. Each is built for x86-64 and arm64, scanned for vulnerabilities before it is published, carries a software bill of materials, and is signed with Sigstore’s cosign by Atlantic’s release pipeline, with no long-lived signing key. `.env` pins both by digest, so what runs is exactly what was scanned and signed. Your administrator gets your own read-only **deploy token** from Atlantic once: its username is already in `.env` (`AAL_REGISTRY_USER`), and the token goes in `secrets/registry-token`. It can read the images and nothing else. Revoking it stops only you. To check an image’s signature before you run it, ask Atlantic for the `cosign verify` command of your release: it names the identity of the pipeline that signed it. If `.env` leaves the images empty, your LightHouse predates the first release with published images: ask Atlantic. ### Fill in two choices In `.env`: - **The model provider**, `AAL_GATEWAY_BACKEND`: `anthropic` (the Claude API), `bedrock` (Amazon Bedrock) or `openai-compatible` (a model on your own GPUs, or any OpenAI-compatible endpoint). For Bedrock in the EU, uncomment the three preset lines `.env` gives; they map each model in the gateway’s policy to Bedrock’s own id. - **How Octy signs your people in**, `OCTY_OIDC_ISSUER`, `OCTY_OIDC_AUDIENCE` and `OCTY_OIDC_JWKS_URL`: your OpenID Connect identity provider (Entra ID, Okta, Google, Keycloak). Octy uses Claude Haiku 4.5 to route and Claude Sonnet 4.6 to answer, both allowed and priced in `gateway/policy.yaml`. Change both files together. The prices are Anthropic’s published rates; put your own provider’s rate card there before you rely on spend. ### Start **Docker** ```sh cd lighthouse ./lighthouse-start.sh ``` **Podman** ```sh cd lighthouse CONTAINER_RUNTIME=podman ./lighthouse-start.sh ``` The first run makes, on this host, every secret it can: the deployment’s signing key and sealing key, a password for each database user and the gateway’s service token. They are files in `secrets/`, a directory closed to everyone else on the host; nothing in them leaves it. It then writes a template for **`secrets/model-credentials`** and stops: fill in the provider’s credentials there, as `KEY=value` lines (for Bedrock, `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, or none where the host gives the gateway a role; for the Claude API, `ANTHROPIC_API_KEY`). Only the gateway can read them. Run it again: it signs in to Atlantic’s registry with your deploy token, pulls the images, creates the product network and starts the stack. It prints the deployment’s **public key** and key id every time. For a new deployment, send that to Atlantic to register it (never the private key). The reader and the command channel connect within a minute of registration. The gateway’s **first budget** is set before its first call: `LIGHTHOUSE_FIRST_BUDGET_USD` in `.env`, $100 a month by default, only where no budget is set yet. A gateway with no budget refuses every call. Later budgets come from LightHouse (`budget.set`, once you switch it on) or the gateway’s own command. ### Check it ```sh ./lighthouse-check.sh # asks Octy about documents/welcome.md ./lighthouse-check.sh "a question your documents answer" ``` It checks that every container is running and healthy, that the two that run once finished cleanly, that the gateway has its budget, that the reader and the command channel hold their connections to LightHouse, and that Octy answers through the gateway **with citations**. With `AAL_KEY` (a viewer API key) and your tenant’s machine access token (`CF_ACCESS_CLIENT_ID`, `CF_ACCESS_CLIENT_SECRET`) in the environment, it also reads what LightHouse sees. It exits 0 only if every check passes. ### Without the product side If your product already runs its own gateway and database, take `product` out of `COMPOSE_PROFILES` in `.env`, and set the three store addresses there: `AAL_HANDLER_GATEWAY_STORE` (the command channel’s own user, which may change only what commands change), `AAL_READER_GATEWAY_STORE` and `AAL_TICK_GATEWAY_STORE` (read-only users). Then your gateway posts its records to `http://aal-relay:4319` on the network `AAL_PRODUCT_NETWORK` names. ### More settings | Setting | What it is | | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `COMPOSE_PROFILES` | What runs: your profile (`always` or `ondemand`), and `product` | | `AAL_DEPLOYMENT` | This deployment’s name as registered in LightHouse. It must match `deployment:` in `handler-commands.yaml`, or every command is refused | | `AAL_PRODUCT_NETWORK` | The network where your product’s gateway reaches the relay. The start script creates it | | `AAL_GATEWAY_URL` | The gateway, for the Token Value Benchmark’s schedule on the sync tick | | `HTTPS_PROXY`, `NO_PROXY` | Your proxy, if outbound traffic goes through one | | `SOCKET_PROXY_IMAGE`, `DOCKER_CLI_IMAGE` | Ephemeral profile only: pinned by digest in `.env` | | `DOCKER_GID` | Ephemeral profile on Docker: the start script finds it | | `CONTAINER_SOCKET`, `SOCKET_PROXY_USER` | Ephemeral profile on Podman: Podman’s socket, and `0:0`. See [Set up the host](#set-up-the-host) | Name every image in full, with its registry. Podman on RHEL and Fedora refuses a short name such as `docker:28.5.2-cli` when it cannot ask you which registry you meant. Docker accepts either form. The containers run as user 10001; the start script makes each secret file readable inside them and closes the directory to everyone else on the host. Where SELinux is enforcing, label the secrets once (see above). ## What it runs **Your own servers**: a Compose stack under Docker or Podman, wherever your servers are Way in - **Sign-in front door**, oauth2-proxy, off until you start it: people signed in by your identity provider your people, signed in Engine - **Gateway**, a container of your product's: the only container with a model credential - **Octy and your agents**, containers: answer from your documents, through the gateway - **Telemetry relay**, a lasting container: signs records; buffers on disk if LightHouse is unreachable - **Content reader**, a container · started every minute: answers reads signed by Atlantic - **Command channel**, a container: applies signed commands your policy allows - **Connector-schedule tick**, a container: every 15 minutes, syncs your sources model calls, from the gateway alone Models - **Self-hosted model**, vLLM or NVIDIA NIM, on your GPUs: optional; prompts never leave your machines - **A provider's API**, with your own key: for example the Claude API Kept on your servers - **Secrets**, secret files: the deployment key, the command and sealing keys - **Knowledge database**, PostgreSQL with pgvector: the gateway's store and your index - **Logs and buffers**, volumes: every content read; the relay's buffer One outbound path, through your firewall or proxy, over HTTPS - **Operational telemetry** (downward): counts, costs and timings from the relay, signed by your deployment. Never content - **Content, read in place** (both ways): a read signed by Atlantic, answered by your reader on the connection it opened - **Signed commands** (upward): pause, approve, set a cap: checked by your command channel against your policy **LightHouse**: your tenant, in Atlantic's account: intake, API, MCP and portal The Compose stack on your own servers. Nothing of Atlantic's listens on your network: the relay, the content reader and the command channel dial out to LightHouse. The sign-in front door is the only way in, and only when you start it. A self-hosted model keeps prompts and answers on your machines. - Docker - vLLM - NVIDIA (NVIDIA NIM) | Container | Compose profile | What it does | | ----------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `aal-relay` | both | Takes content-free records from your product’s gateway, signs them with the deployment’s key and sends them to LightHouse. It buffers on disk while LightHouse is unreachable. It runs under both profiles, because the gateway can post to it at any time | | `aal-content-reader` | `always` | The read-only content reader. It holds its connection to LightHouse and answers only reads signed with Atlantic’s reader key | | `aal-content-reader-ondemand` | `ondemand` | The same reader, run every minute. Each run connects for 50 seconds (`connect --window 50`), then exits. `up` also starts it once | | `aal-scheduler` | `ondemand` | The Docker CLI in a loop. It starts the reader by name, waits for it to finish, then waits 10 seconds, so the reader starts about once a minute and never runs twice at once. Under Podman it talks to Podman’s Docker-compatible API | | `aal-scheduler-proxy` | `ondemand` | The only container that mounts the runtime’s socket. It accepts connections from the scheduler only, and allows only ping, version, and starting and waiting on a container named `aal--*` | Every engine container runs as user 10001, with a read-only root file system, all capabilities dropped and no new privileges, and restarts unless you stop it. The gateway is your product’s own container, so the engine never holds model credentials. **The command channel, the connector-schedule tick and the sealing key are in the generated file**: the channel under both profiles, a container that runs the tick every 15 minutes, the command key and sealing key as secrets, and the connector store in the channel’s volume. A new file beside `compose.yaml`, `handler-commands.yaml`, is your deployment’s policy, with every command type off until you switch it on. The always-on file still mounts no socket. ### The sign-in front door The generated file also holds the sign-in front door, as a Compose profile (`front-door`) that is off until you start it. It is oauth2-proxy in front of your product’s interface, signing people in through your own OpenID Connect identity provider, so the interface is reachable only by people your provider admits. Use it when your product’s interface runs beside the stack. Its four secret files, and how to make them, are in the setup comments at the top of the generated file. Start it with `--profile front-door`. Inbound port 443 is open to the front door only; nothing else listens. ### The settings it sets | Setting | On | Value | | -------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `AAL_LIGHTHOUSE_URL`, `AAL_CONTROL_PLANE_URL` | relay, reader | LightHouse’s intake address, filled in for you. Both names are set, because earlier engines read the second | | `AAL_LIGHTHOUSE_KEY_FILE`, `AAL_CONTROL_PLANE_KEY_FILE` | relay, reader | The deployment key’s secret file, under both names | | `AAL_DEPLOYMENT` | relay, reader | `/` | | `AAL_RELAY_LISTEN`, `AAL_TELEMETRY_BUFFER_DIR` | relay | `0.0.0.0:4319`, reachable on the deployment’s networks only; the buffer volume | | `AAL_READER_AAL_PUBLIC_KEY_FILE`, `AAL_READER_LOG_DIR` | reader | Atlantic’s reader key; where the reader logs every read, on its own volume | | `AAL_READER_KNOWLEDGE_DB`, `AAL_READER_GATEWAY_STORE` | reader | From `.env`; without them, the bundle’s database as the reader’s own read-only user, its password read from `secrets/` at start | | `AAL_DEPLOYMENT_PROFILE`, `AAL_CLOUD`, `AAL_REGION`, `AAL_COMPONENT` | relay, reader | The profile; `onprem`; `onprem`; `relay` or `reader` | ### A file that does not set the contract revision The generated file tells each of the engine’s containers which contract revision LightHouse accepts, and gives the reader a writable buffer for its own records. A file that sets neither leaves each container on the engine’s default revision, so it holds back every newer record: the deployment’s profile and its sources’ sync schedules never reach LightHouse. With such a file, add a `compose.override.yaml` beside it, with the revision your LightHouse serves (`contract_revision` in the answer to `GET /api/v1/me`): ```yaml x-revision: &revision AAL_LIGHTHOUSE_REVISION: "1.34" AAL_CONTROL_PLANE_REVISION: "1.34" services: aal-relay: {environment: *revision} aal-sync-tick: {environment: *revision} aal-handler: {environment: *revision} aal-content-reader: environment: <<: *revision AAL_TELEMETRY_BUFFER_DIR: /tmp/aal-telemetry ``` ## Your product’s side: the gateway, the knowledge database and Octy Under the Compose profile `product`, the bundle runs the parts that do the work: | Container | What it does | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `knowledge-db` | PostgreSQL with pgvector: the gateway’s store (database `gateway`) and Octy’s index (database `knowledge`). Its first start makes the second database and a user for each part | | `gateway-setup` | Runs once at every start, then exits: makes the gateway’s tables, gives each database user its rights, and sets the first budget where none is set | | `gateway` | The model gateway: the only container with a model credential, the budgets, the allow-list and prices, the kill switch. It reaches the provider over `edge` | | `octy-index` | Runs once at every start: indexes `documents/` into the knowledge database. Unchanged documents are skipped. After adding some, `docker compose run --rm octy-index` | | `octy` | Octy, answering your people from your documents through the gateway, with citations, signed in by your identity provider | Each runs hardened like the rest; PostgreSQL keeps only the five capabilities it needs to own its volume. **Nothing listens on your network**: Octy answers on the product network at `http://octy:8095`. Publish her through your own front door, or the sign-in front door above (`FRONT_DOOR_UPSTREAM=http://octy:8095`). **Sources and their labels.** Each document in `documents/` gives `doc_class: internal` or `public` in its front matter. The sync tick reads `catalogs/knowledge.yaml`: one card per source, as in [In code](/build/code/). The tick files every document under the label its card gives, and quarantines a label the engine’s default vocabulary does not know. A source starts with its schedule off, and nothing syncs until someone chooses. For a source connected in LightHouse, **Sync now** and a schedule on its connection’s card (**Setup and admin → Connectors**, a client administrator signed in as a person) reach the tick through the command channel, once `connector.sync` and `connector.schedule` are switched on in `handler-commands.yaml`; the tick runs it at its next quarter-hour. ### What LightHouse sees With a viewer API key and your tenant’s machine access token (see the [Quickstart](/start/quickstart/)), or `lighthouse-check.sh` with both in the environment: | Call | What it shows once the stack is up | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `GET /api/v1/me` | `tier_b.connected: true` and `reachable: true`: the content reader holds its connection and Atlantic’s current key | | `GET /api/v1/deployments/profiles` | Your deployment with profile, `cloud: onprem`, and its components (relay, reader, handler, gateway) | | `GET /api/v1/health` | Each component’s last state, and each source’s last pull | | `GET /api/v1/usage` | Calls, tokens and estimated cost, after the first model call through the gateway | In the first runs on Docker, the reader and the command channel connected within a minute of registration, and records from the gateway arrived within a minute of its first call. ## Permissions There is no cloud identity. What each container can reach is set by its networks and its secrets: - **Secrets**: the two files above, mounted as Compose secrets and never passed as settings. - **Networks**: `edge`, the only way out, to LightHouse (and your proxy); your product’s existing network, where its gateway reaches the relay; and `scheduler`, an internal network with no route out, used only by the scheduler and its socket proxy. - **The runtime’s socket**: only the socket proxy mounts it. Mounting the socket read-only does not make the API read-only; the proxy’s allowlist is what does. The proxy refuses container IDs, any container name outside `aal--*`, creating containers, exec, images, volumes and networks. Atlantic has checked these refusals against Docker, and against Podman in rootless and rootful mode. ## Hardware and network requirements - **Network**: outbound HTTPS and WebSocket on port 443 to LightHouse’s intake address. `HTTPS_PROXY` and `NO_PROXY` are honoured. With no outbound path at all, see [Air-gapped operation](#air-gapped-operation). - **Hardware**: see the table below. ### Hardware requirements What LightHouse’s containers need on your own machines, beside your product’s own stack (its database, gateway and interface). Either deployment profile, Docker or Podman, x86-64 or arm64. | | Minimum | Recommended | | ------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------- | | CPU | 2 vCPU | 4 vCPU | | Memory | 2 GiB | 4 GiB | | Disk | 10 GiB free | 20 GiB free, SSD | | Network | Outbound HTTPS (443) to LightHouse’s intake address and your identity provider; inbound 443 to the sign-in front door only | The same | **How we measured it.** On 6 November 2026, with Docker on an 8-vCPU, 8 GiB Linux VM: five minutes idle, then five minutes at 3,000 telemetry records a minute (a busy gateway), with LightHouse unreachable on purpose so the telemetry buffer filled and the reader and command channel kept reconnecting. LightHouse’s containers together peaked at 98 MiB of memory under the always-on profile and 152 MiB under the ephemeral profile (its schedulers cost about 50 MiB more), and averaged under a tenth of one CPU core, with brief bursts of up to one core while reconnecting. The minimum adds room for the operating system, the container runtime and the images; the recommended figures keep the host under half its memory with the buffer full and a sync indexing. You can run the same measurement on your own host with `scripts/measure-onprem.sh` in the infrastructure package. | Volume | Grows with | Size | | --------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `buffer` | Records held while LightHouse cannot be reached: about 0.8 MiB a minute at 3,000 records a minute (measured) | Capped: 512 MiB in the example settings (about 11 hours at that rate), 64 MiB if you set no cap. The oldest is dropped first | | `reads` | One line per read Atlantic makes, about 300 bytes | About 110 MB a year at 1,000 reads a day. Nothing rotates it | | `commands` | One line per command, plus sealed connector credentials | Under 50 MB a year for most deployments | | Knowledge index | Your synced documents, in your knowledge database (PostgreSQL with pgvector) | Measured at 7.5 KiB a chunk with the default embedding, 17.6 KiB with a 1,024-wide one: about 75 MB per 10,000 chunks (roughly 1,000 ten-page documents) | A self-hosted model needs its own hardware: see [Self-hosted models](#self-hosted-models). ## Self-hosted models You can run an open-weight model on your own NVIDIA GPUs and have the gateway call it, so prompts and answers never leave your machines. It is optional and off by default. The model is served by vLLM by default (Qwen3-8B, under the Apache 2.0 licence, unless you choose another), with an OpenAI-compatible API, as the `aal-inference` service in the generated file. It publishes no port, answers only on your product’s network, and refuses any caller without the key your gateway sends. 1. **Prepare the GPU.** Install NVIDIA’s driver, and either the NVIDIA Container Toolkit (Docker) or a CDI specification (Podman: `nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml`). 2. **Set the key.** Put `AAL_INFERENCE_KEY` (32 or more random characters) in `.env`. You can also set the model (`AAL_LOCAL_MODEL`) and the name it is served under (`AAL_LOCAL_MODEL_NAME`). 3. **Start it.** Use `--profile inference` with Docker, which reserves the GPU as a device, or `--profile inference-cdi` with Podman, which uses the CDI device `nvidia.com/gpu=all`. The first start downloads the weights into the `models` volume. Then set `AAL_INFERENCE_OFFLINE=1` and the container needs no outbound access at all. 4. **Point the gateway at it.** Merge the generated `gateway-local-model.yaml` into your gateway’s policy, and set the gateway’s `openai-compatible` backend and `AAL_INFERENCE_URL` to the service. The policy entry allows the model for the most sensitive tier of data (S4), prices it at zero unless you price your hardware, and reports it to LightHouse as running on premises. LightHouse’s model picker then offers it on premises. A model whose every stated place is `onprem` meets every residency rule in the model picker, because its data never leaves your own machines: it is wherever those machines are, and you hold them to the rule. Only an on-premises deployment can offer such a model. See [Regions](/data-sovereignty/regions/). ### NVIDIA NIM instead of vLLM NVIDIA NIM serves the same API. It needs your own NVIDIA AI Enterprise licence and NGC API key; Atlantic supplies neither. With them, a `compose.override.yaml` replaces the image of `aal-inference` with the NIM image, pinned by digest, and gives it the key from your `.env`. The gateway’s settings do not change, except that the model’s name in the policy is the one NIM serves. ### Hardware for a model These figures are estimates derived from the model’s size, not measured. A model needs its weights (2 bytes a parameter at 16-bit precision) plus working memory for the context and the calls in flight. | | Minimum | Recommended | | --------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------ | | GPU (Qwen3-8B, the default) | One NVIDIA GPU with 24 GB (L4, A10, RTX 4090), Ampere or later | One with 48 GB (L40S, RTX 6000 Ada), for more calls at once and the full 32k context | | Host memory | 32 GiB | 64 GiB | | Shared memory | 8 GiB | 8 GiB | | Disk for the weights | 40 GiB | 100 GiB, SSD | | CPU | 8 cores | 16 cores | A larger model scales with its weights: a 70B model needs about 140 GB of GPU memory, so two 80 GB GPUs. Measure the model on your own evaluation set before you buy hardware for it. ## Air-gapped operation A deployment runs in one of two network modes. Set the mode on the relay with `AAL_TELEMETRY_MODE`. | | `outbound-proxy` | `offline` | | --------------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | Network | One outbound path, through your proxy, to LightHouse’s intake address on port 443 | No path to LightHouse | | Telemetry | Sent live by the relay, signed, through the proxy | Signed and numbered as if sent, kept on disk, and carried across as bundle files | | Reading your content in place from LightHouse | Available | Not available | | Commands from LightHouse | Live, over the command channel | By signed command file | | What LightHouse shows | Live | Up to the last bundle imported | | Setting | `AAL_TELEMETRY_MODE=outbound-proxy` (or unset), with `HTTPS_PROXY` and `NO_PROXY` | `AAL_TELEMETRY_MODE=offline` on the relay | ### `outbound-proxy` The relay, the content reader and the command channel read the standard proxy settings (`HTTPS_PROXY`, `NO_PROXY`) and tunnel TLS through the proxy with `CONNECT`. Allow one host, LightHouse’s intake address as **Get my stack** fills it in, on port 443. TLS is end to end: the proxy sees the host name and the volume, never a record, a read or a command. A proxy that terminates TLS breaks the signed handshakes of the reader and the command channel and is not supported, so pass the intake address through untouched. `AAL_TELEMETRY_MODE=outbound-proxy` changes no behaviour; it records in the deployment’s settings how the deployment is connected. An unknown mode is refused: telemetry stays off and the log says so. Model calls go wherever your gateway’s policy routes them, which is separate from this setting. A deployment with no outbound path at all needs a model it can reach locally, such as a [self-hosted model](#self-hosted-models). **Your network**: the engine on your own servers - **Relay**: sends signed telemetry live - **Content reader**: holds its connection, for reads in place - **Command channel**: receives signed commands live - **Gateway**: model calls go where your policy routes them, separately Your proxy: one host allowed, TLS end to end - **Telemetry** (downward): live, signed by your deployment - **Reads in place** (both ways): available, as on any cloud - **Commands** (upward): live, over the command channel **LightHouse**: your tenant, in Atlantic's account - **Intake**: checks each signature; shows your deployment live With outbound-proxy, the deployment is connected through one allowed path. Your proxy sees the host name and the volume, never a record, a read or a command. A proxy that terminates TLS is not supported. ### `offline` The relay sends nothing and opens no connection to LightHouse. Each batch it would have sent is signed exactly as the live send would have been, numbered in the deployment’s sequence, and kept in a spool on disk. The relay seals new batches into bundle files at intervals, and an operator carries the files to a machine that can reach LightHouse and imports them. Commands travel the other way in a signed command file. - **Relay**: in your air-gapped network - **Command handler**: in your air-gapped network - **Operator**: carries files by your approved means - **LightHouse**: your tenant, from a connected machine Telemetry out 1. Relay: **Sign, number and keep**. each batch signed as a live send would be, numbered in the deployment's sequence, kept on disk 2. Relay to Operator: **Export and verify**. bundles of every batch after the last one LightHouse holds, each checked as LightHouse will check it 3. Operator to LightHouse: **Carry and import**. signatures, manifest and sequence checked, then stored through the live intake Commands in 4. LightHouse to Operator: **Export the command file**. every command waiting for the deployment, as signed frames, each exported once 5. Operator to Command handler: **Carry and apply**. Atlantic's signature, the expiry, replay and your policy, checked as on the channel Results back 6. Command handler to Operator: **Write the results**. each answer signed with the deployment's key 7. Operator to LightHouse: **Import the results**. each answer verified, then applied as a live one Nothing crosses the gap by network. Bundles carry signed telemetry to LightHouse; a command file carries signed commands back; a results file carries the signed answers to LightHouse. Each file is checked on arrival, so the person who carries it does not need to be trusted. The relay in offline mode must run as a lasting service with a disk that survives a restart, because the spool is on that disk. It refuses to run as a job’s sidecar. On your own servers the relay already runs as a lasting container under both Compose profiles. **Settings on the relay:** | Setting | Default | What | | -------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `AAL_TELEMETRY_MODE` | `online` | `offline` | | `AAL_DEPLOYMENT`, `AAL_LIGHTHOUSE_KEY_FILE` | None | As online. `AAL_LIGHTHOUSE_URL` is not needed, and is not used if set | | `AAL_LIGHTHOUSE_REVISION` | As online | The contract revision of the LightHouse that will import the bundles. Anything newer is held back, as online | | `AAL_TELEMETRY_OFFLINE_DIR` | `offline` in the relay’s buffer directory | The spool, on a disk that survives a restart | | `AAL_TELEMETRY_OFFLINE_MAX_BYTES`, `AAL_TELEMETRY_OFFLINE_MAX_AGE_S` | 1 GiB, 90 days | The spool’s limits. A batch dropped over a limit shows in LightHouse as a gap | | `AAL_TELEMETRY_BUNDLE_ROTATE_S`, `AAL_TELEMETRY_BUNDLE_ROTATE_BYTES` | 1 hour, 16 MiB | How often the relay seals a bundle, or sooner at this size | **Settings in the command handler’s policy** (`handler-commands.yaml`). Command files are off until you turn them on: ```yaml command_files: enabled: true # default false: every file is refused max_ttl_s: 86400 # the longest lifetime a command in a file may have: 900 seconds to 7 days; default a day ``` Every command type stays off until your policy enables it, as on the channel. ### What works offline | | Offline | | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | Agents, schedules, the model gateway, budgets, caps, the kill switch and guardrails | Unchanged: they run in the deployment | | Usage, cost, runs and health in LightHouse | Delayed: up to the last bundle imported | | Live views, such as a run while it runs or a deployment’s wake | Not live: the records arrive with the bundle, as history | | Alerts LightHouse raises from telemetry | Raised when a bundle is imported, not when the event happened | | Approvals managed in LightHouse | By command file: a decision made in LightHouse arrives with the next file. Break-glass, where your policy allows it, is unchanged | | Commands: pause, budgets, pre-approvals, approvals, releases and secrets | By command file, within your policy’s lifetime | | Connector credentials sealed in LightHouse | By command file, sealed to the deployment’s key as on the channel | | Reading your content in place from LightHouse | Not available: nothing can dial out, and nothing may dial in | Bundles carry operational telemetry only: the same counts, costs, timings, statuses and keyed hashes as a live deployment sends. Opt-in export is not part of offline mode. ### The operator’s routine Telemetry goes out in four steps: export, verify, carry and import. First, find where LightHouse is up to. 1. **Find where LightHouse is up to.** On a machine that reaches LightHouse: ```sh lighthouse-ai telemetry status --deployment ``` `held_through` is the highest batch number LightHouse holds with nothing missing below it. Any missing ranges are listed. 2. **Export.** Inside the air-gapped network, in the relay’s container: ```sh python -m aal_engine.telemetry export --since --out /path/to/bundles ``` It writes bundles of every batch after that number and prints a summary: the bundles written, the next number and any batch withheld. Bundles the relay sealed on its own schedule are also in the spool’s `bundles` directory; you can carry those instead. 3. **Verify.** Check each file as LightHouse will, before it leaves: ```sh python -m aal_engine.telemetry verify-bundle /path/to/bundles/.tar.gz ``` 4. **Carry** the files across by your own approved means. 5. **Import.** On the machine that reaches LightHouse: ```sh lighthouse-ai telemetry import .tar.gz ``` The deployment is read from the bundle unless you give `--deployment`. The answer shows what was stored, what LightHouse already held, and the new `held_through` for the next export. Commands come back in two steps. 1. **Export the command file.** On the machine that reaches LightHouse: ```sh lighthouse-ai commands export --deployment --out commands.json ``` The file holds every command waiting for the deployment, as signed frames. Each is marked delivered when the file is written, so a command is never exported twice. 2. **Apply it.** Carry the file across, then inside the air-gapped network, where the command handler runs: ```sh python -m aal_engine.handler apply-file commands.json --results answers.json ``` Each command is checked exactly as on the channel: Atlantic’s signature, the deployment, the issuer, the expiry, whether it has been applied before, your policy and every precondition. `--results` writes each answer signed with the deployment’s key. A command meant for a file is created with `delivery: "file"`. It may live 30 seconds to 7 days, a day by default, and is never sent down the command channel. A command made for the channel lives at most 15 minutes, so it is useful in a file only if the file is applied within that time. The command channel refuses any command that lives longer than 15 minutes. **Who may import and export.** A `client_admin`, as a person at the keyboard, or a signed-in tool whose token carries the `offline` scope (`lighthouse-ai login --scope "telemetry:read offline"`). A machine key cannot. Every import is in the audit log as `telemetry_bundle_imported`, every refused upload as `telemetry_bundle_refused` (with the refusal’s code and the file’s hash and size, nothing from inside it), and every command file as `command_file_exported`. ### How a bundle is trusted - **The deployment’s key signs everything that leaves.** Each batch carries the signature its live send would have carried, and the bundle’s manifest is signed by the same key. LightHouse refuses a bundle signed by another deployment’s key or naming another deployment. - **The sequence replaces the clock.** A carried bundle is old by design, so its timestamps are not held to the live five-minute window. LightHouse refuses a bundle it already holds (`409 bundle_duplicate`), skips batches it already has, and refuses the whole bundle if a number it holds arrives with different contents (`409 sequence_conflict`). Each missing number is reported as a gap. Records keep their ids, so a record imported twice is stored once. - **The person who carries a file is not trusted.** Altering a batch, a manifest or a command breaks a signature; removing a batch shows as a gap; replaying one is a duplicate; and a command that waited too long has expired. - **The same checks as live.** Each new batch goes through the same intake and allow-list as live telemetry. Before writing a bundle, the relay checks every batch again and withholds any that fails, so a file edited in the spool cannot travel under the deployment’s signature. - **Limits.** A bundle upload is at most 48 MB, and 64 MB once decompressed. A larger export is split into several bundles. ### Command results import LightHouse imports the answers that `--results` writes and applies each answer as it applies a live answer: ```sh lighthouse-ai commands import-results answers.json ``` | Rule | Behaviour | | ------------ | -------------------------------------------------------------------------------------------------------------------- | | Verification | Every answer in the file is verified with the command channel’s own verification before any answer is applied | | Matching | Each answer must answer a command that LightHouse exported by file to that deployment | | Failure | One failed answer causes the whole file to be refused | | Duplicates | A file imported a second time is refused | | Status | Command statuses move forward only | | Audit | Each import and each refusal is recorded in the audit log as `command_results_imported` or `command_results_refused` | API: `POST /api/v1/deployments/{deployment}/command-results` performs the same import. `GET` on the same path lists the imports and the commands awaiting an answer. ### Offline site page In LightHouse, the card for each air-gapped deployment links to its **Offline site** page. The page shows the last bundle imported, the sequence with any missing batches, the `--since` value for the next export, the commands awaiting an answer, and every bundle and results import. A `client_admin` can upload a bundle or a results file and export a command file from this page as an alternative to the CLI. ## Images and models carried in by file A network without internet access cannot pull images or download models. Images and models are transferred as files, verified on the offline side before they are loaded, and run under the digests the stack pins. The tool is `aal_engine.mirror`, part of the engine; on the connected side, run it on a host where the engine is installed. It uses only the Python standard library and runs on an offline host that has Python and a container runtime without the engine. Each bundle includes a copy of the tool as `aal-mirror.py`. Use the copy supplied with the release. - **Connected host**: yours, with internet access - **Operator**: carries files by your approved means - **Offline host**: in your air-gapped network - **Your registry and model store**: in your air-gapped network 1. Connected host: **Pack the release**. images by digest with Atlantic's signatures and SBOMs, model weights with each file's checksum, and the signed release manifest 2. Connected host to Offline host: **Carry the bundles**. the verifier travels with them 3. Offline host: **Verify before anything loads**. every file against its manifest, Atlantic's images against their signatures, offline; one mismatch refuses the bundle 4. Offline host to Your registry and model store: **Load and install**. images pushed under the same digests; weights installed beside their manifest 5. Your registry and model store to Offline host: **Run at the pinned digests**. the stack pulls from your registry; models load from the mirror only A new release and its model weights carried into an air-gapped network as signed bundles, verified on the offline side before anything is loaded, and run at the same digests the stack pins. ### Images On a host with internet access, pack every image pinned in the stack’s `.env`: ```sh python -m aal_engine.mirror images pack --env .env --out images.tar ``` Every image in `.env` must be pinned by digest. An image referenced by tag only is refused. Atlantic’s images are first verified online against the identity of the release pipeline that signed them. Each image is then saved by digest with its signature and software bill of materials. Sigstore’s trusted root is packed with the images for offline signature verification. A manifest in the bundle lists every file with its SHA-256 and size. Transfer `images.tar` and the stack’s `.env` separately. On the offline side, with cosign 2.4 or later, run: ```sh python3 aal-mirror.py images verify images.tar --env .env --dir ./mirror python3 aal-mirror.py images load ./mirror --registry registry.internal:5000/aal python3 aal-mirror.py images env .env --registry registry.internal:5000/aal > .env.mirror ``` | Command | Behaviour | | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `verify` | Refuses the bundle and loads nothing if any file is missing, unlisted or altered; if an image’s digest differs from the digest pinned in `.env`; or if an Atlantic image fails its signature or bill-of-materials check against the packed trusted root. Third-party images (the identity proxy, the database, the model server) are checked by digest only | | `load` | Pushes each image to the client’s registry (Harbor, Artifactory or any OCI registry) under the same digest, with its signatures | | `env` | Writes a `.env` that points the stack at the client’s registry, with every digest unchanged. `compose.yaml` is the same file online and offline | ### Retrieval models Retrieval uses two small open-weight models: the embedding model and, when re-ranking is enabled, the re-ranker. In a connected deployment they are downloaded on first use. For an offline site, pack them on the connected side and install them on the offline side: ```sh python -m aal_engine.mirror models pack --out models.tar.gz # connected python3 aal-mirror.py models install models.tar.gz --dir /srv/aal/models # offline ``` `install` refuses any file the bundle does not list and any checksum that differs. It then unpacks the weights with their manifest. Set `AAL_MODELS_OFFLINE=1` and set the engine’s model directory to the install directory (the client documentation names the setting). The engine then verifies the files against the manifest before loading them. If a file is missing or changed, the engine refuses to load and does not download. The engine makes no outbound call for a model. ### Self-hosted model weights For [a self-hosted model](#self-hosted-models) on an offline site, download the weights on the connected side and transfer them with each file’s checksum: ```sh huggingface-cli download Qwen/Qwen3-8B --local-dir ./Qwen3-8B # connected python -m aal_engine.mirror weights pack ./Qwen3-8B --name Qwen/Qwen3-8B --out weights.tar python3 aal-mirror.py weights install weights.tar --dir onprem/weights # offline ``` `install` refuses an unlisted file, a missing file, a checksum that differs and a target directory that is not empty. The stack’s Compose file includes an offline profile of the model server. To enable it, add `inference-offline` (Docker) or `inference-offline-cdi` (Podman) to `COMPOSE_PROFILES` in `.env`. | Property | Offline model server | | -------- | ---------------------------------------------------------------------- | | Address | The same address as the online service; gateway settings are unchanged | | Network | The product network only, with no outbound network | | Weights | Loaded read-only from `AAL_LOCAL_MODEL_DIR` (default `onprem/weights`) | | Image | Pulled from the client’s registry | For an air-gapped deployment, **Get my stack** writes the offline profile into `.env`, with `AAL_MODELS_OFFLINE=1` and the model directories. ### Release verification offline Each engine release includes a **signed release manifest**, `release.json`. The manifest names every image of the release by digest, the retrieval models with each file’s checksum, the engine version, the LightHouse contract revision the release is built against, and the release notes. The same release pipeline signs the manifest, under the same identity as the images it names. Atlantic provides the manifest, its signature, the models bundle and the verifier with each release. The client packs `images.tar` on its connected host from the release’s `.env`, as described under [Images](#images). The transfer directory contains: | File | Content | | ------------------------------------------ | -------------------------------------------------------- | | `release.json` and `release.sigstore.json` | The manifest and its signature | | `images.tar` | The release’s images, packed as above | | `models.tar.gz` | Included only when the release changes a retrieval model | | `aal-mirror.py` | The verifier, as released | On the offline side, run: ```sh python3 aal-mirror.py release verify release-/ --dir ./mirror --installed python3 aal-mirror.py release verify release-/ --dir ./mirror --fresh --env .env # a first install ``` `release verify` checks the manifest’s signature offline against the packed trusted root, then checks every image and model against the manifest. It refuses the release and unpacks nothing if: - the manifest or its signature was altered, or was signed by an identity other than that version’s release pipeline; - an image is missing, has a different digest or belongs to another release; - a model file differs; - the release is older than the installed version, unless `--allow-downgrade` is passed. On success it prints the version, the signing identity, the contract revision and the release notes for the person who approves the upgrade. The client’s engineers decide when to apply the release: 1. Run `images load` and `images env`, as under [Images](#images). Result: the release’s images are in the client’s registry and a new `.env` points at them. 2. Run `models install` if the release includes `models.tar.gz`. Result: the retrieval models are installed with their manifest. 3. Run `docker compose up -d` (or `podman compose up -d`) with the new `.env`. Result: the stack runs the new release. The next telemetry bundle carries the new engine version, and LightHouse records the upgrade from it. The engine holds no licence key and performs no licence check. An air-gapped site does not depend on reaching a licence server. ## Regions The region is wherever your servers are. LightHouse records it as `onprem`. ## Deployment profiles On your own servers an idle container costs memory, not money, so always-on (Compose profile `always`) is a good default. Ephemeral (`ondemand`) frees memory and keeps no connection to Atlantic open between runs; a portal read then waits up to about a minute while the reader starts. The relay runs under both. There is no cloud bill to compare against, so LightHouse shows no estimated saving. Scheduled runs the `ondemand` containers with `AAL_WAKE_SCHEDULE` in `.env` set to the [wake window](/concepts/deployment-profiles/#the-wake-window); inside the window each run of the reader stays connected for its whole 50 seconds, so a read is answered at once, and outside it the stack behaves exactly as ephemeral. To switch, get the file again from LightHouse with the other profile, because each file holds only the profile you chose. Then run `compose down` and `compose up -d` with the new profile, using your runtime’s command. The volumes are kept, and with them the buffer and the read log. See [Deployment profiles](/concepts/deployment-profiles/). ## Upgrading and removing the stack - **Upgrade**: change each image’s digest in a reviewed change, then run `docker compose up -d` (or `podman compose up -d`). See [Upgrades](/operations/upgrades/). - **Remove**: run `docker compose --profile always --profile ondemand down` (or the same with `podman compose`). Then delete the `secrets/` directory and any volumes you no longer need: `buffer` holds records not yet sent, and `reads` holds the read log. ### Remove my stack LightHouse can generate the removal for you. As a client administrator, open **Setup and admin → Run → Remove my stack**. It gives you a step-by-step guide and a script, `lighthouse-removal.sh`, for this stack. The script runs on your machine and only when you run it: LightHouse never does, and nothing is removed automatically. 1. The script refuses to run until the variable `LIGHTHOUSE_REMOVE` names the deployment, so it cannot be run against the wrong one by accident. 2. It stops and removes the stack’s containers, then the secrets and the volumes you choose to delete. Records not yet sent (`buffer`) and the read log (`reads`) are lost with their volumes, so keep them first if your records policy asks you to. 3. The last step is yours, in LightHouse: deregister the deployment. You sign in as a person with a second factor, type the deployment’s name again and give a reason. LightHouse then refuses the deployment’s signatures from that moment, and records the deregistration in the audit log. Only Atlantic can reinstate it, within 30 days. Source: https://docs.atlanticagenticlabs.com/clouds/on-premises/ --- # Atlantic-hosted > The engine run for you by Atlantic: what that means for your data, regions and access. **Atlantic-hosted** means the engine runs in a dedicated AWS account in Atlantic’s AWS organisation, in the region you choose, managed and billed by Atlantic. It is the same engine and the same stack as [AWS](/clouds/aws/), run for you. ## How to ask for it 1. In LightHouse, **Setup and admin → Where agents run**, choose **Atlantic-hosted**, a region and a profile (ephemeral by default), and optionally a reason. 2. Choose **Ask Atlantic to host it**. Nothing is created yet: the request goes to Atlantic’s engineers. One request is open at a time; withdraw it to ask for a different region. 3. Atlantic approves or declines it. Once approved, an engineer creates the account and applies the stack; the request then shows **Provisioned**, and the deployment appears in LightHouse. By API, as a `client_admin`: `POST /api/v1/run-targets/hosted-requests` with `{"region": "eu-west-2", "profile": "ephemeral", "reason": "..."}`, `GET` to follow it, and `DELETE /api/v1/run-targets/hosted-requests/{rid}` to withdraw it. See the [Read reference](/api/reference/read/#post-hosted). LightHouse itself cannot create accounts: a person does, after approval. ## Where it runs, and whose account - A dedicated AWS account for your tenant, created in Atlantic’s organisation and placed under its guardrails. No other client shares it. - Atlantic’s organisation policies apply to it: it stays in the organisation, the audit trail cannot be turned off, and models are called only in the regions your contract names. - The account’s security baseline is applied before the stack. ## Regions and residency eu-west-1 (the default), eu-west-2, eu-central-1 and us-east-1. Everything the stack creates is pinned to the region you choose, as on [AWS](/clouds/aws/#regions). See [Residency by cloud](/data-sovereignty/residency-by-cloud/). ## Who can see what Your content is in that account, read in place, as in your own cloud. Atlantic’s engineers operate the account; what they may see of your content in LightHouse is still governed by your access rules. See [Who can see what](/data-sovereignty/access/). ## Cost Quoted as managed infrastructure: there is no cloud bill of yours to compare, so LightHouse shows no estimated saving for it. ## Moving to your own cloud later Choose your own cloud in **Where agents run** and apply its stack. Changing the choice moves nothing on its own: the hosted deployment keeps running until it is taken down, so you can move when the new one is ready. Source: https://docs.atlanticagenticlabs.com/clouds/atlantic-hosted/ --- # Build agents > Three ways to build an agent: from the library, with the builder, or in code. There are three ways to put an agent to work. Each ends in the same place: a card in your deployment’s catalogue, released through the same gate. | Way | When to use it | State | | ----------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------- | | [From the library](/build/library/) | A ready-made agent fits the job | Built: you request it in LightHouse; it reaches your deployment through a reviewed merge | | [With the builder](/build/builder/) | You want to describe the job in plain words | Built: Octy drafts the card, your deployment evaluates it on your own data, and a person approves it | | [In code](/build/code/) | Your engineers write the agent, or change one | Built: a card and a Python function, run by the engine’s orchestrator | 1. **Draft** (LightHouse or your code) : from the library, with the builder (Octy drafts the card), or in code: a card with its tools, budget, effect and autonomy 2. **Send to your deployment** (your account) : a builder draft is sealed to your deployment's key; your deployment checks and validates it Otherwise: invalid refused, with the checks that failed, in words 3. **Evaluate** (your account) : the golden set on your own knowledge base, and the pack's red-team cases; answer checks in code wherever they can be 4. **The release gate** (your account) : fixed floors, the worst check against the last release, an answer evaluation for every allowed model family; the decision is recorded in the release ledger Otherwise: gate not passed the version cannot be made current 5. **Publish** (LightHouse) : a person with a second factor approves; the version is made current by a signed command your deployment checks against its own ledger 6. **Run** (your account) : the orchestrator runs the card; outputs with an external effect wait for a person unless a pre-approval covers them; every step is on the run map 7. **Evidence and monitoring** (your account and LightHouse) : the online monitor samples live outputs and a scheduled golden-set run re-checks the released version; each release is reported to LightHouse Otherwise: a breach rolls back to the last version that passed; with none, the agent is stopped through the gateway's kill switch Each way of building an agent ends in the same gate. Nothing goes live because it was drafted: your deployment validates it, your own data evaluates it, and a person publishes it. ## What every agent has - **A card**: its tools, its budget, its effect and its autonomy. See [Agents](/concepts/agents/). - **Evaluations**: a golden set run before every release, and again against what is released. See [Evaluations](/build/evaluations/). - **Approvals**: a person signs off any output with an effect outside the run, unless a standing pre-approval covers it. See [Approvals](/build/approvals/). - **Versions**: only a version that passed the release gate can be made current, and a breach rolls back to the last version that passed. See [Versioning and rollback](/build/versioning/). - **A run map**: every step of every run, with its model, cost and sign-offs. See [The run map](/build/run-map/). Source: https://docs.atlanticagenticlabs.com/build/ --- # From the library > Add a ready-made agent from the library to your tenant. The library is the catalogue of ready-made agents your tenant can add. Adding one does not deploy it immediately. It raises a request, and the agent reaches your deployment through a reviewed merge and the release gate, so what runs is always the version that was tested. ## Browsing the library **Agents → Library** lists agents from three places: | Namespace | What it holds | | -------------------- | --------------------------------------------------------------------- | | `aal` | Atlantic’s own agents | | your tenant’s own | The agents your deployments already report | | `market/` | Agents other publishers list on the marketplace, approved by Atlantic | Each entry shows its card’s settings: purpose, triggers, tools, connectors, models, effect, autonomy, budget and timeout. An Atlantic card holds settings and a short purpose, and no code. Model prices and Atlantic’s margin are shown to your `client_admin`s; everyone else sees a relative cost tier. By API: `GET /api/v1/library` and `GET /api/v1/library/{namespace}/{name}`. By MCP: [`library`](/mcp/tools/library/). See the [Marketplace reference](/api/reference/marketplace/). ## Adding an agent You need the `client_admin` role, signed in as a person. 1. Open the agent and choose **Add to deployment**. 2. Optionally add a **Note for the engineers** (up to 500 characters). 3. Choose **Add to deployment (v…)**. The request is for the version shown on the button. 4. LightHouse records an **agent request**, writes it to your audit log and shows “Asked: request …”. Nothing runs until the agent is added to your catalogue and released. The request goes to your administrators and to Atlantic’s engineers. The card reaches your catalogue through a merge, and the agent runs once its version passes the release gate in your deployment. Follow it in `GET /api/v1/agent-requests`: `open`, `accepted`, `declined` or `done`. A machine key or an MCP client can read the library but cannot add to it (`403 person_required`), so an agent holding a key cannot add agents. The API route, `POST /api/v1/library/{namespace}/{name}/add`, also accepts an optional `deployment`; see the [Marketplace reference](/api/reference/marketplace/). ## What you can change Everything on the card is yours to set in your own catalogue: the tools, the model, the budget, the schedule, the autonomy (within your pack’s ceiling) and the approvers. Changing a card is changing code: it goes through review and the release gate like any other change. See [In code](/build/code/) and [Versioning and rollback](/build/versioning/). Source: https://docs.atlanticagenticlabs.com/build/library/ --- # With the builder > Build an agent in LightHouse without writing code: describe the job, review Octy's draft, evaluate it on your own data, and publish it after a person approves. In LightHouse™ you describe a job in plain words, and Octy™ drafts the agent’s card from the closest card in [the library](/build/library/): its instructions, tools, knowledge bases, guardrails, approvals and an evaluation set. You review the draft beside its template and send it to your deployment. There it is checked, and evaluated on **your own knowledge base** and on your pack’s red-team cases. You see the scores and an estimated cost. A person with a second factor then approves it, and it goes live through the same [release gate](/build/versioning/) as every other agent. Nothing goes live because Octy wrote it. Octy only drafts. Your deployment decides whether the draft is valid, your own data decides whether it works, and a person decides whether it is published. The minimum contract revision and engine are in the [compatibility reference](/concepts/telemetry-contract/#compatibility-reference). ## Before the first build Four things have to be on. A `client_admin` does the first; your engineers do the second and third. 1. **Your tenant’s command settings** (**Setup and admin → Commands**) switch on `card.propose`, `eval.run`, `card.publish` and `release.add`. The builder’s two new commands are off by default. See [Both sides must allow](/concepts/handlers/#both-sides-must-allow). 2. **Your deployment** allows the same four in its own command policy, and its pack takes built agents. In the pack’s catalogue: ```yaml builder: cards: /var/lib/aal/state/builder/research # a directory the handler may write tools: [search_knowledge, draft_document] # the only tools a built card may hold max_budget_usd: 5 # per run (default 5) min_recall: 0.6 # the evaluation's bar (default 0.6) min_questions: 3 # (default 3) ``` and in the deployment’s command policy: ```yaml commands: card.propose: {enabled: true, roles: [handler, client_admin]} card.publish: {enabled: true, roles: [client_admin]} eval.run: {enabled: true, roles: [handler, client_admin], max_cap_usd: "10.00"} release.add: {enabled: true, roles: [client_admin]} ``` The roles are your choice. A deployment that also names its gateway’s policy (`AAL_GATEWAY_POLICY`) can check a draft’s model against your residency rule. Without it, a draft that names a model is refused (`residency-unchecked`); a draft that leaves the model to the gateway is not. 3. **A sealing key.** LightHouse seals the draft to your deployment’s own key and only to a key the deployment announces, so it needs the sealing key and secrets store of [your own credential store](/connect/#turn-on-your-own-store). 4. **Octy is on** for your organisation. The draft is made by the assistant’s own model, under its caps and meter. `GET /api/v1/builder` (any `viewer`) says where each deployment stands: `sealing`, `propose`, `evaluate`, `publish`, `release`, and `ready` when all of them hold. Only a ready deployment is offered when you send a draft. When none is ready, **Agents → Build an agent** says “No deployment can take a built agent yet” and names what to switch on. ## Build an agent You need `handler` or above, signed in as a person. Everyone else on the tenant can follow the list of built agents but not build. 1. **Describe the job.** Open **Agents → Build an agent**. In **The job**, say in plain words what the agent does, for whom, from which documents, and what a person must check: 20 to 2,000 characters. Choose the **pack it joins** and **runs a month** (200 by default), and optionally a **template**; the default, *Octy chooses*, picks the closest card in the library. 2. **Draft it with Octy.** Octy makes one drafting call on the assistant’s escalation model. Nothing is kept except the meter’s row and an audit line carrying a hash of your description; LightHouse does not store the description itself. 3. **Review it beside its template.** The draft is shown field by field next to the template it started from, each marked *same as the template*, *added*, *changed* or *removed*: purpose, tools, approvals, budget per run, action, model, knowledge bases, instructions, what it must refuse, what it must never say, and its evaluation questions. A template holds settings, never words, so the instructions and questions are always new. Edit anything. Under **Approvals** you choose between *A named person approves each output* and *Draft only: nobody acts on it*. 4. **Name the document for each question.** The evaluation set needs **3 to 20 questions**, and each must name the document it should find, as it appears in your knowledge base. Octy cannot see your documents, so it leaves them blank. The page lists what is still to do and keeps **Send to my deployment** disabled until it is done. 5. **Send to my deployment**, with a reason. LightHouse seals the draft to your deployment’s own key. Your deployment opens it, checks it hashes to what was sent, validates it, and keeps it. LightHouse keeps ids and hashes only. The proposal moves from `proposing` to `proposed`, or to `invalid` with the checks that failed, in words. 6. **Evaluate on my data.** Set a cost cap (the default is $2.00) and give a reason. Your deployment runs the questions over your own index and your pack’s red-team cases on its scheduler’s next tick; the proposal is `evaluating` until the scores are in. Neither calls a model, so the estimated spend is $0.00. The cap is the most it may ever spend. 7. **Ask for publication**, once the proposal is `evaluated` and passed. A person is asked to approve. 8. **Approve and publish**, or **Reject**. See below. The proposal’s page shows its status in words, the checks your deployment ran, the scores, and the estimated cost. **Check again** refreshes a step still in flight. | Status | Means | | ------------------- | --------------------------------------------------------- | | `proposing` | Sent to your deployment, waiting for it to check the card | | `proposed` | Checked and kept by your deployment; ready to evaluate | | `invalid` | Your deployment refused the card | | `evaluating` | Evaluation and red-team cases queued in your deployment | | `evaluated` | Scores are in | | `publish_requested` | Waiting for a person to approve publication | | `publishing` | Approved; publishing in your deployment | | `published` | Published and live | | `rejected` | Rejected | | `failed` | A step did not complete; the reason is on the page | ### Approving Octy, a script and a key cannot take the approval step. It needs a person with `handler` or above of your own organisation, **signed in with a second factor**, at the portal. Atlantic’s staff, a delegated token and a machine key are all refused (`403 person_required`). A proposal is approved in LightHouse and nowhere else. Approving sends `card.publish` to your deployment, and then `release.add`, held back until the publish is applied, both as the person who approved. If you asked for publication yourself and approve it yourself, that is allowed and is recorded as **self-approval**. The decision, with its reason, shows on the proposal. Your deployment checks every rule again at publication, against the catalogue and policy as they are then. It refuses `gate-not-passed` unless the evaluation and red team passed there, and `evidence-changed` if the draft or version is not the one the approver was shown. ## What your deployment checks | Check | Refused as | Prevents | | -------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------- | | The draft’s shape, strictly | `card-invalid` (`draft-shape`, `card-shape`, the field) | A field you saw being dropped without a word | | The engine’s card schema, beside the pack’s cards | `card-invalid` (`schema`), `card-exists` | A card the catalogue would refuse at its next load | | Autonomy at most 1; no executor of code | `card-invalid` (`autonomy`) | Code, a command or a standing pre-approval through a form | | Tools only from `builder.tools`, none the pack denies | `card-invalid` (`tools-not-allowed`, `tool-denied`) | A tool you never offered to built agents | | Budget within `builder.max_budget_usd`; a data class | `card-invalid` (`budget`, `data-classes`) | An unbudgeted agent, or one nobody classified | | The pack’s Cedar policy with the card, self-tested | `card-invalid` (`cedar`) | A policy set that grants more than the cards say | | The model allowed for every data class; no global profile | `card-invalid` (`residency`, `residency-unchecked`) | Content sent where your tier forbids | | 3 to 20 questions, each naming its document, unique | `card-invalid` (`evals-too-few`, `evals-unreferenced`, `evals-duplicate`) | An evaluation that scores nothing | | At publication: evaluated, both passed, same draft and version | `gate-not-passed`, `evidence-changed` | Publishing what was not measured, or not what was approved | Each problem is shown in words on the proposal. ## What the scores mean The evaluation has two parts, and a proposal needs both to pass: - **Retrieval, on your index.** Each question is asked of your own knowledge base, and the deployment scores whether the document you named came back: mean recall, MRR, nDCG and top-1. The bar is the pack’s `min_recall`, 0.6 unless you set it. - **The red-team cases of your pack**, in five categories: prompt injection, data exfiltration, goal hijack, denied tools, and secret and personal-data leakage. They run with an attacker stub. A proposal that does not pass cannot be published (`409 not_evaluated`); draft it again. The scores reach LightHouse as `eval` records, `builder.retrieval` and `redteam.` for the card at the proposal’s version: counts and numbers only; the questions are not transmitted. ## The estimated cost Every proposal shows an estimated cost, from your deployment’s own price card, and says what it rests on: | `basis` | Meaning | | --------------- | ------------------------------------------------------------------------------------------- | | `price_card` | The price your deployment reports for the model the card names | | `dearest_model` | The dearest model your deployment reports, because the card leaves the model to the gateway | | `budget` | Capped at the card’s budget per run, where that is lower | | `no_price_card` | Your deployment has not reported a price for the model yet, so there is no figure | Per run, it counts the instructions at four characters a token, six passages of 400 tokens and a 200-token question in, and 800 tokens out. Per month, it is the per-run figure times the runs a month you expect. It is an estimate, `"estimated": true`, and it is not a limit: the card’s budget per run is. ## By API All under `/api/v1/builder`. The reads are any `viewer`’s. The writes are a person’s: a `handler` or above, signed in, and the approval also needs a second factor. A machine key is refused (`403 person_required`). | Route | Does | | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `GET /builder` | The templates (metadata only), the packs your deployments reported, each deployment’s readiness, your command settings for the four types, and the defaults | | `POST /builder/drafts` | Octy drafts a card: `{"job", "pack", "template"?, "runs_per_month"?, "deployment"?}` | | `POST /builder/proposals` | Send a draft to a deployment: `{"draft", "reason", "deployment"?, "runs_per_month"?, "job_sha256"?}`. Answers 202 with the proposal | | `GET /builder/proposals`, `GET /builder/proposals/{id}` | The proposals (`?status=` narrows), or one, with its checks, scores, estimate and the four commands | | `POST /builder/proposals/{id}/evaluate` | `{"cap_usd"?, "reason"}`. Sends `eval.run` for the proposal | | `POST /builder/proposals/{id}/publish-request` | `{"reason"}`. Only once the evaluation and every red-team category passed | | `POST /builder/proposals/{id}/approve`, `/reject` | `{"reason"}`. Approval sends `card.publish`, then `release.add` | Refusals: `422 draft_invalid` (the draft is out of shape, and the field is named), `503 draft_unavailable` (the model failed), `409 builder_unavailable` (the deployment announced no sealing key, or its policy does not switch `card.propose` on), `403 commands_disabled` (your tenant’s command settings do not), `409 not_evaluated`, and `403 person_required` or `403 role_required`. A draft is canonical JSON, at most 16 KiB: ```json { "format": 1, "pack": "research", "template": "aal/research.summary", "card": { "id": "supplier-digest", "purpose": "Drafts a weekly digest of supplier bulletins for operations.", "overseer": "Operations Lead", "budget_usd": 1.5, "data_classes": ["internal"], "tools": ["search_knowledge"], "effect": "external", "autonomy": 1, "knowledge": ["supplier-bulletins"] }, "instructions": "Read this week's supplier bulletins and draft a digest, citing each one.", "guardrails": { "refuse": ["negotiating prices"], "never_say": ["delivery is guaranteed"] }, "evals": { "questions": [ { "id": "drying-time", "question": "How long does drying a floor take?", "expect": ["supplier-bulletin-water"] }, { "id": "adjuster", "question": "When is a loss adjuster appointed?", "expect": ["water-claims-handling"] }, { "id": "fraud", "question": "Which signs suggest an inspection?", "expect": ["fraud-indicators"] } ], "k": 6, "channel": "hybrid" } } ``` The instructions are at most 8,000 characters. `expect` names the documents a question should find, as your index knows them. A walk through, from the control plane’s own tests with invented data (names changed; trimmed to the fields that matter). Drafting returns the draft, the template it started from and the estimate: **curl** ```bash curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/builder/drafts" \ -H "Cookie: CF_Authorization=$CF_AUTHORIZATION" \ -H "Content-Type: application/json" \ -d '{"job": "Every Monday, read the week'"'"'s supplier bulletins and draft a short digest for the operations team, citing each bulletin it uses.", "pack": "research", "runs_per_month": 200}' ``` **Python** ```python import os import httpx base = f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/builder" cookies = {"CF_Authorization": os.environ["CF_AUTHORIZATION"]} got = httpx.post(f"{base}/drafts", cookies=cookies, json={ "job": "Every Monday, read the week's supplier bulletins and draft a short " "digest for the operations team, citing each bulletin it uses.", "pack": "research", "runs_per_month": 200, }).json() print(got["draft"]["card"]["id"], got["estimate"]["per_month_usd"], got["estimate"]["basis"]) ``` **TypeScript** ```ts const base = `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/builder`; const headers = { Cookie: `CF_Authorization=${process.env.CF_AUTHORIZATION}`, "Content-Type": "application/json" }; const got = await ( await fetch(`${base}/drafts`, { method: "POST", headers, body: JSON.stringify({ job: "Every Monday, read the week's supplier bulletins and draft a short digest for the operations team, citing each bulletin it uses.", pack: "research", runs_per_month: 200, }), }) ).json(); console.log(got.draft.card.id, got.estimate.per_month_usd, got.estimate.basis); ``` ```json { "draft": { "format": 1, "pack": "research", "card": { "id": "every-monday-read-the", "…": "…" }, "…": "…" }, "template": { "id": "aal/coding.change-author", "…": "…" }, "estimate": { "estimated": true, "runs_per_month": 200, "tokens": { "input": 2659, "output": 800 }, "model": "eu.vendor.model-a", "per_run_usd": 0.019977, "per_month_usd": 4.0, "budget_usd": 10.0, "basis": "dearest_model" }, "job_sha256": "55d3ec7d2eee052925aa859c1cca7ab6936eb58f2b7557d5ef2773d7c154e568" } ``` That draft came from the test suite’s stub model, not Octy, so its card is a fixed one. What matters is the shape. Send the reviewed draft, then evaluate it, with the cap and the reason: ```bash curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/builder/proposals" \ -H "Cookie: CF_Authorization=$CF_AUTHORIZATION" -H "Content-Type: application/json" \ -d '{"draft": {…}, "reason": "a weekly digest", "runs_per_month": 4, "job_sha256": "55d3ec7d…"}' curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/builder/proposals/$ID/evaluate" \ -H "Cookie: CF_Authorization=$CF_AUTHORIZATION" -H "Content-Type: application/json" \ -d '{"cap_usd": "3.00", "reason": "before sign-off"}' ``` Asking for publication before the scores are in is refused: ```json { "error": "not_evaluated", "message": "the proposal has not passed its evaluation and its red team in your deployment" } ``` Once they are in, the request is accepted, and the proposal reads, abridged: ```json { "proposal_id": "371bbe02cb2e47efa7c0c7ec617348d9", "deployment": "example-prod", "pack": "research", "card": "supplier-digest", "agent": "research:supplier-digest", "status": "publish_requested", "version": "0123456789abcdef", "estimate": { "basis": "price_card", "model": "eu.vendor.model-a", "estimated": true, "budget_usd": 1.5, "per_run_usd": 0.019842, "per_month_usd": 0.08, "runs_per_month": 4 }, "evaluation": { "retrieval": { "passed": true, "metrics": { "mean_recall": 0.9, "mean_mrr": 0.8, "scorable": 3 } }, "redteam": { "injection": { "passed": true, "metrics": { "cases": 4, "passed": 4, "failed": 0 } }, "exfiltration": { "passed": true, "metrics": { "cases": 4, "passed": 4, "failed": 0 } }, "hijack": { "passed": true, "metrics": { "cases": 4, "passed": 4, "failed": 0 } }, "denied-tool": { "passed": true, "metrics": { "cases": 4, "passed": 4, "failed": 0 } }, "leakage": { "passed": true, "metrics": { "cases": 4, "passed": 4, "failed": 0 } } }, "passed": true }, "publish_request": { "requested_by": "ops@example.com", "reason": "ready for the team" }, "decision": null } ``` After `POST .../approve` the status is `publishing`, the `decision` is `{"decided_by": "ops@example.com", "reason": "reviewed the scores", "self_approved": true}`, and `commands.publish` and `commands.release` are `queued` until your deployment applies them. When both are `applied`, the status is `published`. ## From the CLI The CLI reads built agents and does not build them: drafting, sending, evaluating and approving are a person’s, at the portal, because approval needs a second factor that a delegated token never has. `lighthouse-ai builds` needs the `agents:read` scope. ```bash lighthouse-ai builds lighthouse-ai builds --status publish_requested lighthouse-ai builds show 5f0c00000000000000000000000000e1 lighthouse-ai builds --json | jq '.proposals[] | select(.status == "evaluated")' ``` ```text proposal agent status evaluation estimated / month 5f0c00000000 research:weekly-digest publish_requested passed (red team 1/1) $3.34 1 waiting for approval in the portal (Agents, then Build an agent) ``` `builds show ` takes the 32-character proposal id and prints the agent, status, deployment, version, template, problems, retrieval scores, evaluation result and the estimated cost per run and per month, then notes that costs are estimated from your deployment’s own price card. These two outputs are from the CLI’s own test fixtures, with invented data. ## What it records - **In your audit log**: `builder_draft` (the job’s hash only), `builder_proposed`, `builder_evaluation_requested`, `builder_publish_requested`, `builder_publish_approved` and `builder_publish_rejected`, each with who and why. - **A webhook**: asking for publication raises `approval.requested` with `kind: agent_publish`, the `proposal_id`, the `agent`, the `version` and the `deployment`. See [Webhooks](/api/webhooks/). - **In LightHouse**, a proposal keeps its ids, the SHA-256 of the job description and of the draft, the version and the codes of the checks your deployment answered, the estimate’s numbers, the four command ids, and who did what and when. It never keeps the purpose, instructions, guardrails or questions. It is erased at offboarding. - **In your deployment**, the draft itself, in its state directory. At publication the card is written into the pack’s builder directory, and the release ledger records the gate’s decision. - **What leaves your account**: the commands’ answers (codes, the version, each check’s outcome), the `eval` records, and the `release` record. The purpose, instructions, guardrails and questions do not leave it. ## Limits - A built agent can only **draft**, or wait for **a named person to approve each output**. It cannot run code or commands, and it cannot be given a standing pre-approval through a form. For a pre-approval, see [Approvals](/build/approvals/). - Its tools come only from the list your pack offers to built agents. Its budget per run stays within the pack’s limit. - The job is 20 to 2,000 characters; the draft at most 16 KiB; its instructions at most 8,000 characters; its evaluation set 3 to 20 questions. - It starts from a card in the library. A template holds settings and no wording. - The scores come from your own documents, so they are only as good as the documents you name. A question that names the wrong document fails, as it should. For a job the builder cannot express, write the agent with your engineers or with our certified forward-deployed engineers: [In code](/build/code/). Every agent, however it is made, passes the same [evaluations](/build/evaluations/) and [release gate](/build/versioning/). Source: https://docs.atlanticagenticlabs.com/build/builder/ --- # In code > Write an agent against the engine, in Python. An agent in code is a **card** in your pack’s catalogue and, for a `python` card, an async function. The engine’s orchestrator runs the cards in dependency order, each under its own card, and holds any output with an external effect for a person’s sign-off. The engine is Atlantic’s Python package `aal_engine`. It is delivered to your deployment as a versioned release, and published as signed container images ([The engine’s images](/clouds/on-premises/#the-engines-images)). A public Python package and SDK for the engine: \[Coming] ## The agent card in code A catalogue is a YAML file in your own repository. This one has two agents: `summary` counts notes and writes one line (an internal effect: it runs unattended); `publish` takes that line and would publish it (an external effect at autonomy 1: it waits for a person). ```yaml pack: research agents: - id: summary purpose: Count the notes in the inbox folder and write a one-line summary. executor: python target: research_agents:summary overseer: ops@example.com budget_usd: 1.00 effect: internal produces: out/summary-{run}.txt - id: publish purpose: Publish the summary to the team page. executor: python target: research_agents:publish overseer: ops@example.com budget_usd: 0.50 needs: [summary] effect: external autonomy: 1 produces: out/published-{run}.txt ``` `id`, `purpose`, `executor`, `overseer` and `budget_usd` are required. `produces` is the artefact that proves the agent ran: an agent that exits cleanly having written nothing has failed. For every field, see [Agents](/concepts/agents/#the-agent-card). ## The agent’s code A `python` card’s `target` is `module:function`, an async function that takes the agent’s context and returns an `Outcome`: ```python from pathlib import Path from aal_engine.orchestrator import AgentContext, Outcome async def summary(ctx: AgentContext) -> Outcome: notes = sorted(Path("inbox").glob("*.md")) out = ctx.artefact() out.parent.mkdir(parents=True, exist_ok=True) out.write_text(f"{len(notes)} notes in the inbox\n") return Outcome(note=f"{len(notes)} notes") async def publish(ctx: AgentContext) -> Outcome: out = ctx.artefact() out.parent.mkdir(parents=True, exist_ok=True) out.write_text(Path(ctx.inputs["summary"]).read_text()) return Outcome(note="ready to publish") ``` The context gives the agent its card, its run ID, its working directory, the artefacts of the cards it `needs` (`ctx.inputs`), and the model through the gateway (`await ctx.model(prompt)`), within the card’s budget. ## Tools and handlers - **Tools**: a card’s `tools` is the whole list; the executor grants nothing else, and a pack’s `deny_tools` are refused to every agent. With run tokens on, each tool call is checked against a Cedar policy generated from the card. See [The gateway](/concepts/gateway/#the-tool-gate). - **Handlers**: whoever decides on the `publish` output is a handler. In a deployment whose approvals are managed by LightHouse, the decision is made there and reaches the engine as a signed command. See [Handlers](/concepts/handlers/). ## Local runs ```python import json from pathlib import Path from aal_engine.catalog import load from aal_engine.orchestrator import Orchestrator orch = Orchestrator(load("catalog.yaml"), client="example", state_dir=Path("var/state"), workdir=Path(".")) state = orch.run("run-0001") print(json.dumps(orch.summary(state), indent=2)) ``` With two notes in `inbox/`, `PYTHONPATH=. python run.py` prints: ```json { "by_status": { "ok": [ "summary" ], "awaiting-approval": [ "publish" ] }, "failed_hard": [], "cost_usd": 0.0, "ok": true } ``` `publish` is waiting, not failed. Running `run-0001` again resumes it: an agent already done is not run again. Locally, with no LightHouse policy in force, a named person can decide in code: ```python orch.decide("run-0001", "publish", approve=True, by="ops@example.com") ``` In a deployment whose approvals are managed by LightHouse, that same call is refused (`approvals-managed-by-insights`): the decision is made in LightHouse. A source of knowledge is a card too, with the target `aal_engine.ingest.connector:run_card` and a `source` block. See [Connect your estate](/connect/upload/#connect-a-folder-in-code). ## Releasing 1. Merge the catalogue and code change into your deployment’s repository, reviewed. 2. Run the evaluations and the release gate on the new version. Only a version that passes can be made current. See [Evaluations](/build/evaluations/). 3. Make it current: a handler’s `release.add` command from LightHouse, or the release ledger in the deployment. See [Versioning and rollback](/build/versioning/). 4. Watch it in **Agents → Activity** and the [run map](/build/run-map/). Deploying from a command line is `lighthouse-ai agents deploy`, and a release gate in CI is `lighthouse-ai evals run --wait --fail-below`. See [Deploy and roll back](/cli/#deploy-and-roll-back). Source: https://docs.atlanticagenticlabs.com/build/code/ --- # Evaluations > How agents are evaluated before and after every release. Every agent is evaluated before it is released and again while it runs. An evaluation scores what the agent retrieves and what it writes against a **golden set**: questions or tasks with the answers or documents a good agent must find. ## Golden sets A golden set belongs to the pack. Each entry names what a good answer must find or mention, and what it must never claim. The engine scores: - **retrieval**: recall, precision, mean reciprocal rank and nDCG over the documents retrieved, and whether the right one came first; - **answers**: grounded (no invented citation), complete (every required point present), weak support, citation rate, and forbidden claims. Retrieval scoring calls no model, so it is deterministic and costs nothing. Answer checks are made in code wherever they can be: whether a cited passage was ever retrieved is a set-membership test, not a judgement. Where a statement’s support cannot be settled that way, an optional judge model decides it, called through your own gateway under a cost cap of its own; without a judge, those statements are left as the code-level check found them. The engine’s own retrieval is measured the same way, on invented golden sets of its own, on every engine release. ## The quality bar: the release gate The release gate turns an evaluation into one decision a release can be held to: 1. **Two fixed floors.** Any invented citation or forbidden claim blocks, whatever else improved. 2. **The worst check decides.** Each metric is compared with the last release on the same golden set; one that falls beyond the tolerance set in your policy blocks. 3. **No answer evaluation, no release.** Retrieval scores alone say nothing about what a model wrote. 4. **Every model family your policy allows needs its own passing answer evaluation**, so moving to another family is a measured change. 5. **The decision is recorded**, with every check, in the release ledger. ```bash python -m aal_engine.agent.gate --current retrieval.json --current answers.json \ --baseline last-release.json --policy gateway-policy.yaml --record decision.json ``` ## After release The **online monitor** samples live outputs (more often for higher autonomy and more sensitive data) and checks each in code: citations to passages never retrieved, and the pack’s stop rules. A scheduled re-run of the golden set against the released version feeds the same monitor. A breach rolls the agent back to the last version that passed. See [Versioning and rollback](/build/versioning/). ## Running evaluations on your own data Your golden set is built from your own documents and questions, and the evaluation runs in your deployment, against your own index. Nothing of it leaves your account except the scores. You run it by hand or on a schedule you set. ### Run one now A person with `handler` or above can run an agent’s evaluation once, from the **Run evaluation** button in the agent’s **Evaluations** section, from `POST /api/v1/agents/{agent_id}/evals`, or from the CLI: ```bash lighthouse-ai evals run research:summary --cap 5 --wait --fail-below 0.8 ``` - **A spend cap is required** (`--cap`, in US dollars). Your deployment checks it against its own policy’s ceiling. You can name one evaluation set with `--set`. - **It runs in your deployment**, at its next connector tick, once for each evaluation card, against your own index. Only the scores come back. - **Both sides must allow it**: your tenant’s command settings and your deployment’s policy must switch `eval.run` on. - **Who**: a person, or a delegated token with the `deploy` scope, signed as the person who approved it. Never a machine key. - **`--wait`** waits for the new results, and **`--fail-below N`** exits 1 when one did not pass or its metric is below N or missing, so a pipeline can gate a release on it. See [A release gate in CI](/cli/#a-release-gate-in-ci). ## Results in LightHouse - **Reinforcement → Evaluations and releases** shows each agent’s results and its releases. - `GET /api/v1/evals` (filter by `pack` and `family`) and `GET /api/v1/releases`: see the [Read reference](/api/reference/read/#evals). - MCP: [`evals`](/mcp/tools/evals/). Each result is an `eval` record: pack, agent, version, model family, suite, metrics and whether it passed. A record contains no question or answer. Source: https://docs.atlanticagenticlabs.com/build/evaluations/ --- # Approvals > Putting a person in the loop: where an agent must ask, and how it is enforced. An agent asks for a person whenever its output has an effect outside the run. Where it must ask is declared on its card, and enforced by the engine at run time, not by its prompt. ## Declaring approval points Two fields on the [card](/concepts/agents/#the-agent-card) decide it: ```yaml - id: publish effect: external # it sends, publishes or writes into one of your systems autonomy: 1 # a named person approves each output ``` | `effect` | `autonomy` | Behaviour | | ---------- | ---------- | ------------------------------------------------------------------------ | | `internal` | (ignored) | Runs unattended; writes only to the run’s own store | | `external` | `0` | A draft only. A card that `needs` it is refused when the catalogue loads | | `external` | `1` | Waits for a person to approve each output | | `external` | `2` | Goes ahead within a standing pre-approval; otherwise waits | `effect` defaults to `external` and `autonomy` to `1`, so a card that forgets to say is gated rather than free. A pack’s `ceiling` (1 by default, at most 2) can lower a card’s level and cannot raise it. ## Pre-approvals A card at level 2 declares the kind of action it performs and the parameters it reports for each one: ```yaml - id: send-reminder effect: external autonomy: 2 action: reminder.send action_params: [audience, template] ``` The catalogue names its `approvers`: the only people who may grant a pre-approval. A handler grants one in LightHouse (`preapproval.grant`) for that action, with constraints on the declared parameters, a daily and a total limit, and an expiry. When the agent would wait, the orchestrator looks for a live grant that covers it; if one does, the use is counted and the output approved at once, naming the grant and its approver. If none does, or the store cannot be read, it waits for a person. ### Manage pre-approvals in LightHouse Open the agent from **Agents → Hub**. For a level-2 (pre-approved) agent, the **Autonomy** card lists its grants. Each shows how much of its daily and total limit has been used, and when it expires. - On a live grant: **Adjust limits** (*Most a day*, *Most in total*) sends `preapproval.limits`, and **Revoke** sends `preapproval.revoke`. - On an expired or revoked grant: **Grant again** (*Until*, *Most a day*, *Most in total*) sends `preapproval.grant` for the same action. Every one of these needs a reason, and goes to your deployment as a command (see [Handlers](/concepts/handlers/)). The portal has no form for a first grant of a new action yet; send `preapproval.grant` with `POST /api/v1/agents/{agent_id}/commands` from a signed-in person’s session, with `action`, `expires_at`, `max_per_day`, `max_total` and `reason` (and optionally `allow`: up to 20 constraints on the declared parameters, each written `key=value[,value]`, for example `audience=internal`). See the [Handler commands reference](/api/reference/handler-commands/). Your deployment refuses a grant from anyone the catalogue does not name in `approvers` (`not-an-approver`), and one outside the limits its policy sets (`bounds`). ## Enforcement at run time, not in the prompt - The orchestrator decides whether an output waits, from the card. The model is never asked. - With approvals managed by LightHouse (the default for new deployments), the engine accepts a decision only as a command signed by LightHouse, from a person with a second factor. Any other route is refused and logged. - A decision carries the digest of the artefact the person saw; if it changed, the decision is refused. - If LightHouse cannot be reached, nothing is approved. See [Approvals](/concepts/approvals/) and [Handlers](/concepts/handlers/). Source: https://docs.atlanticagenticlabs.com/build/approvals/ --- # Versioning and rollback > Every agent is versioned; any release can be rolled back. Every agent has versions, and the **release ledger** in your deployment records each one: its gate decision, whether it passed, and which version is current. Only a version that passed its evaluations can be made current, and a rollback always goes to the last version that passed, never just the previous one. ## Versions and releases - A version is recorded with its gate decision and the digest of what was built. - **Promote** makes a passed version current. A version that did not pass cannot be promoted. - The orchestrator can require the ledger: then a card whose current version is not a released one does not run. From LightHouse, a handler makes a released version current with the `release.add` command; the engine refuses it (`gate-not-passed`) unless that version passed the gate in your deployment. See [Handlers](/concepts/handlers/). **From the CLI** (`lighthouse-ai agents deploy`), a token with the `deploy` scope makes the same change. A version that passed its gate goes live at once, as the person who approved the token, when your tenant’s settings and your deployment’s policy allow `release.add`. Any other version waits as a **deploy request**: a person with `handler` or above approves or rejects it on **Deployments** in LightHouse, with a reason and their second factor, and it expires after 72 hours. Your deployment still refuses a version its own ledger has not passed. See [Deploy and roll back](/cli/#deploy-and-roll-back). In the deployment, the ledger’s own commands: ```bash python -m aal_engine.assurance --ledger var/release-ledger.sqlite record --decision decision.json --by ops@example.com python -m aal_engine.assurance --ledger var/release-ledger.sqlite promote --by ops@example.com python -m aal_engine.assurance --ledger var/release-ledger.sqlite status ``` ## Rolling back - **Automatically**: when the online monitor or a scheduled golden-set run finds a breach, the agent rolls back to the last version that passed its evaluations. With no passed version to return to, the agent is stopped through the gateway’s kill switch. - **By hand**: `python -m aal_engine.assurance --ledger var/release-ledger.sqlite rollback --by ops@example.com --reason "..."`, or `release.add` with the earlier version from LightHouse. **From a command line**: `lighthouse-ai agents rollback ` returns to the last version that passed before the current one, or to `--to `. It needs a delegated token with the `deploy` scope. Where your deployment’s policy or your tenant’s settings do not allow it to go live directly, the rollback waits as a deploy request for a person to approve in LightHouse. See [Deploy and roll back](/cli/#deploy-and-roll-back). ## What is kept Every version, every gate decision and every promotion and rollback stays in the ledger. Each release is also reported to LightHouse as a `release` record (pack, agent, version, digest, whether it passed the gate): see `GET /api/v1/releases` and **Reinforcement → Evaluations and releases**. Source: https://docs.atlanticagenticlabs.com/build/versioning/ --- # The run map > See every step of a run: the model, the tools, the evidence, the cost and the sign-offs. The run map draws one run as a tree: every step and sub-agent in order, each annotated with the model it used, its tokens, its cost, its time, its searches and the strength of its evidence, and where it waited for a sign-off. ## Reading the run map Open a run from **Agents → Activity** or **Insights → Runs**. - **The tree**: the run at the root, then each agent, then each step: model calls, tool calls, searches, approvals, grounding and screening checks, and deliveries. - **Per node**: status (`ok`, `error`, `running`), duration, model, input and output tokens, cost, and counts in and out. - **Searches**: how many, the passages returned, the tokens sent and the tokens not sent. - **Evidence**: claims, the share at the ladder’s strong tiers, and the share uncited. See [Evidence](/concepts/evidence/). - **Sign-offs**: a step waiting for a person stays in **Active now**; it is not stalled. A model call is placed under the step that was open when it ended. A call that fits no step stays on the run’s own node and is counted and is not assigned to a sibling. The map is counts, timings and identifiers only. It holds no prompt, answer or document text. ## The router’s explanation per step Open a step and its panel says how its model was chosen: the router’s mode (`route`, `pinned`, `off` or `fallback`), the reason, and a plain sentence, for each of the step’s calls. Where the router was off, the sentence says which model it would have chosen. Where a failed check escalated the step, it names the model the step was re-run on. Each step carries at most 20 decisions. A decision whose step is not on the map is shown on the run’s own node. In the API, each node of `GET /api/v1/runs/{run_id_hash}/map` carries a `routing` object: its `count`, how many `escalated`, and the `decisions`. See [The model router](/router/). ## In the API `GET /api/v1/runs/{run_id_hash}/map` returns the same tree. For runs in progress, `GET /api/v1/runs/active` sends an `ETag` that leaves out the clock, so a page polling every few seconds gets `304 Not Modified` until something happened, and `GET /api/v1/runs/active/stream` streams them. See [Run Map](/api/reference/read/#run-map), and the MCP tool [`run_map`](/mcp/tools/run-map/). ## Sharing a run Share the run’s address in LightHouse: anyone in your tenant with access can open it. A link outside your tenant does not open. To share a run with someone outside LightHouse, export it. ## Export a run An export is a content-free record of one run, as a file you can forward or keep: **PDF**, a branded record to share or file, or **JSON**, the same record for scripts and other systems. - **Portal**: on the run’s page, choose **Export**, then **PDF** or **JSON**. - **API**: `GET /api/v1/runs/{run_id_hash}/export?format=json` (the default) or `?format=pdf`. The file is sent as an attachment named `run-.json` or `.pdf`, and is not cached. - **CLI**: `lighthouse-ai runs export [--format json|pdf] [-o ]`. The file is written exactly as sent. `-o -` writes to standard output, and `-o ` writes the default name inside that directory. - **MCP**: the read tool `run_export` returns the JSON document. Who can export is who can open the run map: `viewer` and above, and a machine key. A signed-in tool needs the `agents:read` scope. Another tenant’s run, like a run that does not exist, answers `404`. Every export is recorded in your audit log as **Run exported** (`run_exported`), with who asked, the run, the format and whether it came through the API or MCP. A refused export writes nothing. ### What it contains - The run and deployment identifiers, the agent, the status, when it started and finished, and how it was triggered. - The steps, in the run map’s order, with each step’s timing, model, tokens, cost and retries. - The agents, the models with their provider, and the tools by name, with calls and errors. - Timings and the critical path, the slowest and most expensive steps, and token and call totals. - Cost in US dollars and in the viewer’s display currency, each call converted at the European Central Bank’s rate for its own day. Estimated figures are marked as estimated. - The outcome, the approval steps and any break-glass decisions. - Guardrail refusals by label, model errors by class, and screening and grounding counts. Times are ISO 8601 in UTC, with the viewer’s time zone named. The PDF carries your organisation’s logo, name and colour from your branding. ### What it never contains Prompts, outputs, retrieved passages, tool arguments and tool results are never in an export, and the document lists them under `excludes`. Every value is checked again against the same allow-list that LightHouse’s intake uses, and a value that would not pass is left empty. The finished document is then checked as a whole: every text value must be an identifier, a code or a time, or nothing is sent and the export fails. Nothing is read from your account’s content. Source: https://docs.atlanticagenticlabs.com/build/run-map/ --- # Security > Every control: what it is, where it is enforced, and how you can verify it yourself. This section is written for the person who signs off on LightHouse: a security architect, a reviewer or an engineer. Each control is described the same way: - **What it is.** One or two sentences. - **Where it is enforced.** The component that refuses, and whether it sits in your account or in Atlantic’s. - **How to verify it.** A request you can send, a header you can inspect, or a record you can read in your own audit log. Anything not built yet is marked \[Coming], with no date. ## The design in one paragraph The engine runs in your account and holds your content. LightHouse runs in Atlantic’s account and holds operational telemetry: counts, costs and timings only; content is not transmitted. When a person in LightHouse needs to see content, it is read in place from your account and shown to them, not copied. Every connection between the two is opened from your side, and every message across it is signed. The [architecture page](/security/architecture/) draws this boundary. ## The controls at a glance | Control | Enforced in | Verify it with | | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------- | | [Sign-in through your identity provider, MFA required](/security/api/#people-sign-in-through-your-identity-provider) | The edge and the LightHouse service | `GET /api/v1/me` shows how your second factor was proved | | [Machine keys: read only, one tenant, 365 days at most](/security/api/#machines-a-key-and-a-service-token) | LightHouse service | A key at another tenant’s host answers `401` | | [Tenant isolation by row-level security](/security/api/#tenant-isolation-in-the-database) | The database | Every query runs under your tenant’s scope; nothing names a tenant in a parameter | | [Writes audited](/security/api/#every-write-is-audited) | LightHouse service | `GET /api/v1/audit` | | [A key may never pay, raise a limit or approve](/security/api/#what-a-machine-key-may-never-do) | LightHouse service and your handler | Those routes answer `403 person_required` to a key | | [MCP is read only](/security/mcp/) | LightHouse service | No tool approves, pays or changes a limit | | [Retrieved text is evidence, never instruction](/security/mcp/#prompt-injection) | The engine, in your account | The tool gate refuses what the agent’s card does not permit | | [Content security policy with a per-request nonce](/security/ui/#content-security-policy) | The portal | Inspect `Content-Security-Policy` on any page | | [Cost caps and kill switches in code](/security/engine/#caps-and-kill-switches) | The gateway, in your account | A refused call is a `model_call` with `outcome: refused` | | [The Cedar tool gate](/security/engine/#the-tool-gate) | The engine, in your account | The `tool_denials_total` metric in your account, by reason | | [No long-lived cloud keys](/security/engine/#no-long-lived-keys) | Your cloud’s identity service | Read the roles the stack creates | | [Signed telemetry](/security/supply-chain/#signed-telemetry) | Your deployment signs; intake verifies | An unsigned post answers `401 unsigned` | | [Scanning on every commit and pipeline](/security/supply-chain/) | Atlantic’s repositories and CI | Ask for the latest reports under NDA | The [security controls summary](/trust/security-controls/) puts the same rows on one page for a questionnaire. ## Where to start [Architecture and trust boundary](/security/architecture/)What runs where, and the three things that cross. [API security](/security/api/)Sign-in, roles, keys, isolation, limits and audit. [Engine and gateway](/security/engine/)Controls in code the model cannot reach. [Verify it yourself](/security/verify/)Tests you can run from outside, today. [Report a vulnerability](/security/verify/#reporting-a-vulnerability)Disclosure policy, response targets, safe harbour and credit. Data handling has its own section: [Data sovereignty](/data-sovereignty/). Source: https://docs.atlanticagenticlabs.com/security/ --- # Architecture and trust boundary > What runs in your account, what runs in Atlantic's, and what crosses between them. LightHouse and the engine are separate components. The engine, which touches your content, runs in your account. LightHouse, which Atlantic runs, receives only operational telemetry about that work. Your account your cloud, or your own servers - **Agents and orchestrator**run your agents and their approvals - **Gateway**the only path to a model: caps, kill switch, tool gate, masking - **Your documents and index**indexed and searched where they are - **Models**your Bedrock, Vertex AI or Azure OpenAI, or a provider's API - **Content reader**serves read-only views of your content, on request - **Handler**collects signed commands; your policy decides - **Your secrets**credentials, in your own secret store - **Logs**every content read, recorded in your account Trust boundary · every connection is opened from your side ↓ **Operational telemetry**Counts, costs and timings, signed by your deployment. Never content. ↕ **Content, viewed in place**A read request signed by Atlantic travels down a connection your reader opened. The answer is shown to the person who asked and is not stored. ↑ **Signed commands**Pause, approve, set a limit: made by a person in LightHouse, signed, and checked by your handler against your own policy. Atlantic's account LightHouse, in the EU (Ireland) - **Intake**verifies each signature, refuses anything off the allow-list - **Store**one shared database; each tenant's records isolated by row-level security - **API, MCP and portal**at your tenant's own host - **Sign-in**through your identity provider, with a second factor What runs on each side, and the only three things that cross. Content export to Atlantic is a fourth flow, opt-in and off by default. ## What runs in your account The Atlantic Agentic Engine, deployed by your own pipeline from a stack you review. On AWS, Azure or Google Cloud it runs in your account or subscription; on premises it runs as containers on your own servers. With [Atlantic-hosted](/clouds/atlantic-hosted/), the same engine runs in a dedicated account Atlantic manages for you. | Component | What it does | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Agents and orchestrator | Run your agents, their steps and their approval points | | Gateway | The only path from an agent to a model. Checks the model against your allow list, enforces caps and the kill switch, masks personal data your policy names, and records each call | | Index and documents | Your connectors read your sources; the index is built and searched where it lives | | Models | Called by the gateway in your cloud (Amazon Bedrock, Vertex AI, Azure OpenAI) or through a provider’s API with your key | | Content reader | Answers read-only requests for your content, one at a time, each signed by Atlantic | | Handler | Collects signed commands from LightHouse and applies those your own policy permits. With a sealing key and a store, it also keeps the connector credentials you connect in LightHouse | | Secret store | Your connector credentials, including those you connect in LightHouse once your deployment keeps them, and your deployment’s signing key | Nothing here listens for a connection from Atlantic. The reader and the handler each open one outbound connection, so the only network path the engine needs to LightHouse is outbound HTTPS to one Atlantic hostname, given to you at onboarding. ## What runs in Atlantic’s account LightHouse: the intake that receives telemetry, the database it is stored in, the API, the MCP server and the portal. It runs on AWS in the EU (Ireland, `eu-west-1`), behind Cloudflare. Each tenant has its own host, `https://.atlanticagenticlabs.com`. The tenant ID is a random label generated at onboarding. It does not identify the client, because hostnames are public. ## What crosses, and in which direction Three flows, each opened from your side. ### Operational telemetry, out Your deployment posts records to LightHouse: one per model call, run, step, search, evaluation, cap, health check and so on. Every record type has a fixed list of attributes. The engine drops anything not on the list before sending, and LightHouse refuses any record that carries one. A model call record carries the agent, the model, token counts, cost, latency and outcome. It does not carry the prompt, the answer, a document, a passage or a person’s name. A person appears only as a keyed hash computed in your account. See [the telemetry contract](/concepts/telemetry-contract/) for every record type. ### Content, viewed in place When a person with the `content_viewer` role opens content in LightHouse (a knowledge record, an agent’s output, an approval), LightHouse sends a read request down the connection your content reader opened. The request is signed with Atlantic’s reader key. Your reader refuses any request that key did not sign for your deployment, that is more than five minutes old, or that it has seen before. The answer is shown to the person who asked. It is not stored in LightHouse. Your reader logs every read in your account: who asked, which key signed, the request ID, what and when. You can cut this flow off without Atlantic: stop the reader, or remove Atlantic’s public key from it. ### Signed commands, in A person with the `handler` role can pause an agent or decide an approval in LightHouse, and a `client_admin` can also set a spending limit or change the model router’s settings. See [Handlers](/concepts/handlers/) for every command. Each command is signed with Atlantic’s command key and collected by your handler over its own outbound connection. Your handler applies it only if your deployment’s own policy permits that command type. See [Approvals](/concepts/approvals/). ### Content export, off by default A fourth flow exists only if you turn it on: export of knowledge records and outputs into LightHouse, encrypted under a key held for your tenant alone. It needs a signed data processing agreement and is off unless your tenant’s record says otherwise. See [Data sovereignty](/data-sovereignty/). ## How to check the boundary yourself - **Egress.** Restrict your deployment’s outbound traffic to your model endpoints and the one Atlantic hostname. The engine keeps working; nothing else is needed. - **What arrives.** `GET /api/v1/runs`, `GET /api/v1/usage` and every other read return counts, timings, identifiers and costs. The responses contain no text from the tenant’s documents. - **Who read your content.** Your reader’s log, in your account, lists every content read. In LightHouse, `GET /api/v1/audit` lists them too, as `content_read`. - **Cutting it off.** Stop the content reader. LightHouse’s content pages then say content cannot be read in place right now (`503 tier_b_unavailable`), and nothing else changes. **curl** ```bash # What LightHouse knows about your tenant and your deployments curl "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/me" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" ``` **Python** ```python import os import httpx headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"], } me = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/me", headers=headers) me.raise_for_status() print(me.json()["deployments"]) ``` **TypeScript** ```ts const res = await fetch(`https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/me`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, }); console.log((await res.json()).deployments); ``` `/api/v1/me` also reports two flags for your tenant: `tier_b` (whether content can be read in place) and `tier_c` (whether content export is on), so you can confirm export is off. See the [API reference](/api/reference/people-and-preferences/#me). Source: https://docs.atlanticagenticlabs.com/security/architecture/ --- # API security > Authentication, roles, tenant isolation, rate limits, idempotency and audit for the LightHouse API. The LightHouse API lives at your tenant’s own host, `https://.atlanticagenticlabs.com/api/v1/`. The portal and the [MCP server](/security/mcp/) use the same service, the same checks and the same roles. This page covers each check in the order a request meets it. ## The tenant comes from the hostname **What it is.** The service works out which tenant a request is for from the hostname alone. It does not read a tenant from a query parameter, a body field or a header such as `X-Forwarded-Host`, so a forged value has no effect. **Where.** The LightHouse service, before any route runs. A hostname that is no tenant’s answers `404 unknown_client`. **Verify.** Send a request to a hostname that is not yours: it is refused at the edge or answers `404`. Add a `client` parameter to any request on your own host: it is ignored, or refused as `400 bad_query` where the route takes no such parameter. ## People: sign in through your identity provider **What it is.** People sign in through the tenant’s own identity provider. Atlantic holds no passwords. Supported: Microsoft Entra ID, Google Workspace, GitHub (with rules by organisation and team), GitLab (by group), Okta, OneLogin, Ping, Auth0, Keycloak and any SAML or OIDC provider. A one-time email code is offered for named external viewers only. Signing in proves who someone is. Your tenant’s access rules then decide whether they get in, and with which role. The rules match on provider, group, GitHub team, email domain or a named email. An email domain alone is not enough for a GitHub or GitLab identity, because its email is often not the company’s. **Where.** Twice. Cloudflare Access at the edge checks the identity against your tenant’s own Access application. The LightHouse service verifies the signed token again and applies your access rules. A person who passes the edge but not your rules gets `403 not_authorised`. ### A second factor, enforced twice **What it is.** Every person must prove a second factor. It cannot be turned off. **Where.** - **At the edge**, the Access policy requires a second factor from your identity provider wherever the provider reports one. Otherwise it requires Cloudflare Access’s own second factor (a security key or an authenticator). - **In the service**, a person is accepted only if the identity provider reported a second factor, or if the service has confirmed that every allow policy on your tenant’s Access application requires one. That check runs at start and every five minutes. If a policy lacks the requirement, or the check has not completed for more than 15 minutes, the person is refused with `403 mfa_required`, even if the edge let them through. A misconfigured policy fails closed. Sessions last at most 12 hours. **Verify.** Sign in and call `GET /api/v1/me` from the portal’s session. `viewer.mfa.source` says how your second factor was established: `provider`, `cloudflare` or `access_policy`. ## Machines: a key and a service token **What it is.** Scripts and services authenticate with two credentials, one checked at the edge and one checked by the service: 1. Your tenant’s **Cloudflare Access service token** (`CF-Access-Client-Id` and `CF-Access-Client-Secret`), checked at the edge. 2. A **LightHouse API key** (`Authorization: Bearer aalcp-...`), checked by the service. The service token on its own reads nothing, and a request with only the key is stopped at the edge before it reaches the service. | Property of an API key | Rule | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | Roles | `viewer` or `content_viewer` only. Not `handler` or `client_admin`, so a leaked key cannot change who has access | | Scope | One tenant. A key is looked up within the hostname’s tenant only; at any other tenant’s host it does not exist and answers `401` | | Expiry | Mandatory, at most 365 days | | Storage | Shown once when issued. LightHouse keeps only its SHA-256, so a copy of the database grants nothing | | Revocation | Immediate. A revoked key is a row, not a deletion, so the audit log keeps who revoked it and when | **Where.** Keys are issued by a `client_admin` in **Settings → Keys**, or with `POST /api/v1/keys`. See [Authentication](/api/authentication/). **Verify.** Call any route with your key at another tenant’s host, or with a revoked key: `401`. List your keys and the service token’s expiry with `GET /api/v1/keys` (a `client_admin`, as a person). **curl** ```bash # A key at its own tenant's host: 200. The same key anywhere else: 401. curl -i "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/health" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" ``` **Python** ```python import os import httpx headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"], } r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/health", headers=headers) print(r.status_code, r.headers.get("strict-transport-security")) ``` **TypeScript** ```ts const res = await fetch(`https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/health`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, }); console.log(res.status, res.headers.get("strict-transport-security")); ``` ## Roles and least privilege **What it is.** Four roles. Each includes everything the one above it may do. | Role | Adds | | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `viewer` | Operational telemetry: runs, usage, cost, health, evaluations, savings | | `content_viewer` | Your content, read in place from your account | | `handler` | Commands on your agents: pause, resume, set a budget cap, grant and revoke pre-approvals, decide an approval and make a released version current, within your command settings and your deployment’s own policy | | `client_admin` | Access rules, API keys, the access review, the audit log and the command settings; spending limits, the model router’s settings and the Token Value Benchmark; connectors, where agents run, models, branding and the library’s **Add to deployment**; billing and payments | **Where.** The service checks the role on every API route and every MCP tool. A missing role is `403 role_required`, naming the role needed. **Guard rails** that your own administrators cannot change, each refused as `422 guard_rail`: - At least one unexpired `client_admin` grant always remains. - A one-time email code matches only a named email. - Public email domains (gmail.com, outlook.com and the like) cannot be used as a domain rule. - A time-limited grant runs at most a year. - No rule may name Atlantic. Atlantic staff get at most `content_viewer`, and only if your rules say so. - MFA cannot be turned off. **Verify.** `GET /api/v1/access/review?format=csv` (a `client_admin`) lists who holds which role by which grant, their last sign-in, every key, and every Atlantic staff read. See [Who can see what](/data-sovereignty/access/) for Atlantic’s own access. ## Tenant isolation in the database **What it is.** Each tenant’s control-plane records are isolated from every other tenant’s by PostgreSQL row-level security in a shared database. Tenant content stays in the tenant’s own deployment and is not stored by LightHouse. Row-level security is a second layer of protection behind the query layer, which already scopes every query to the hostname’s tenant. **Where.** The database itself: - The service connects as a role that owns nothing and cannot bypass row-level security. - Every table that holds a tenant’s rows has row-level security enabled and forced. - The tenant is set per transaction, from the request’s hostname (or, for telemetry, from the signing deployment). - If a code path forgets to set it, the setting is empty and matches nothing: the query reads and writes nothing, rather than everything. - A query that names another tenant gets no rows. An insert or update of another tenant’s row fails. A test in LightHouse’s own suite finds every table with a tenant column from the database catalogue and fails if any lacks forced row-level security and its policy, so a new table cannot be added without it. **Verify.** The database is not reachable from outside, and no route takes a tenant parameter. Under NDA, Atlantic walks through the policies and the test. See [Verify it yourself](/security/verify/). ## Rate limits and request sizes **What it is, today:** | Limit | Where | | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | Every API request: 600 a minute for one credential, 3,000 for your tenant, answered `429 rate_limited` with `Retry-After` and `RateLimit-*` headers | The service, counted in the database so the limit is the same across every instance | | Telemetry from your deployment: records a minute and bytes a day, per tenant and per deployment | LightHouse intake answers `429` with `Retry-After`; nothing of the refused request is stored | | Telemetry requests per source address | Cloudflare, at the edge | | Sign-up attempts per address, email and email domain, per minute and per day | The public sign-up endpoints | | JSON request bodies: 256 KB by default. Many write routes set a smaller cap, for example 16 KB for commands, approval decisions and connector tokens, and 4 KB for profile requests. An oversized body is refused with `422 invalid` (“the body is too large”) | The service reads bodies in chunks and stops at the cap, so an oversized body is not buffered whole | | Branding images: 512 KB | The branding routes | See [Rate limits](/api/rate-limits/) for the headers and how to retry. A refused request is not counted, and Atlantic staff never spend your tenant’s allowance. The provider limits your own models are under (requests, input and output tokens a minute) are separate. LightHouse measures them; see [Rate limits](/api/rate-limits/). **Verify.** Send a JSON body over 256 KB to any write route: it is refused before it is read in full. ## Idempotency **What it is.** Two mechanisms make writes safe to retry. - **`Idempotency-Key` on commands.** `POST /api/v1/agents/{agent_id}/commands` and `POST /api/v1/approvals/decisions` accept an `Idempotency-Key` header of 8 to 128 characters (letters, digits, `.`, `_`, `:` and `-`). The same person sending the same key again gets the original command back, not a second command. The database enforces it with a unique index, so even a double click that races is caught. - **Optimistic versions on settings.** Access rules, command settings, routing settings and other settings carry a `version`. A `PUT` with a stale version is refused with `409 version_conflict`, so two administrators cannot silently overwrite each other. **Verify.** Send the same command twice with one `Idempotency-Key`: both answers carry the same `command_id`. **curl** ```bash # Run as a person with the handler role (commands are never made by a key). curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/agents/$AGENT/commands" \ -H "Cookie: CF_Authorization=$CF_AUTHORIZATION" \ -H "Idempotency-Key: pause-2026-11-01-001" \ -H "Content-Type: application/json" \ -d '{"type": "agent.pause", "params": {"reason": "investigating a failure"}}' ``` **Python** ```python import os import httpx r = httpx.post( f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/agents/{os.environ['AGENT']}/commands", cookies={"CF_Authorization": os.environ["CF_AUTHORIZATION"]}, headers={"Idempotency-Key": "pause-2026-11-01-001"}, json={"type": "agent.pause", "params": {"reason": "investigating a failure"}}, ) print(r.status_code, r.json()["command_id"]) ``` **TypeScript** ```ts const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/agents/${process.env.AGENT}/commands`, { method: "POST", headers: { Cookie: `CF_Authorization=${process.env.CF_AUTHORIZATION}`, "Idempotency-Key": "pause-2026-11-01-001", "Content-Type": "application/json", }, body: JSON.stringify({ type: "agent.pause", params: { reason: "investigating a failure" } }), }, ); console.log(res.status, (await res.json()).command_id); ``` `$AGENT` is the agent’s ID, `:`. `$CF_AUTHORIZATION` is the session cookie your browser holds after signing in. See [Idempotency](/api/idempotency/) and the [Handler commands reference](/api/reference/handler-commands/). ## Every write is audited **What it is.** An append-only audit log per tenant. It records every change to your access rules (who, when, before and after), every key issued or revoked, every sign-in and refusal, every handler command, every change to limits, billing, branding, connectors and settings, every content read, and every read by Atlantic staff. Personal preferences (a person’s own time zone, theme or tour progress) are not audited. **Where.** The database refuses any update, delete or truncate of the audit log. The service writes the entry in the same transaction as the change wherever the change is LightHouse’s own. **Verify.** **Setup and admin → Audit** in LightHouse, or `GET /api/v1/audit` as a `client_admin`. Each entry names the actor, their identity provider type, the summary, the reason and whether it was a break-glass action. See the [Audit reference](/api/reference/read/#audit). ## What a machine key may never do **What it is.** Some actions are for a signed-in person only, whatever role a key or a service holds: - **Pay**: top up, change auto-recharge, add or remove a payment method, open checkout. - **Raise a limit**: add, change or clear a spend limit. - **Approve**: decide an approval, issue any handler command, grant a pre-approval. - **Administer**: change access rules, issue keys, change routing settings, start a benchmark. **Where.** In the LightHouse service, each of these routes checks that the caller is a person from your organisation who has proved a second factor. A key is refused with `403 person_required` (on administration routes, `403 role_required`, since no key can hold `client_admin`). In your account, your deployment accepts approvals and limit changes only as commands signed by LightHouse, and only those your policy permits. No MCP tool does any of these things. **Verify.** Call `POST /api/v1/approvals/decisions` or `POST /api/v1/limits` with your API key: `403 person_required`. LightHouse’s own test suite asserts this for top-up, auto-recharge, payment methods, the customer portal and spend limits. Source: https://docs.atlanticagenticlabs.com/security/api/ --- # MCP security > How the hosted MCP endpoint is secured, and how prompt injection is handled. LightHouse serves the Model Context Protocol at two endpoints (streamable HTTP): your portal’s, `https://.atlanticagenticlabs.com/mcp`, and the hosted endpoint, `https://mcp.atlanticagenticlabs.com/t//mcp`. It gives an assistant such as Claude, Cursor or Codex the same reads as the API, as tools. This page covers what protects it, and how the engine handles text that tries to give an agent orders. To connect a client, see [Connect a client](/mcp/connect/). ## Authentication **What it is.** Your portal’s endpoint accepts exactly the credentials the API does, and checks them the same way: - **A person**: signed in through your identity provider with a second factor, by Cloudflare Access at your tenant’s host. - **A machine**: your tenant’s Access service token at the edge, and a LightHouse API key (`viewer` or `content_viewer`) in the service. The hosted endpoint accepts **OAuth only**: a delegated token (`lhat-`) that a person approved in their own portal. A machine key, a portal session or an Access session is refused there by its shape, before any lookup, so the host reachable from any editor does not accept a long-lived key or a cookie. **Where.** A wrapper in the LightHouse service authenticates every HTTP request before the MCP library sees it, then hands the verified identity to the tool. No tool takes a tenant argument. On your portal’s endpoint the tenant comes from the hostname. On the hosted endpoint it comes from the path, and the token’s own tenant must match it: a token for another tenant is refused, whatever address it is sent to. The server is **stateless**: no MCP session ID carries your identity from one request to the next. A session ID that carried identity would be a second credential outside the identity checks. **Verify.** Call either endpoint without credentials, or with a key at another tenant’s host: refused, exactly as the API refuses. Call the hosted endpoint with a machine key: `401 invalid_token`. ## OAuth on the hosted endpoint **What it is.** OAuth for public clients (authorisation code with PKCE, and dynamic client registration), with the person approving in their own portal: - **Discovery.** A request without a token is answered `401` with `WWW-Authenticate` naming the endpoint’s protected-resource document (RFC 9728). That document names your tenant’s own portal as the authorisation server, so you sign in on the hostname your identity provider knows, under your own second factor. The hosted endpoint never sees a password or a session. - **Registration** (RFC 7591) returns an identifier and no secret. Because registration is unauthenticated by design, it is bounded per tenant: at most 20 new clients an hour and 1,000 in total. Past either, it answers `429 too_many_requests` in the OAuth error shape, so a client that follows the specification backs off. A redirect must be `https` to a real host, `http` only on the loopback address for a desktop client, or a private-use scheme a native app owns. Another `http` address, a wildcard, a fragment, or a scheme a browser acts on itself (`javascript:`, `data:`, `file:`) is refused. - **PKCE** (`S256` only) on every authorisation code; a code is single use, expires in 5 minutes, and must come back with the client and redirect it was issued to. - **Approval** happens on your portal’s own page, `https://.atlanticagenticlabs.com/oauth/authorize`, which shows the client, where the answer goes and each scope in words. An error never redirects. - **Only a person approves.** The approval needs a person’s own portal session with a second factor proved. A machine key is refused, and so is a delegated token: a token cannot mint another, so a stolen token cannot be made permanent. **The token.** Opaque, stored only as a SHA-256 digest, valid 8 hours, bound to one tenant, one person and the scopes they approved. Its refresh token rotates on every use, and one presented twice revokes the whole chain, because a repeated refresh token indicates theft. The person’s access is re-read on every request, so withdrawing it stops the token at once, and the role never exceeds the one they approved with. A delegated token is refused everywhere a machine key is: it cannot approve, decide, pay, raise a limit or administer. **Scopes.** A delegated token reaches only the tools its approved scopes allow (`telemetry:read`, `agents:read`, `knowledge:read` or `billing:read`). It is refused with `403 scope_required` before the tool runs, on both the hosted endpoint and your portal’s `/mcp`, so a prompt that induces an assistant to call a tool it was not granted has no effect. The role check below applies as well. The table of tools per scope is in [The hosted endpoint](/mcp/#the-hosted-endpoint). **What a delegated token cannot do.** Whatever its scopes, it cannot approve, pay or administer. No MCP tool does any of those, and the API refuses a delegated token on those routes exactly as it refuses a machine key. **Availability.** Atlantic turns the hosted endpoint on for the platform as a whole. Where it is not on, the address does not answer, and a machine key with your Access service token at your portal’s endpoint is the way in. **Verify.** `GET https://mcp.atlanticagenticlabs.com/t//.well-known/oauth-protected-resource` names your portal as the authorisation server; `GET https://.atlanticagenticlabs.com/.well-known/oauth-authorization-server` lists `S256` as the only code challenge method and `none` as the only client authentication. ## The role each tool needs **What it is.** Every tool checks its role before it runs, with the same cumulative roles as the API (`viewer`, `content_viewer`, `handler`, `client_admin`). | Tools | Role | | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | Nearly every tool: runs, usage, cost, health, evaluations, savings, caching, routing, knowledge bases, evidence scores | `viewer` | | `knowledge` (knowledge records, read in place from your account) | `content_viewer`. Every call is written to your audit log as `content_read` | | `commercial_terms`, `market_usage` | `client_admin` | | `models`, `model_picker` | `viewer`; price cards are shown only to a `client_admin` | The [MCP tools reference](/mcp/tools/) lists every tool with its inputs and its role, generated from the server itself. **Verify.** Call `knowledge` with a `viewer` key: the tool answers with the `role_required` refusal. ## Read only, deliberately **What it is.** No MCP tool approves, rejects, pauses, revives, changes a limit, tops up, pays or connects a provider. An AI agent must not approve its own work, spend money or loosen its own limits. The MCP server offers no tool that does any of these. **Where.** The MCP server’s tool list. Commands and approvals exist only on the API, for a signed-in person, and a key is refused there with `403 person_required`. **Verify.** List the tools (`tools/list`). Every one is a read except `connection_schedule` and `connection_sync`, which set or start a connection’s source sync for a client administrator signed in at their own keyboard, and are refused for a machine key and a delegated token. ## A person on anything that acts **What it is.** Inside your account, what an agent may do on its own is declared on its card: its tools, and its autonomy (internal work, a draft, a person’s sign-off, or a standing pre-approval). An agent whose card says sign-off stops and waits for a person. **Where.** The engine enforces the card at run time, not in the prompt. Where your deployment’s policy says approvals are managed by LightHouse (the default for new deployments), the engine accepts an approval only as a command signed by LightHouse and made by a person with the `handler` role. Every other route to approve, including the engine’s own, is refused and logged. If LightHouse cannot be reached, nothing is approved: items wait, and agents act only within standing pre-approvals. You can turn on your own break-glass for named people (off by default). A decision taken that way is flagged in your audit log. See [Approvals](/concepts/approvals/). ## Prompt injection Retrieved documents, emails and web pages may contain text written to steer a model. The engine treats that text as **evidence, not instruction**, and does not rely on the model to tell the difference. **What it is.** Three layers, each in code: 1. **Fencing.** Untrusted text is wrapped in a delimiter it cannot forge before it reaches a model, so the boundary between your instructions and retrieved material is explicit. 2. **Signals.** Text that tries to give orders is detected and counted. The counts reach LightHouse as screening records (counts only), and repeated violations can stop the scope. 3. **The tool gate.** This is the layer that enforces the limit. Each tool call passes, in order: the run’s signed token (which names the tools this run may use), a Cedar policy (which must permit this agent this tool), the scopes declared on the card, and, for a tool that acts in the world, the delegated credential of the person the run acts for. A hijacked agent still cannot call a tool its card does not grant, widen its scope, or act for a person when the run has none. Fencing and signals do not stop prompt injection on their own. The tool gate limits a successful injection to what the agent was already permitted to do. **Where.** The engine, in your account. The model never sees the tool gate’s policy and cannot change it. See [Engine and gateway](/security/engine/#the-tool-gate). **Verify.** In LightHouse, **Security and context → Safeguards** shows screened and blocked requests. `GET /api/v1/refusals` returns refused model calls by reason and the screening counts. ### Tested against injection The engine’s assistant, Octy, ships with a red-team evaluation suite: injection through retrieved documents, approval and payment coercion, exfiltration and overclaim. In CI it runs against a stub model that is gullible by design, so it tests the code around the model rather than a model’s good behaviour. A suite passes only if every case passes. Live runs against your own models are started by a person. See [What a red-team suite covers](/security/verify/#what-a-red-team-suite-covers-before-go-live). Source: https://docs.atlanticagenticlabs.com/security/mcp/ --- # UI security > The content security policy, headers, sessions and tests behind LightHouse's interface. The LightHouse portal is the interface that tenant users sign in to at `https://.atlanticagenticlabs.com`. It shows your telemetry, and your content where your roles allow. Every control on this page can be checked with your browser’s developer tools. ## Content security policy **What it is.** Every page carries a content security policy with a fresh nonce, made for that request alone (18 random bytes). Only scripts from the portal’s own origin, or inline scripts carrying that request’s nonce, can run. There is no `'unsafe-inline'` for scripts anywhere. An attacker who injects HTML into a page cannot run a script in it. The policy, as sent: ```text default-src 'self'; script-src 'self' 'nonce-' https://js.stripe.com https://*.js.stripe.com; style-src 'self' 'nonce-'; style-src-elem 'self' 'nonce-'; style-src-attr 'unsafe-inline'; img-src 'self'; font-src 'self'; connect-src 'self' https://api.stripe.com; frame-src 'self' https://js.stripe.com https://*.js.stripe.com https://hooks.stripe.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none' ``` Two entries in it need explanation: - **Stripe.js is the only third party**, for the in-app payment pages, with exactly the origins Stripe’s own security guide lists. A test in the portal’s suite fails if anything else adds an origin. - **`style-src-attr 'unsafe-inline'`** allows inline `style="…"` attributes, which the charts, maps and progress bars render on the server. A nonce cannot cover an attribute. No tenant-supplied value reaches a style attribute: a tenant’s brand is served as a same-origin stylesheet built from validated values. The sign-in page at `platform.atlanticagenticlabs.com` has its own, stricter policy (`default-src 'none'`, `'strict-dynamic'`, `form-action 'none'`, `Referrer-Policy: no-referrer`) and serves nothing but the sign-in page and its files. **Where.** The portal’s request handler makes the nonce, sets the policy on the response, and passes the nonce to the framework’s own scripts. **Verify.** Load any page twice and compare the `Content-Security-Policy` header: the nonce differs each time. **curl** ```bash curl -sI "https://platform.atlanticagenticlabs.com/" | grep -i -E "content-security-policy|strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy" ``` **Python** ```python import httpx r = httpx.get("https://platform.atlanticagenticlabs.com/") for name in ("content-security-policy", "strict-transport-security", "x-frame-options", "x-content-type-options", "referrer-policy", "permissions-policy"): print(name, "=", r.headers.get(name)) ``` **TypeScript** ```ts const res = await fetch("https://platform.atlanticagenticlabs.com/"); for (const name of ["content-security-policy", "strict-transport-security", "x-frame-options", "x-content-type-options", "referrer-policy", "permissions-policy"]) { console.log(name, "=", res.headers.get(name)); } ``` The sign-in host needs no credentials, so anyone can run this. Your tenant’s own pages need a signed-in session; open your browser’s network panel on any of them to see the portal’s policy. ## Security headers **What it is.** Every portal response carries: | Header | Value | What it prevents | | --------------------------- | ------------------------------------------ | ----------------------------------------------------------------------- | | `Strict-Transport-Security` | `max-age=31536000; includeSubDomains` | Any visit over plain HTTP after the first | | `X-Content-Type-Options` | `nosniff` | A browser treating an upload as script | | `X-Frame-Options` | `DENY` | The portal being framed by another site (with `frame-ancestors 'none'`) | | `Referrer-Policy` | `strict-origin-when-cross-origin` | Paths and queries leaking to other sites | | `Permissions-Policy` | `camera=(), microphone=(), geolocation=()` | The page requesting devices it does not need | The API adds `nosniff`, `Referrer-Policy: no-referrer` and the same HSTS to every response, including streamed ones, that has not set its own. **Verify.** The command above, or `curl -sI` against any API route with your key. ## Sessions **What it is.** A person’s session is a Cloudflare Access session at your tenant’s host, opened through your identity provider with a second factor. It lasts at most 12 hours. Each request carries the signed Access token, which the LightHouse service verifies on every request, not only at sign-in. **Where.** Cloudflare Access issues and expires the session. The service verifies the token’s signature and audience against your tenant’s own Access application, and refuses a token made for any other. **Verify.** Sign in, wait past the session length, and reload: you are sent to sign in again. See [API security](/security/api/#people-sign-in-through-your-identity-provider) for the second-factor checks. ## Branding uploads **What it is.** Your administrators can brand the portal: a name, logos, a favicon, two colours, a font and a corner radius. It is applied as **values, not CSS**. A tenant cannot send a stylesheet, because CSS could restyle or hide parts of a page (a spoofed approval, a hidden warning) or read the page out through selectors. - **SVG** logos are rebuilt from an allow-list of elements and attributes. Scripts, foreign objects, event handlers, external or `data:` references and `url()` to anything but a fragment are refused. - **PNG and WebP** (at most 512 KB) are decoded in full and re-encoded from their pixels alone, so metadata, colour profiles and anything appended after the image never reach your portal’s origin. An image whose header disagrees with its contents is refused. - Every image is served from the portal’s own origin with its exact content type and `nosniff`; an SVG also carries a sandboxing policy of its own. - Colours that fall below WCAG AA contrast (4.5:1) on either theme are adjusted to the nearest shade that passes, and both values are returned so you can see what changed. - Fonts come from a fixed list of self-hosted or system fonts. The portal makes no third-party font request. **Where.** The LightHouse service, on upload. Every branding change is in your audit log. **Verify.** Upload an SVG containing `