# RELIASTRA - Full reference (llms-full.txt) > RELIASTRA probes the external services software depends on, records every > observation, confirms faults deterministically, and keeps evidence a third > party can verify without an account. > Canonical origin: https://reliastra.com/ - all URLs below are absolute canonical URLs. ## Product RELIASTRA observes third-party endpoints you configure ("dependencies"), correlates their failures with incidents you report, classifies likely causes with a deterministic, versioned engine, and compiles evidence records that can be verified without an account. It is a tool for individual engineers: one plan, one seat, no organisation administration, no sales process. One paid plan: Developer ($9/month). New accounts get a 14-day trial with full Developer capabilities; without a subscription they keep running on reduced limits (3 dependencies, 1-minute checks, 24-hour retention). ## What is observed, and from where (state this exactly) - Observation points deployed today: 1 (us-east). - Default probe interval: 300 seconds. - A `region` field appears on every observation. It names the worker that ran the probe. With one observation point it carries no confirmation weight, and RELIASTRA does not claim multi-region or quorum confirmation. - An incident opens after 2 consecutive failed checks (rule `single.consecutive_failures`) and resolves after 2 consecutive successes (rule `single.consecutive_successes`). One failed probe is recorded, not declared. - Missed probes are never backfilled. Response bodies are never read or stored. - Public records currently target vendor-published status-site endpoints (for example https://status.openai.com for OpenAI). The status text published at those URLs is never read or reconciled; only the endpoint's HTTP behaviour is measured. A vendor's API, models or routes are not covered unless an API endpoint is listed as an observed target on the record. Probes are issued from 1 observation point today, on a 300-second interval by default. Every page that reports a measurement says which window it covers and how many observations stand behind it. ## Programmatic access CLI (`reliastra`), shipped in the RELIASTRA repository under `cli/` as a single static binary with no runtime dependencies. Install it with `go install github.com/ReliaAstra/Reliastra/cli/cmd/reliastra@latest`, or run `go run ./cli/cmd/reliastra …` from a checkout. reliastra login --email you@example.com # or: login --token rel_... for an API key reliastra doctor # config, credential, reachability: which one is failing reliastra deps list | deps show | deps add --interval 60 | deps rm reliastra checks recent --limit 20 --dependency reliastra incidents list --status open --web reliastra incidents show --evidence # follows the incident to its evidence record reliastra incidents correlate reliastra evidence list | evidence show | evidence get --out incident.pdf reliastra verify --file incident.pdf # exits 4 when the document does not match reliastra keys list | keys create --scopes read:checks,read:incidents | keys rm reliastra obs list | obs show # the public observatory, no credential needed reliastra open incident | open evidence | open docs Every data command takes `--json` and prints the API's own field names. Exit codes: 0 success, 1 usage, 2 API error, 3 auth, 4 verification claim failed, 5 not permitted, 6 unreachable. REST API: `https://api.reliastra.com/v1/`. The API origin serves its own OpenAPI document at `https://api.reliastra.com/openapi.json`; a self-hosted deployment answers at the same paths on its own origin. Endpoints a service needs: `GET /v1/dependencies`, `GET /v1/dependencies/{id}/results`, `GET /v1/checks/recent`, `GET /v1/incidents?dependency_id={id}`, `GET /v1/incidents/{id}`, `GET /v1/evidence`, `GET /v1/evidence/{id}` (record plus a one-hour signed download URL), `GET /v1/evidence/{id}/artifact` (the document itself, streamed), `GET /v1/verify/{verification_id}` (public, no account), `GET /v1/verify/keys`, `GET /v1/vendors`. Credentials: an API key is `rel_` followed by 40 hex characters, sent as `X-API-Key`, `Authorization: rel_...` or `Authorization: Bearer rel_...`. Keys are denied by default: they cannot reach identity, account, webhook or key-management surfaces, whatever scopes they carry, so a leaked key cannot mint a credential or redirect events. Webhooks: `POST /v1/webhooks` with `events` from incident.opened, incident.updated, incident.resolved and evidence.ready (the enum also accepts vendor.degraded, vendor.down, vendor.recovered, sla.breach and check.failed, which nothing emits yet). Deliveries are signed with HMAC-SHA256 when the subscription has a secret, carry X-Reliastra-Event, X-Reliastra-Delivery and X-Reliastra-Signature headers, and are retried on a fixed backoff (1m, 5m, 15m, 1h, 3h, then permanently failed). Configuration is session-only. ## Differentiation from uptime monitoring | Uptime monitoring | RELIASTRA | |---|---| | Watches your services | Watches the third-party services your software calls | | Alerts "checkout is down" | Answers "was it you or the dependency?" | | Your own vantage point | A vantage point outside both your network and the vendor's | | Vendor status page as evidence | Independent scheduled probes, retained as records | | Screenshots for SLA claims | Checksummed, third-party-verifiable fault records | What RELIASTRA does not do: it does not instrument the vendor's internal systems, it does not replace application tracing, and it does not tell you why a dependency failed. ## Documentation map - Overview: https://reliastra.com/docs - Quickstart: https://reliastra.com/docs/quickstart - Concepts: https://reliastra.com/docs/concepts - Configuration: https://reliastra.com/docs/configuration - Monitoring: https://reliastra.com/docs/monitoring - Incidents: https://reliastra.com/docs/incidents - Evidence: https://reliastra.com/docs/evidence - Verification: https://reliastra.com/docs/verification - REST API: https://reliastra.com/docs/api - CLI: https://reliastra.com/docs/cli - Webhooks: https://reliastra.com/docs/webhooks - Methodology: https://reliastra.com/docs/methodology - Security: https://reliastra.com/docs/security Each guide is also served as plain Markdown at its URL with a ".md" suffix - for example https://reliastra.com/docs/monitoring.md. The complete text of all 12 guides is inlined below, so reading this file requires no second request and no guide here depends on a page being reachable. ## Documentation (full text) Rendered from the same corpus the site renders (lib/docs/corpus.ts). Inline markup is Markdown: backquoted code, **bold**, and [links](https://…). ### Quickstart > Install the CLI, add an endpoint, read the first observation, and follow an incident through to its evidence record. #### Install the CLI Everything below is one path, and the fastest way through it is the CLI. The npm and pipx packages are thin installers that download the verified binary on first run; Go builds from source. ```bash npm install -g reliastra # or pipx install reliastra # from source go install github.com/ReliaAstra/Reliastra/cli/cmd/reliastra@latest reliastra --version ``` The CLI lives in that repository at `cli/`, a Go module with no dependencies beyond the standard library. The npm/pip installers share one cache and verify SHA-256 against the release checksums.txt. From a checkout, `go build -o reliastra ./cli/cmd/reliastra` produces the binary and `go run ./cli/cmd/reliastra …` runs without installing. See cli/README.md for verification details. #### What you need - An HTTPS endpoint you are authorized to monitor. Any URL that returns a status code works; it does not have to be health-check-shaped. - An account. The trial starts on signup, no card. > **Authorization** > > Only monitor endpoints you own or are permitted to probe. A dependency that requires a credential can carry it in a header - the value is encrypted at rest and never returned by any API response. #### Add a dependency From the console: **Dependencies → Add**, paste the URL, choose an interval. Or from the CLI: ```bash reliastra login --email you@example.com reliastra deps add "Payments API" https://api.example.com/health --interval 60 ``` Or directly against the API: ```bash curl -sS https://api.reliastra.com/v1/dependencies \ -H "Authorization: Bearer $RELIASTRA_TOKEN" \ -H 'Content-Type: application/json' \ -d '{ "name": "Payments API", "endpoint_url": "https://api.example.com/health", "check_interval_seconds": 60, "expected_status_codes": [200] }' ``` _POST /v1/dependencies_ ```json { "id": "9f1c8b0e-6a2f-4f1e-9f3a-1c2d3e4f5a6b", "name": "Payments API", "endpoint_url": "https://api.example.com/health", "method": "GET", "expected_status_codes": [200], "timeout_seconds": 10, "check_interval_seconds": 60, "regions": ["us-east"], "is_active": true, "next_check_at": "2026-09-18T10:01:00Z" } ``` _201 Created_ #### The first observation The scheduler picks the dependency up on the next tick and writes one row per probe. There is nothing to enable and no agent to install - the probe is issued by RELIASTRA, not by you. ```bash reliastra checks recent --limit 5 EXECUTED (UTC) RESULT STATUS LATENCY DETAIL DEP 2026-09-18 10:01:03Z up 200 184 ms dep-9f1c ``` _GET /v1/checks/recent_ > **One failed row is not an incident** > > A single failed probe is recorded and nothing more. An incident opens after 2 consecutive failures from the single observation point and resolves after 2 consecutive successes. #### Follow an incident When the detector opens an incident, the incident - not the individual probe - is the thing to read. Its window, severity and root-cause field are one record: ```bash reliastra incidents list --status open reliastra incidents show reliastra incidents show --evidence ``` `--evidence` follows the record to the evidence artifact issued for it, so the window, the detector’s rule, the observation list and the integrity hashes are one command away rather than three. > **Correlation is not causation** > > `reliastra incidents correlate ` scores an overlapping dependency degradation against this window using five weighted signals under a published methodology version. An alignment between two timelines is what it reports, and that is all it reports. #### Retrieve evidence and verify it ```bash reliastra evidence list reliastra evidence show # prints the public verification URL reliastra evidence get --out incident.pdf reliastra verify --file incident.pdf ``` `verify` needs no account: it reads the public verification record, recomputes the SHA-256 of the bytes on disk and compares it with the checksum recorded at issue time. It exits 4 when they disagree, which is what makes it usable directly as a gate: ```yaml - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: { go-version: '1.23' } - run: go run ./cli/cmd/reliastra verify "$VERIFICATION_ID" --file incident.pdf ``` _GitHub Actions_ #### Between the terminal and the web The CLI and the console are two views of one record, and the CLI prints the address of the other view rather than describing what it would show. ```bash reliastra open incident --browser reliastra open verify # prints the URL; no account needed open "$(reliastra open evidence )" # printing is the default, so this composes ``` - Every identifier is the same in both places: an incident id from `incidents list` opens the same incident in the console. - `--json` prints the API’s own shape, so a script sees exactly what the API returned. - `--web` adds the console URL to the list commands; `evidence show` prints the verification URL unconditionally. - A self-hosted deployment points the links at its own origin with `--site-url` or `RELIASTRA_SITE_URL`. #### Where to go next - **CLI** — Every command, the exit codes, and how to use it in a pipeline. - **REST API** — The endpoints behind the CLI, scopes for API keys, pagination and error semantics. - **Configuration** — Intervals, expected status codes, secret headers, disabling without deleting. - **Incidents** — How the detector decides, what severity means, and how an incident closes. - **Evidence** — Turning a resolved incident into a record you can hand to someone. - **Verification** — What the public record proves, and what it deliberately does not. --- ### Concepts > Four ideas the rest of these docs assume: observation, confirmation, attribution, evidence. #### Observation An observation is one probe: RELIASTRA issued an HTTP request to your dependency and recorded what came back. It is a fact, not an interpretation, and every downstream conclusion is derived from a set of them. Probes are issued from **one observation point** today, every 300 seconds by default. What that means for a claim is stated on every surface that reports one. - `executed_at` `timestamp` — When the probe completed, in UTC. - `status_code` `integer | null` — The HTTP status returned. Null when the request never produced a response. - `latency_ms` `number` — Time to first byte. Not a transaction time - the probe reads headers and stops. - `is_up` `boolean` — The verdict the detector reads: status code in the expected set, no transport error. - `error_message` `string | null` — Transport error text, when the failure was at the connection level. > **An observation is about a path, not a vendor** > > A probe measures the route from RELIASTRA to that endpoint. It cannot see the vendor’s internal state, other customers, or other regions. Conclusions that need those are not available from this data and are never drawn from it. #### Confirmation One failure is a data point; a run of them is a fault. The detector is a pure function of the stored observations - no clock reads, no randomness, no heuristics - so a decision can be replayed from the rows and reproduced exactly. - **Opens an incident** — 2 consecutive failed checks. Rule id `single.consecutive_failures`. - **Resolves an incident** — 2 consecutive successful checks. Rule id `single.consecutive_successes`. - **Backed out** — A failure run that does not reach the threshold closes nothing and opens nothing. It stays in the record as observations. The rule identifier and the reason string are stored with the incident and printed in the evidence artifact, so a reader can tell which rule fired without reading source code. #### Attribution Attribution asks whether an incident overlaps degradation on a dependency you have configured. Five normalised signals are combined with fixed weights and the result is classified against two thresholds. It is arithmetic, not a model, and the methodology version is stamped on every result. | Classification | When it is returned | | --- | --- | | vendor_failure | Confidence ≥ 75 | | multi_cause | Confidence ≥ 50 and < 75 | | infrastructure_issue | Below 50 and RELIASTRA’s own probes were degraded | | unknown | Anything else. This is a result, not an error. | > **Correlation, not causation** > > No classification means "the vendor caused your outage". A high score means two timelines lined up closely with the signals the engine measures. Treat it as evidence to weigh, and read the weights in the Methodology guide before quoting a score. #### Evidence An evidence record is the compiled artifact for one incident: the window, the observations inside it, the arithmetic behind the SLA figures, the attribution result, and a checksum over the payload. It is generated once and retained, not recomputed on read. The record is verifiable by someone who does not have an account - that is the point of it. A public endpoint returns the hashes, the signature and the procedure to check them. --- ### Configuration > Every field on a dependency, its default, and the two that can lock you out of your own endpoint. #### Dependency fields - `name` `string, ≤150` — Appears in incidents, evidence records and notifications. Name it the way your team refers to it. - `endpoint_url` `string` — Must start with http:// or https://. Any path is valid. - `method` `GET | POST | PUT | PATCH | DELETE | HEAD` — Default GET. - `headers` `object | null` — Sent with every probe. Authorization values are encrypted at rest and never returned by an API response - responses carry `has_headers` instead. - `expected_status_codes` `array` — Default [200]. Any status outside this set counts as a failure. A 401 you did not expect is a failure, which is usually what you want. - `timeout_seconds` `1–300` — Default 10. The probe gives up and records the timeout as a failure. - `check_interval_seconds` `1–86400` — Default 300. Shorter intervals detect faster and produce more rows; retention is by age, not by row count. - `regions` `array, min 1` — The scheduler label for the worker that runs the probe. One point is deployed today; this is not a geographic spread and the API does not offer a choice that changes the answer. - `alert_threshold_ms` `integer | null` — Latency above this value is flagged on the dependency record. Null disables it. It does not open an incident on its own. - `is_active` `boolean` — Default true. Setting false stops probing and preserves history - use this instead of deleting when you are unsure. #### Secret headers ```json { "name": "Internal gateway", "endpoint_url": "https://gw.internal.example.com/healthz", "headers": { "Authorization": "Bearer ", "X-Probe-From": "reliastra" }, "expected_status_codes": [200], "timeout_seconds": 5 } ``` _A dependency that authenticates its health endpoint_ > **Values are write-only** > > A read of a dependency returns `has_headers: true`, never the values. There is no endpoint that returns them, including for administrators. Rotate by sending a new `headers` object; there is no way to read the old one back. #### Choosing an interval The interval is the resolution of every claim made from this data. At 300 seconds, an outage shorter than that can exist entirely between two probes and leave no trace. Shrinking the interval narrows that blind spot; it does not close it. | Interval | Blind spot | Use it for | | --- | --- | --- | | 30s | Outages under ~30s | A dependency your product calls on every request | | 60s | Outages under ~1m | Checkout, auth, anything with a hard SLA | | 300s (default) | Outages under ~5m | Background syncs, dashboards, internal tools | | 3600s | Outages under ~1h | Vendors you report on monthly, not daily | Detection latency is the interval multiplied by the failure threshold: at 300 seconds and a threshold of 2, an incident opens roughly 10 minutes after the dependency actually broke. #### Updating and removing ```bash # Pause probing without losing history reliastra deps list --json | jq -r '.[] | select(.name=="Payments API") | .id' \ | xargs -I{} curl -sS -X PATCH "https://api.reliastra.com/v1/dependencies/{}" \ -H "Authorization: Bearer $RELIASTRA_TOKEN" \ -H 'Content-Type: application/json' -d '{"is_active": false}' ``` > **Deleting is permanent** > > Deleting a dependency removes its observations. Incidents and already-issued evidence records survive, because a record you have handed to a vendor cannot be recalled - but you lose the ability to show what it was measuring. --- ### Monitoring > What a probe does, what it records, and the four things it structurally cannot see. #### What a probe does 1. Resolves the endpoint and opens a connection. 2. Sends the configured method, headers and no body. 3. Reads the response status and headers, then closes. 4. Writes one row: timestamp, status, latency, verdict, error. The probe reads headers and stops. It does not download the body, so a large JSON payload does not inflate the latency it reports or the bill it costs. #### Observation states - **up** — The status code was in `expected_status_codes` and no transport error occurred. - **failed** — Either the status was outside the expected set, or the request produced no response (DNS, TLS, connection, timeout). - **blocked** — A failure inside the observation path itself - the probe could not be trusted. Blocked observations are excluded from availability arithmetic and counted separately. > **A failed probe is not a failed vendor** > > An observation records what happened on this path, at this minute. It is the detector’s job - not the probe’s - to decide whether that amounts to an incident. #### What monitoring cannot see - `Vendor-internal state` — The probe is outside the vendor’s network. It sees what the vendor’s edge returned. - `Other customers` — A 200 from this path does not mean every caller got a 200. It means this one did. - `Erratic paths` — A dependency that fails for one in twenty requests may never produce the consecutive failures the rule needs. Reported latency distribution is the signal to read in that case. - `Anything behind your auth` — If the endpoint requires a session you cannot supply, the probe cannot reach what your application reaches. #### Reading latency Latency is the wall-clock time from issuing the request to receiving the complete response, redirect hops included, measured from one observation point. It therefore contains DNS, TLS and the network path between RELIASTRA and the endpoint - none of which your users experience identically. Use it to detect change over time on the same dependency, not to rank one dependency against another. ```bash reliastra checks recent --limit 200 --json \ | jq '[.[] | select(.is_up)] | (map(.latency_ms) | sort) as $l | { count: ($l|length), p50: $l[($l|length*0.5|floor)], p95: $l[($l|length*0.95|floor)] }' ``` _Distribution rather than a single number_ --- ### Incidents > The detection rule, the fields on an incident, and what resolution does and does not mean. #### The rule ```text if current.is_up is false: failures = trailing run of failures ending at current if failures >= 2 and no incident open: open incident, started_at = first failure of the run else: successes = trailing run of successes ending at current if successes >= 2 and incident open: resolve incident ``` _The decision, in full_ The incident’s `started_at` is the **first** failure of the run, not the check that crossed the threshold. An incident window therefore covers the outage the dependency actually had, rather than starting a check or two late. ```json { "rule": "single.consecutive_failures", "reason": "2 consecutive failed check(s); 2 required", "confirmed": true, "consecutive_failures": 2, "required": 2, "run_started_at": "2026-09-18T09:55:00Z" } ``` _Detection metadata, stored with the decision_ #### Incident fields - `started_at / resolved_at` `timestamp` — The outage window. `resolved_at` is null while the incident is open. - `severity` `critical | major | minor` — Set when the incident opens and editable afterwards. - `status` `open | resolved | false_positive` — `false_positive` is a first-class value: if a run of failures was your own maintenance, saying so keeps the data honest instead of deleting the row. - `root_cause` `vendor_failure | network_issue | config_error | unknown` — Your classification. It is separate from the attribution score and can disagree with it. - `evidence_status` `pending | ready | failed | skipped` — Where artifact generation is up to, so no surface has to render a bare "none". #### Correlating dependencies When several of your dependencies degrade at once, the interesting question is whether they share one cause. Correlation records that a second dependency was failing inside a window around the incident, with the method and confidence stored on the link. ```bash reliastra incidents correlate 9f1c8b0e-… # or, on the API: curl -sS -X POST "https://api.reliastra.com/v1/incidents/9f1c8b0e-…/correlate" \ -H "Authorization: Bearer $RELIASTRA_TOKEN" -H 'Content-Type: application/json' \ -d '{"correlated_dependency_id":"d4e5…","time_window_seconds":300,"correlation_method":"manual"}' ``` > **Careful** > > A correlation is a recorded observation about two timelines. Two dependencies failing together is not evidence that one caused the other, and RELIASTRA does not present it that way. #### What resolution means Resolution means 2 consecutive successful probes. It does not mean the vendor confirmed anything, that the underlying cause was fixed, or that the service is healthy - it means this path responded successfully twice in a row. --- ### Evidence > What the artifact contains, how it is generated, and how long it is retained. #### Generation An evidence record is generated for a resolved incident. Generation is asynchronous: `evidence_status` moves from `pending` to `ready`, or to `failed` with a reason in `evidence_error`. A record is written once and never silently regenerated - if you need it rebuilt, `POST /v1/evidence/{report_id}/regenerate` creates a new one and records that it was rebuilt. #### What is in the record 1. **Incident record** - the window, the dependency, severity, status, and the observation topology the measurements came from. 2. **Detection record** - the rule identifier, its reason string, and the run that satisfied it. 3. **Incident window measurements** - checks in window, successes, failures, blocked probes excluded, availability, longest failure run, latency, first and last observation. 4. **SLA impact calculation** - target uptime, measured availability, degradation impact, measured downtime, and the arithmetic basis for each. 5. **Observed latency and failures** - the chart, drawn from the rows in the appendix. 6. **Rolling 24-hour health** - context, labelled as context, never as the incident window. 7. **Correlated dependency events** - the other dependencies that failed nearby, by name. 8. **Deterministic attribution** - classification, confidence score, methodology version. 9. **Documented observations** - every observation in the window, individually, with timestamp, result, latency and status. 10. **Authenticity, retention and verification** - the payload hash, the document checksum, the verification URL, the signing status. #### Integrity - **Evidence data hash** — SHA-256 over the canonical payload - the incident’s facts as data, not as a rendered PDF. - **Document checksum** — SHA-256 over the rendered bytes. A PDF cannot contain the hash of itself, so the checksum lives on the record, not inside the document. - **Signature** — Ed25519 over the canonical payload bytes, when the deployment has a signing key configured. The public key is at `/v1/verify/keys`. > **Unsigned is stated, not hidden** > > A deployment with no signing key issues unsigned artifacts and the document says so on its face. That is deliberate: a missing signature that looks like a present one is worse than no signature at all. #### Retention and sharing Records are retained for 365 days from issue. Sharing is by token: a recipient opens the artifact and its verification page without an account. The token is unguessable and carries capability, so treat a shared link as you would the document. ```bash reliastra evidence list reliastra evidence get 4b2e… --out incident-2026-09-18.pdf ``` --- ### Verification > How a third party checks an artifact without trusting RELIASTRA, and without an account. #### The verification endpoint ```bash curl -sS https://api.reliastra.com/v1/verify/8Kd2xQ… ``` _No authentication. Cache-Control: no-store._ ```json { "found": true, "incident_id": "9f1c8b0e-…", "dependency_id": "d4e5f6a7-…", "time_window": { "start": "2026-09-18T09:55:00+00:00", "end": "2026-09-18T10:06:00+00:00" }, "data_hash": "3f9a…", "report_checksum": "0c72…", "methodology_version": "v1.0", "created_at": "2026-09-18T10:07:12+00:00", "authenticity": { "signed": true, "algorithm": "Ed25519", "signature_covers": "canonical payload bytes (the value hashed into data_hash)", "public_keys": "/v1/verify/keys" } } ``` _200 OK_ > **What the record does not contain** > > The payload itself. The endpoint proves what a payload must hash to; it does not restate the incident. That is why a verifier who has only the token learns nothing about the customer. #### Verifying a document you were handed 1. **Read the verification URL or QR from the document** — Both point at `/reports/{verification-id}`. 2. **Fetch the record and compare the checksum** — The record returns the SHA-256 of the rendered bytes. Compute the same hash over the file you hold. ```bash sha256sum incident.pdf ``` 3. **Check the signature, if the record reports one** — Fetch the public key, then verify the Ed25519 signature over the canonical payload bytes. The signature covers the payload, not the PDF, so a re-render that changes font embedding does not invalidate it. ```bash curl -sS https://api.reliastra.com/v1/verify/keys ``` #### As a CI gate `reliastra verify` returns a status code rather than a sentence, so it can gate a pipeline without a wrapper. Exit 4 means the claim did not hold - including when the verification service could not be read, because "we could not check" must not be reported as a pass. ```yaml - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: { go-version: '1.23' } - name: Verify the evidence record run: go run ./cli/cmd/reliastra verify "${{ vars.VERIFICATION_ID }}" --file incident.pdf ``` _.github/workflows/evidence.yml_ --- ### REST API > Authentication, the endpoints that matter, pagination and rate limits. #### Authentication Two credentials work on the API. A session token from `/v1/auth/login` acts as the account. An API key acts for a specific set of scopes and is what a service or a pipeline should use. ```bash # Issue a scoped key (shown once) reliastra keys create ci-bot --scopes read:checks,write:dependencies,read:incidents,read:evidence # Use it export RELIASTRA_TOKEN=rel_… curl -sS https://api.reliastra.com/v1/dependencies -H "Authorization: Bearer $RELIASTRA_TOKEN" ``` | Scope | Grants | | --- | --- | | read:checks | Read observations | | write:dependencies | Create, update and delete dependencies | | read:incidents | Read incidents and correlations | | read:evidence | Read evidence records and download artifacts | #### Endpoints | Method and path | What it does | | --- | --- | | POST /v1/auth/login | Exchange email and password for an access and refresh token | | POST /v1/auth/refresh | Rotate an expired access token | | GET /v1/users/me | The authenticated account | | GET /v1/dependencies | List dependencies (`limit`, `cursor`) | | POST /v1/dependencies | Create one | | GET /v1/dependencies/{id} | Read one | | PATCH /v1/dependencies/{id} | Update one | | DELETE /v1/dependencies/{id} | Delete one and its observations | | GET /v1/dependencies/{id}/results | Observations for one dependency | | GET /v1/dependencies/{id}/history | Aggregated history over a window | | GET /v1/checks/recent | The most recent observations across dependencies | | GET /v1/incidents | List incidents (`limit`, `cursor`, `status`, `severity`, `dependency_id`) | | GET /v1/incidents/{id} | One incident with its correlations | | PATCH /v1/incidents/{id} | Set status, severity, root cause or description | | POST /v1/incidents/{id}/correlate | Record a correlated dependency | | GET /v1/incidents/{id}/evidence | The evidence record for this incident | | GET /v1/evidence | List evidence records | | GET /v1/evidence/{id} | One record: checksum, verification id and URL, payload hash, and a one-hour signed `download_url` | | GET /v1/evidence/{id}/artifact | The rendered artifact itself, streamed. Use this from a script | | GET /v1/evidence/{report_token}/download | Public gate download by token, for a shared record | | POST /v1/evidence/{id}/regenerate | Rebuild an artifact from its incident | | GET /v1/verify/{verification_id} | Public verification record. No authentication. | | GET /v1/verify/keys | Public signing keys, in JWK form | | GET /v1/vendors | The public observatory index | | GET /v1/vendors/{name} | One vendor’s public record | | GET\|POST /v1/webhooks | List or create webhook subscriptions (session only) | | GET /v1/api-keys | List keys (prefixes only; needs `read:api_keys`) | | POST /v1/api-keys | Issue a key. The full value is returned once. | #### From an artifact to its verification A resolved incident produces an evidence record. `GET /v1/evidence/{id}` returns everything needed to check the artifact it issued, including the public verification id and URL that are printed inside the document itself: ```json { "id": "7c1d0a5f-…", "incident_id": "9f1c8b0e-…", "checksum": "0c72…", // SHA-256 of the rendered document "data_hash": "3f9a…", // SHA-256 of the canonical facts payload "verification_id": "8Kd2xQ7mB4pL", "verification_url": "https://reliastra.com/reports/8Kd2xQ7mB4pL", "methodology_version": "2.0", "signed": false, // this deployment issues unsigned artifacts "expires_at": "2027-09-04T09:12:00Z" } ``` _GET /v1/evidence/{id}_ `verification_url` opens a page that needs no account, and `GET /v1/verify/{verification_id}` is the same record as JSON. `GET /v1/verify/keys` publishes the Ed25519 public keys for deployments that sign, so a third party can check a signature without trusting either endpoint. #### What an API key can and cannot reach Keys are denied by default. A key can reach the dependency, observation, incident and evidence surfaces its scopes allow; it cannot reach identity, account, webhook or key-management surfaces at all, whatever scopes it carries. That boundary is deliberate: a leaked key must not be able to mint credentials or read the account. | Surface | API key | Session | | --- | --- | --- | | Dependencies, observations, incidents, evidence | With the matching scope | Yes | | Webhook configuration | No | Yes | | API key management | No (unless the key carries `read:api_keys`) | Yes | | Account and identity | No | Yes | > **Programmatic reads are still first-class** > > `GET /v1/dependencies/{id}/results`, `GET /v1/incidents?dependency_id=…` and `GET /v1/evidence/{id}` cover the whole read path a service needs. Use the CLI or the console for webhooks and keys, where a human is making the change. #### Pagination ```json { "items": [ … ], "next_cursor": "eyJpZCI6…", "has_more": true } ``` _GET /v1/incidents?limit=2_ Pass `next_cursor` back as `cursor` to continue. Cursors are stable for a query shape, not across filters - change the filter and start again. #### Errors | Status | Meaning | What to do | | --- | --- | --- | | 400 | Validation failed. `detail` lists each bad field. | Fix the request. The field name is in the message. | | 401 | No credential, or the token expired. | Refresh, or issue a new key. | | 403 | The credential lacks the scope. | Check the scopes on the key. | | 404 | No such resource, or not yours. | Confirm the id came from your own list call. | | 429 | Rate limited. | Back off. Paginated list endpoints are the usual cause. | | 503 | A dependency of the API itself is unreadable. | Retry. Do not treat this as an empty result. | > **An empty list and a failure are different** > > `{"items": []}` means you have none. A non-2xx means the question could not be answered. Code that collapses the two will eventually report "no incidents" during an API outage. #### Schema The FastAPI-generated OpenAPI document is served by the API itself and is the authoritative field list - these docs quote it rather than replacing it. ```bash curl -sS https://api.reliastra.com/openapi.json | jq ".paths | keys" ``` --- ### CLI > Install, authenticate, read dependencies and incidents, retrieve evidence, and gate a pipeline on verification. #### Install ```bash npm install -g reliastra # or pipx install reliastra # from source go install github.com/ReliaAstra/Reliastra/cli/cmd/reliastra@latest reliastra --help ``` The npm and pipx packages are thin installers that download the verified binary on first run and verify SHA-256 against the release checksums.txt (see cli/README.md). Go 1.23 or newer to build from source, and the module has no dependencies beyond the standard library. From a checkout, `go run ./cli/cmd/reliastra …` runs without installing. `--version` prints the version, and every command and subcommand answers `--help`, including mid-command (`reliastra evidence get --help`). #### Authenticate ```bash # A session for this machine reliastra login --email you@example.com # Or store an API key, which is what a service should use reliastra login --token rel_… ``` Credential precedence is `--token` → `RELIASTRA_TOKEN` → the config file, and `whoami` prints which one was used - the first question in any support thread. A password is never accepted as a flag: it comes from a prompt, or from `RELIASTRA_PASSWORD` in automation, so it cannot reach shell history or a process listing. A session token can read the account; an API key cannot, by design - identity and account surfaces are closed to keys. The CLI detects which credential it holds and reports the right thing rather than sending you to re-login for a problem re-login cannot fix. ```bash reliastra doctor ``` _Something is wrong, and you want to know what_ `doctor` checks the config file (including its permissions), the credential and the API, and names which of them failed. It needs no valid credential to be useful: “the API is unreachable” and “your credential was rejected” have different fixes and different exit codes. #### Commands | Command | What it does | | --- | --- | | `reliastra login` / `logout` / `whoami` | Session and credential handling | | `reliastra doctor` | Check config, credential and API, and name the failure | | `reliastra deps list` / `show ` / `add` / `rm` | What is being probed, and one dependency in full | | `reliastra checks recent` | Raw observations, newest first (`--dependency `) | | `reliastra incidents list` / `show ` / `correlate ` | Incidents, their windows, and correlation scores | | `reliastra evidence list` / `show ` / `get ` | Evidence records and artifact download | | `reliastra verify ` | Check a document against the public record. No account needed | | `reliastra keys list` / `create` / `rm` | API keys for CI and other services | | `reliastra obs list` / `show ` | The public observatory, unauthenticated | | `reliastra open [id]` | Print (or open) the web page for a resource | Every command accepts `--json`, and the JSON is the API’s own shape: no renamed fields, no dropped nulls, no derived values. `--quiet` drops the explanatory lines. ```bash reliastra checks recent --json | jq '[.[] | select(.is_up == false)] | length' reliastra deps list --json | jq -r '.[] | "(.name) (.endpoint_url)"' reliastra incidents list --status open --web ``` #### Evidence and verification ```bash reliastra incidents show --evidence reliastra evidence show # prints the public verification URL reliastra evidence get --out incident.pdf --payload reliastra verify --file incident.pdf ``` `evidence get` writes the artifact and prints the SHA-256 of the bytes it wrote, computed locally - comparing that with the recorded checksum is the only way to know the transfer was faithful. `verify` is unauthenticated on purpose: it serves somebody who was handed a document and has no account. > **Failing closed** > > A missing record, a changed file, a hash mismatch and a verification service that cannot be read all exit 4. “We could not check” must never be reported as a pass, so it is not. #### Terminal and web ```bash reliastra open incident --browser reliastra open verify # public page, no account needed open "$(reliastra open evidence )" # printing is the default, so this composes ``` `--web` adds the console URL to `deps list`, `incidents list` and `evidence list`. `--site-url` (or `RELIASTRA_SITE_URL`) points the links at a self-hosted origin. #### Exit codes | Code | Meaning | | --- | --- | | 0 | Success | | 1 | Usage error, or invalid configuration | | 2 | The API returned an error (validation, not found, upstream) | | 3 | Authentication required, rejected, or expired | | 4 | A verification claim did not hold | | 5 | Authenticated, but not permitted to make this call | | 6 | The API could not be reached at all | A pipeline can therefore tell a rejected credential (3) from a missing scope (5) from a network failure (6) without parsing prose. Errors are classified and printed without stack traces; a 403 names the scope that was missing. ```bash reliastra verify "$VERIFICATION_ID" --file evidence.pdf # 0 - the file matches the record # 4 - a missing record, a changed file, or a service that could not be read ``` _Verify in a pipeline_ #### Configuration | Variable | Effect | | --- | --- | | `RELIASTRA_TOKEN` | Bearer token or API key for this invocation | | `RELIASTRA_API_URL` | API base URL (default `https://api.reliastra.com`) | | `RELIASTRA_SITE_URL` | Web origin used for links (default `https://reliastra.com`) | | `RELIASTRA_CONFIG` | Path to the config file | | `RELIASTRA_PASSWORD` | Password for a non-interactive `login` | The config file is written with mode 0600 in a 0700 directory. `logout` revokes the session server-side and removes the file even if the API cannot be reached, so an outage cannot leave a token on disk. No credential is ever printed: `whoami` and `doctor` report where a credential came from, never its value. --- ### Webhooks > Push incidents and evidence into your own systems instead of polling for them. #### Create a subscription ```bash curl -sS -X POST https://api.reliastra.com/v1/webhooks \ -H "Authorization: Bearer $RELIASTRA_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"url":"https://ops.example.com/hooks/reliastra","events":["incident.opened","incident.updated","incident.resolved","evidence.ready"]}' ``` #### Events - **incident.opened** — The detector confirmed a failure run. Carries the incident id, dependency id, window and the rule that fired. - **incident.updated** — A field on an open incident changed by hand (severity, status, root cause, description). Carries the field names that changed. - **incident.resolved** — The recovery rule was satisfied. Carries the window and the root-cause field as they stand at resolution. - **evidence.ready** — An artifact was generated and is retrievable. Carries the report id, the verification id and the document checksum, so a consumer can act on it without a second lookup. > **Careful** > > The API accepts five further values - `vendor.degraded`, `vendor.down`, `vendor.recovered`, `sla.breach` and `check.failed` - because they are part of the event enum. Nothing emits them yet, so a subscription that names one stores successfully and never fires. They are listed here rather than omitted: a silent no-op is worse than a documented gap. ```json { "event": "incident.opened", "timestamp": "2026-09-18T10:06:02.412+00:00", "data": { "incident_id": "9f1c8b0e-…", "dependency_id": "d4e5f6a7-…", "started_at": "2026-09-18T09:55:00Z", "severity": "major", "status": "open", "detection": { "rule": "single.consecutive_failures", "required": 2 } } } ``` _incident.opened - body_ | Header | Value | | --- | --- | | `X-Reliastra-Event` | The event type, so a consumer can route without parsing the body | | `X-Reliastra-Delivery` | A unique delivery id - deduplicate on this, not on the body | | `X-Reliastra-Signature` | `sha256=` over the raw body, when the subscription has a secret | - `incident.opened` is sent once, when the detector confirms a failure run. A repeat call for an incident that is already open dispatches nothing. - `incident.updated` carries the field names that changed (`"changed": ["severity"]`), and is not sent when an update resolves the incident. - `incident.resolved` carries the window and the root-cause field as they stand at resolution. - `evidence.ready` is sent after the artifact exists and is retrievable, with the report id, the verification id and the document checksum. #### Delivery - A 2xx within ten seconds marks the delivery successful. Anything else is recorded against the delivery and retried on a fixed backoff: 1m, 5m, 15m, 1h, 3h, then permanently failed. - Delivery happens off the request that caused it, on the task queue, so a slow consumer cannot affect incident detection or evidence generation. - Every delivery carries a delivery id in a header, so a consumer can deduplicate rather than process twice. - `GET /v1/webhooks/{id}/deliveries` lists recent attempts with their response codes, which is how you diagnose a consumer that has started failing. - `POST /v1/webhooks/{id}/test` sends a synthetic delivery, in the same envelope, so one parser covers both paths. > **Treat the body as untrusted input** > > Verify the delivery against the shared secret before acting on it, and never let a webhook body trigger a privileged operation directly. --- ### Methodology > The canonical explanation of every rule and number RELIASTRA reports, and the limits of each. #### Observation topology Probes are issued from **one observation point**. A `region` value appears on every observation because the scheduler labels the worker that ran the probe; under the deployed topology it carries no confirmation weight. > **No regional claims** > > Nothing on this site or in any record claims multi-region agreement, because there is no fleet of independent points to agree. If you have read otherwise elsewhere, that text is wrong and this page supersedes it. #### Detection Under a single observation point there is no second opinion available, so the only honest confirmation signal is persistence: 2 consecutive failed checks open an incident, 2 consecutive successes resolve one. | Property | Value | | --- | --- | | Failure rule | `single.consecutive_failures`, threshold 2 | | Recovery rule | `single.consecutive_successes`, threshold 2 | | Determinism | Pure function of stored observations. Replayable; no clock reads, no randomness. | | Incident start | The first failure of the qualifying run, not the check that crossed the threshold. | | Backfill | None. Missed probes are missing, not reconstructed. | #### Attribution Five normalised signals are combined with fixed weights. The weights sum to exactly 1, which is what makes a score reproducible. | Signal | Weight | Question it answers | | --- | --- | --- | | Temporal overlap | 0.20 | Did the dependency degrade inside the incident window? | | Endpoint overlap | 0.25 | Was the failing endpoint one this dependency serves? | | Latency correlation | 0.25 | Did latency move with the failures? | | Error pattern | 0.15 | Are the errors one coherent class, or several? | | Infrastructure baseline | 0.15 | Were RELIASTRA’s own probes healthy while this happened? | Classification follows the score: **≥75** `vendor_failure`, **≥50** `multi_cause`, and below 50 either `infrastructure_issue` or `unknown`. Every result carries `methodology_version`. #### What RELIASTRA refuses to claim - Causation from correlation. A score is an alignment between timelines. - Vendor-wide outages from one path. A single observation point measures one route. - Availability without a denominator. An availability figure is always shown with the observation count behind it, and prints as **insufficient data** at zero. - A number for something not measured. An unmeasured value renders as a named sentinel, never as `0` or `100%`. - Reconstructed history. If probes were missed, the record says so. > **Where the limits are written down** > > The public observatory states the scope of every figure it reports, and the research corpus documents the audits that found where earlier versions of these pages overstated their own data. --- ### Security > What RELIASTRA stores, what it encrypts, and what the public surfaces can expose. #### What is stored - `Endpoint URLs` — Stored as configured. They appear in incident records and evidence artifacts for your account. - `Secret header values` — Encrypted at rest. Never returned by any API response; reads report `has_headers` only. - `Observations` — Timestamp, status, latency, verdict. Not response bodies - the probe never reads them. - `Evidence artifacts` — Rendered documents, retained 365 days and reachable only by token. > **Response bodies are never captured** > > The probe reads status and headers and closes the connection. There is no path by which a response payload reaches RELIASTRA storage. #### Credentials Each credential class is protected by the mechanism that fits it. Nothing here is a hash of a value RELIASTRA can later read back, except the dependency headers, which are encrypted rather than hashed because the probe has to send them. - `Secret request headers` `Fernet` — Encrypted at rest with Fernet (AES-128-CBC authenticated with HMAC-SHA256) under a key held in configuration, not in the database. Stored as an opaque ciphertext column; reads report `has_headers` only. Encryption rather than hashing, because the probe must send the real value on every check. - `API keys` `SHA-256 + prefix` — Stored as a display prefix plus a SHA-256 hash, with a scope list, an optional expiry and a last-used timestamp. The full value is returned exactly once, at creation; there is no path that reads it back, so a lost key is replaced, not recovered. - `Passwords` `bcrypt` — Hashed, never stored or logged in plaintext. - `Session refresh tokens` `rotating` — Short-lived, and rotated on every refresh. Presenting an already-revoked refresh token is treated as theft, not as a retry: the whole token family is revoked, so a stolen token that is replayed after the legitimate client has moved on ends the session rather than extending it. - `Verification tokens` `capability` — Carry capability for one artifact. They are unguessable, and regenerating a record supersedes the old one. - `Admin surfaces` `separate` — Authenticated on a different path with a different token audience from customer accounts. A customer session cannot be presented to the admin surface. > **Scopes are enforced per request** > > An API key carries the scopes it was created with, and the API checks them on the request rather than at the door. A key with `read:checks` cannot read incidents, and narrowing a key is the right response to a script that only needs one thing. #### In transit - Every public surface is HTTPS only. HTTP is redirected, and the apex sets `Strict-Transport-Security` with `includeSubDomains` and `preload` at a one-year max-age. - Credentialed CORS is never paired with a wildcard origin. The browser refuses that combination outright, so the API is configured with an explicit origin list - which also means an unknown origin cannot read an authenticated response. - Credential values are write-only over the API. A header secret you configure cannot be read back by any response, so it does not travel back out over a connection it did not need to cross. #### Retention - **Evidence artifacts** — Retained 365 days from generation, then expired. The window is a configured value, and the public verification URL for a record stops resolving when the record does. - **Observations** — Kept for the retention window your plan carries. Reducing a plan does not delete history already inside the window. - **Public incident records** — Published for the evidence-retention window and then removed. The observatory describes these pages as expiring rather than permanent, because they are. > **A retention figure that disagreed with the code** > > Retention was once hard-coded at 90 days while the documentation said 365. The code now reads the configured value and the two are checked against each other, because a retention promise a customer relies on is exactly the kind of number that must not drift. #### What is public The observatory publishes measurements for endpoints RELIASTRA probes as part of its own public record. Customer dependencies are never included in it. Nothing in your account appears on any public page unless you explicitly publish it. The verification endpoint returns hashes and a key reference for one artifact, not the incident. A verifier learns that a document is intact, not what it says. #### Reporting a problem Security reports go to [security@reliastra.com](mailto:security@reliastra.com). Include a reproduction and the smallest amount of data that demonstrates the issue; do not include customer data you are not authorized to share. ## Glossary (canonical definitions) ### External Dependency Intelligence External Dependency Intelligence is the practice of continuously observing the third-party APIs and services your software depends on - from outside both your stack and the vendor’s - and turning those observations into attributable, timestamped records of behaviour. Problem: Your own monitoring tells you that your checkout is failing. It cannot tell you whether the cause is your code or the payment provider three hops away whose status page still reads “operational”. Why it matters: Without an independent record, every vendor incident becomes an argument about whose system failed. With one, it becomes a comparison of two measured timelines. Example: At 14:02 your error rate spikes. Over the same window, RELIASTRA’s own probe of your payment provider’s endpoint starts timing out while its probe of your health endpoint stays flat. The dependency window is documented before anyone finishes arguing about it. RELIASTRA approach: RELIASTRA checks each configured dependency on a fixed interval from its own infrastructure, records latency, status codes and outcomes with timestamps, applies a deterministic rule before declaring incidents, and binds evidence reports to checksums you can verify. URL: https://reliastra.com/glossary/external-dependency-intelligence ### Dependency Monitoring Dependency monitoring is the continuous probing of external endpoints your product relies on - APIs, auth providers, payment gateways, cloud services - to detect degradation before your users report it. Problem: Vendor status pages are written by humans, after the fact, and scoped to incidents the vendor chose to declare. Timing is approximate and the record belongs to the counterparty. Why it matters: A dependency that fails silently breaks your product while every internal dashboard stays green. Direct measurement closes that blind spot. Example: Your auth provider starts returning 500s intermittently. Scheduled checks record exactly which probes failed, with timestamps and latencies, separating a single lost request from a fault window that two consecutive checks confirm. RELIASTRA approach: One scheduler dispatches one check task per dependency through a message broker to a worker. Every result carries the region label of the worker that ran it, and a detection policy parameterised by observation topology decides the confirmation rule. Recovery requires consecutive successes, so flapping does not page you twice. URL: https://reliastra.com/glossary/dependency-monitoring ### Incident Attribution Incident attribution is the process of assigning an observed failure to its most likely origin - your infrastructure or a specific external dependency - using correlated timelines rather than inference. Problem: An outage you caused and an outage your vendor caused look identical from inside your own monitoring. Both present as your service failing. Why it matters: Correct attribution decides where engineers look first, what gets rolled back, what gets escalated to a vendor, and what evidence supports an SLA claim. Example: Your incident window (14:02–14:19) overlaps a period in which the dependency was independently observed failing from RELIASTRA’s own infrastructure. That overlap is a fact about two measured timelines - not a finding about cause. RELIASTRA approach: RELIASTRA keeps your incident history and the dependency’s observation history on the same timeline, applies a deterministic correlation engine with confidence levels, and refuses to claim causation - only correlated, timestamped evidence. URL: https://reliastra.com/glossary/incident-attribution ### SLA Evidence SLA evidence is an independent, timestamped record of a vendor’s observed behaviour during a failure window - the kind of artifact you can attach to a service-credit conversation governed by your contract with that vendor. Problem: Screenshots and Slack messages do not settle credit disputes. The vendor’s own status page is written by the counterparty to the claim. Why it matters: An SLA claim needs an independent record of the window. A vendor status page is written by the counterparty to the claim. Example: A 17-minute degradation with every scheduled observation in the window, the detection record that confirmed it and the correlated incident, compiled into one artifact with a verifiable checksum. RELIASTRA approach: When an incident resolves, RELIASTRA compiles the retained observations, the detection rule that applied and the attribution result into one record. Records carry the producing account binding and a checksum, and can be verified by a third party without disclosing endpoints or credentials. URL: https://reliastra.com/glossary/sla-evidence ### Vendor Reliability Vendor reliability is the measured consistency of a third-party service - uptime, latency distribution and incident frequency - observed independently over stated windows and origin sets. Problem: Self-reported “99.99% uptime” figures rarely state the window, the origin set, or how outcomes were classified. A number without those is marketing. Why it matters: Reliability determines architecture (retries, fallbacks, multi-vendor), contract terms (SLA clauses, credits), and incident readiness (who gets paged). Example: Two payment providers both claim four nines. Independent 30-day measurement shows one at 99.98% with a 340 ms p95 and no confirmed fault window, the other at 99.91% with three. The comparison is only meaningful because the window and the observation count are printed beside each figure. RELIASTRA approach: RELIASTRA publishes aggregates only for vendors made public, always with the window, the observation count and the observation point stated. Observatory pages show availability, latency and incident history as measured - never mirrored from a status page. URL: https://reliastra.com/glossary/vendor-reliability ### Dependency Telemetry Dependency telemetry is the retained record of every probe against a dependency - timestamp, the region label of the worker that issued it, latency, status code and outcome - from which availability, latency and incident figures are derived. Problem: An uptime percentage without its underlying observations cannot be audited. You cannot distinguish “vendor down” from “we never ran the probe”. Why it matters: Telemetry is what makes a reliability claim inspectable. It separates target failures (the vendor failed) from infrastructure failures (the probe could not run) and transitional states (never checked, queued, executing). Example: A gap in the chart is labeled explicitly: policy-blocked target, dispatch failure, or dead scheduler - three different causes with three different owners, never collapsed into “no data”. RELIASTRA approach: Each stored result records the region label, outcome, status code, latency and execution time. Missed probes are never backfilled: a gap stays a gap. Retention is 90 days on the Developer plan, and 24 hours once a trial ends without a subscription. URL: https://reliastra.com/glossary/dependency-telemetry ### Infrastructure Evidence Infrastructure evidence is any verifiable record of how systems behaved during a time window - probe results, incident timelines, correlation outputs - preserved with enough context (timestamps, origins, checksums) to be relied upon later. Problem: Logs rotate, dashboards are mutable, and memories of an incident decay within days. By the time a credit conversation or postmortem happens, the record is gone or disputed. Why it matters: Evidence converts a transient outage into a durable, checkable artifact: postmortems cite it, vendors respond to it, contracts reference it. Example: A record covering a 22-minute window: every observation in it, the detection record with the rule id that applied, the correlated incident, and a SHA-256 checksum over the payload plus an Ed25519 signature when a signing key is configured. RELIASTRA approach: Generated records are checksummed and bound to the account that produced them. The unauthenticated verification endpoint confirms a record exists and matches its hashes - without disclosing endpoints, headers or account details. URL: https://reliastra.com/glossary/infrastructure-evidence ### External Dependency Fault Report An External Dependency Fault Report is the compiled artifact for one failure window: which dependency failed, over what interval, observed from where, with what severity, what customer impact correlated, and what the record’s checksum is. Problem: Incident threads contain fragments - graphs, pasted curl output, status-page screenshots. Nobody can later reconstruct exactly what was observed and when. Why it matters: A single compiled report replaces a scattered thread. It is what gets attached to vendor tickets, postmortems and SLA claims. Example: Contents: dependency, window (UTC), the detection record with the rule id that applied, every observation in the window, severity, correlated incidents, the attribution result, methodology version, payload and document checksums, verification link. RELIASTRA approach: Records are generated from retained observations when an incident resolves or on demand, carry the account binding and the checksums, and expose an unauthenticated verification endpoint that confirms existence and integrity - never private configuration. URL: https://reliastra.com/glossary/external-dependency-fault-report ### Independent Measurement Independent measurement is observation performed by a party that neither operates the observed service nor depends on it: the observer issues its own requests, from its own infrastructure, records the raw results, and publishes the method that produced them. Problem: Every account of an outage is written by someone. The operator’s logs, the vendor’s status page and the customer’s dashboards all describe the same window from positions with different incentives and different blind spots. Why it matters: A record is only useful in a dispute if neither party authored it. Independent measurement converts “you say / we say” into one timestamped dataset both sides can check the provenance of. Example: RELIASTRA’s public records measure the HTTP behaviour of a vendor’s listed endpoint from RELIASTRA infrastructure on a fixed schedule; the vendor’s own status text is never read, parsed or reconciled into the number. RELIASTRA approach: Independence is stated as scope, not claimed as authority: which endpoint, which origin, which method, which limits - published in the record itself so a reader can weigh the observation without trusting the brand. See the measurement methodology. URL: https://reliastra.com/glossary/independent-measurement ### Quorum Detection Quorum detection is the rule that an incident is confirmed only when a required number of independent observation points report failure within the same short correlation window - and recovery only when they agree it ended. Under a single-origin deployment the equivalent confirmation is persistence: the same point failing a fixed number of consecutive checks. Problem: One failed probe can mean a dead vendor, a saturated network path, a DNS hiccup or a bug in the probe. Alerting on any single failure produces noise precisely when a team can least afford it. Why it matters: An incident label is a claim. Corroboration is what lets a team act on it - page someone, fail over, open the credit conversation - without first spending thirty minutes deciding whether the alert is real. Example: RELIASTRA’s shipped multi-origin rule: two or more genuinely distinct observation points must fail inside the same 60-second window to open an incident; two consecutive successes across them close it. The deployed public records run one origin, so they use the persistence rule and say so. RELIASTRA approach: The rule is a deterministic pure function of stored check results - no heuristics, no randomness - so any incident can be re-derived from the record. Two labels from one worker never count as two points; that asymmetry is the point. URL: https://reliastra.com/glossary/quorum-detection ### Transport Error A transport error is a probe failure that occurs before an HTTP status could be exchanged - DNS resolution failure, TCP refusal or reset, TLS handshake failure, or a timeout past the probe deadline. It is categorically different from receiving a 4xx or 5xx status. Problem: Monitoring that collapses “no response” and “server returned 500” into one red dot destroys the distinction between an unreachable service and a reachable-but-failing one - two incidents with different owners, symptoms and fixes. Why it matters: Transport errors keep their identity in the record, which is what lets a later reader separate an unreachable service from a reachable-but-failing one. Working out where a failure sits needs more than one vantage point, and RELIASTRA runs one today - so a transport error is reported as an observation of the path it probed, not as a verdict about the target. Example: RELIASTRA stores each observation with its outcome: status code and latency when a response arrived; an explicit error type when it did not. Availability counts “no expected response,” so the taxonomy stays visible in every aggregate. RELIASTRA approach: Probes run under a fixed deadline (15 seconds on public records) with bounded redirect handling, and the security policy can refuse a target before any request leaves - recorded as a policy block, a RELIASTRA-side fact, never as vendor downtime. URL: https://reliastra.com/glossary/transport-error ### Vendor-Reported Status Vendor-reported status is the state a provider publishes about its own services - the status page, the @-account, the email. It is authored by the party whose reliability is in question, scoped to incidents it chooses to declare, and updated on its own schedule. Problem: “The status page says operational” is routinely treated as a measurement. It is a statement: often honest, occasionally delayed, structurally unable to describe what the vendor is not looking at. Why it matters: During an incident, the gap between “not yet declared” and “not happening” is exactly where customer-side decisions live: fail over now or keep waiting. Decisions need evidence with a timestamp, and vendor statements are one input, not the clock. Example: A status site can be fully operational while the API it reports on degrades; conversely a measured status-site failure during a traffic spike is real information about the vendor’s edge, whatever the API is doing. Neither record substitutes for the other. RELIASTRA approach: RELIASTRA never ingests, mirrors or reconciles vendor-reported status into its figures - and publishes the two records side by side conceptually, so disagreement is readable rather than averaged away. Where a vendor’s status endpoint is itself the observed target, the record says so explicitly. URL: https://reliastra.com/glossary/vendor-reported-status ### Partial Outage A partial outage is a failure window in which a service is unavailable or degraded for a subset of its surface: one region, one API route, one model tier, one auth path, one traffic class - while the rest functions normally. “Up” and “down” are both false descriptions of it. Problem: Binary status vocabulary forces partial outages into the wrong bucket. A vendor reporting “no incidents” can be simultaneously true (no global outage) and useless (your route is timing out). Why it matters: Partial outages are the most common failure mode of large platforms, they break failover logic that assumes whole-system down, and they are the hardest windows to evidence afterwards because every aggregate smooths them away. Example: One region of a provider returning 5xx while two others serve normally; completions fast while realtime routes hang; public API degraded while the consumer app is untouched. Each is invisible to any single number - and to any observation from one vantage point. RELIASTRA approach: Per-observation storage with an explicit error type is what makes the shape of a partial outage visible: RELIASTRA reports the exact endpoint and window it observed failing, and prints “insufficient data” wherever a record from one observation point cannot speak to the rest of the surface. URL: https://reliastra.com/glossary/partial-outage ### Availability Availability, as RELIASTRA measures it, is the number of observations in which the probe received the response its target expects (for public vendor records: HTTP 200 within 15 seconds), divided by all scheduled observations in a stated window, reported with the observation count and origins that produced it. Problem: “99.99% uptime” without window, sample size and success definition is not a measurement - it is a decoration. The same month reads 100% from one origin and 99.2% from a region the observer did not run. Why it matters: Four nines and three nines are 10x apart in downtime; a figure whose denominator is unstated cannot support an architecture decision, a contract clause, or a credit claim - it can only support a marketing bullet. Example: On a RELIASTRA record, every window is printed as availability + observation count + latency quantiles, and a window with zero observations renders as “insufficient data” - never as 100%. RELIASTRA approach: Availability is derived at read time from stored observations only; nothing is backfilled or smoothed. The denominator is scheduled probes, so “we never ran the check” surfaces as freshness (staleness) rather than hiding inside the percentage. URL: https://reliastra.com/glossary/availability ### Latency Probe latency is the wall-clock time between a scheduled check issuing its request and receiving the complete response (including any policy-validated redirect hops), recorded per observation and aggregated as a mean and 95th percentile per window. Problem: Availability says whether a request completed; only latency says what clients experienced while it did. Most dependency incidents spend minutes-to-hours in “up but slow” territory before, during, and after the visible outage - and availability dashboards show green the whole time. Why it matters: Timeouts are latency failures viewed from the client: a route degrading to 3 seconds turns into “outage” the moment it crosses the caller’s deadline. Watching the p95 is what separates a capacity conversation from a postmortem about a cliff nobody saw. Example: A record showing p95 climbing while the mean holds describes long-tail failure (one shard, one region). RELIASTRA charts the mean per bucket with failed buckets breaking the line, and prints the p95 threshold beside it. RELIASTRA approach: Latency is measured from outside both networks, on the same schedule as availability, so a drift is timestamped in the same series that will later be cited as evidence. An aggregate mean of zero means “no successful response recorded,” and is printed as no data, never as a fast response. URL: https://reliastra.com/glossary/latency ### Observation density Observation density is the ratio of observations actually recorded in a window to the number the probe schedule implies should exist there: total_observations divided by (window_seconds / probe_interval). It is a measure of the measurement, not of the endpoint. Problem: Availability is blind to the absence of measurement. A scheduler that stops issuing probes produces no failed observations and therefore no availability deficit - the record stays green while the evidence stops accumulating, and an availability figure computed over a near-empty window is indistinguishable from one computed over a full one. Why it matters: Density is the signal that separates an endpoint failing from a measurement pipeline failing. They have different causes, different owners and different fixes, and they produce opposite readings on the same availability chart. Example: On 11 September 2026 the RELIASTRA public record for one dependency returned 277 observations in a 24-hour window against 288 expected (96.2% density) and 595 in a 90-day window against 25,920 expected (2.3%). Availability read 100.0% in both. The falling density, not the availability, was the finding. RELIASTRA approach: RELIASTRA publishes the observation count beside every availability figure and audits its own records for density. The three-check audit - window monotonicity, history depth, expected-versus-observed density - is published with its script and its captured data so anyone can run it against their own monitoring supplier. URL: https://reliastra.com/glossary/observation-density ### Telemetry integrity Telemetry integrity is the property of an observation record that its contents are what they claim to be: observations actually taken, windows that the stored data can fill, labels that match the underlying sample, and enough disclosed provenance - count, window bounds, probe interval, origin - for a reader to check the arithmetic. Problem: Incident attribution depends on the completeness of a record as much as on its accuracy. An incomplete record does not merely miss failures; it makes absences ambiguous, so "no failures were recorded" and "no measurements were taken" become indistinguishable. Why it matters: An attacker who can suppress measurements achieves the same evidentiary effect as one who can falsify them, at lower cost and with less detectability. Publishing the denominator is what closes that ambiguity, which makes telemetry integrity a security property and not only a data-quality one. Example: A 90-day availability figure computed over 2.1 days of observations is arithmetically correct and evidentially thin. Both properties have to be visible in the record, or a reader - or a retrieval system quoting the page - cannot tell which one they are looking at. RELIASTRA approach: Observations are written with their origin and timestamp, never backfilled, and pruned by scheduled jobs rather than silently truncated. Evidence reports are checksummed and bound to the organisation that produced them. Where the public record falls short of this standard, RELIASTRA publishes the audit that found it. URL: https://reliastra.com/glossary/telemetry-integrity ### Dependency blast radius Dependency blast radius is the set of application functionality, data paths and user journeys that degrade or fail when a single external dependency degrades - including the parts that never call it directly, reached through shared workers, connection pools, queues and retry amplification. Problem: The obvious blast radius is the feature that calls the dependency. The real one is larger: long-running calls hold connections and workers that unrelated features also need, so a partial upstream problem becomes a full application outage and produces an incident report naming the wrong component. Why it matters: Blast radius is what makes a dependency a risk rather than a line item. It determines how much isolation an architecture needs, and it is usually discovered during an incident rather than designed for beforehand. Example: A model provider degrades. Client timeouts hold sockets, retries multiply the load, queues grow, workers saturate - and the alert fires in a background job that never called the provider API, six hops from the cause. RELIASTRA approach: RELIASTRA keeps an independent, timestamped record of the dependency side of the timeline, so the outer edge of the blast radius can be correlated against the moment the dependency was independently observed failing rather than inferred from the alert that fired first. URL: https://reliastra.com/glossary/dependency-blast-radius ### Failure domain A failure domain is the set of components that share a failure cause: a region, an availability zone, a connection pool, a worker fleet, a provider account, a DNS resolver. Components in the same domain do not provide redundancy for each other, however many of them there are. Problem: Redundancy is routinely counted in instances rather than in domains. Two workers on one host, two regions behind one control plane, or two "independent" probes issued by one process are one failure domain wearing several names - and a quorum computed across them confirms a single opinion. Why it matters: Failure-domain reasoning is what turns "we have redundancy" into a statement that can be checked. It also bounds blast radius: isolating a dependency into its own domain is the difference between a degraded feature and a degraded product. Example: Two scheduling labels emitted by one worker are one observation point. Treating their agreement as a quorum reports one machine’s opinion as independent confirmation, which is why RELIASTRA’s detection policy distinguishes a single observation topology from a multi-point one and applies a different rule to each. RELIASTRA approach: Every observation carries the origin that produced it, and the incident detection rule is explicit about topology: persistence when there is one observation point, agreement across distinct points when there are genuinely several. Labels are never promoted into independence. URL: https://reliastra.com/glossary/failure-domain ### Control plane The control plane is the set of components that decide and direct behaviour: schedulers, configuration services, orchestration APIs, routing decisions, credential issuance. It issues instructions; it does not carry the workload’s data. In a measurement system the scheduler and broker are the control plane and the workers are the data plane. Problem: Control-plane failure looks nothing like data-plane failure and is routinely misread as one. A scheduler that stops produces no errors - it produces an absence of work, which surfaces as missing observations, stale configuration or checks that silently stop running while every health endpoint still returns 200. Why it matters: Availability of the data plane says nothing about the control plane. During cloud incidents the two fail on different schedules and recover independently, and an incident report that does not distinguish them will recommend the wrong fix. Example: When RELIASTRA’s scheduler, broker or worker is unavailable, checks simply do not run - and the system reports that. A missed probe is never backfilled with a synthesised result, because an observation that did not happen must never appear in a history anyone intends to rely on. RELIASTRA approach: Checks never run inside the API process that serves the dashboard, so a busy dashboard cannot delay a probe and a slow probe cannot block the API. Scheduler health is reported separately from check outcomes, and the absence of observations is surfaced rather than defaulted to a healthy value. URL: https://reliastra.com/glossary/control-plane ### Data plane The data plane is the path that actually carries requests and responses: the network, the load balancers, the proxies, the workers that execute work and the storage that holds it. It is where latency, throughput and errors are observable, and it can be healthy while the control plane that directs it is not. Problem: Monitoring almost always watches the data plane, because that is where the measurable signals are. The consequence is that control-plane failures are inferred from data-plane symptoms - usually as an unexplained drop in traffic - rather than detected directly. Why it matters: Separating the two planes is what makes an incident attributable. "Requests are failing" and "no requests were issued" are different events with different causes, and only the second is a control-plane failure. Example: A probe worker fleet that is running but has received no dispatch instructions shows a healthy data plane and zero observations. The correct reading is a control-plane failure; the data-plane-only reading is that nothing happened. RELIASTRA approach: RELIASTRA reports both sides separately: scheduler and worker health as control-plane state, and per-observation latency, status and outcome as data-plane evidence. The two are never merged into a single "system healthy" value. URL: https://reliastra.com/glossary/data-plane ### External trust boundary An external trust boundary is the point at which data, credentials or control leave the domain governed by your organisation and enter one governed by someone else. Everything downstream of it is subject to that party’s controls, and most of it is not observable from your side. Problem: Boundaries are usually drawn around the network perimeter, which is where they stopped being meaningful. A dependency call crosses a boundary wherever payload or credential leaves the domain - through a managed gateway, a resolver, a provider edge - and those crossings are frequently absent from both the dependency inventory and the security review. Why it matters: A control that cannot be enforced at a boundary has to be enforced before it, or accepted as trust. Knowing which is which is the difference between an architecture with stated assumptions and one with unstated ones. Example: Mutual TLS and workload identity establish who is calling. They establish nothing about what the callee does with the payload, which model serves it, or where inference is executed - so the enforceable controls at a model-API boundary are architectural and contractual, not cryptographic. RELIASTRA approach: RELIASTRA observes dependencies from outside both stacks, which makes the boundary itself measurable: an independent, timestamped record of what the external side did, kept separate from your own incident history so the two can be compared rather than merged. URL: https://reliastra.com/glossary/external-trust-boundary ### AI API dependency An AI API dependency is a hosted model service consumed over the network, where the request payload is composed at call time from system instructions, retrieved documents, prior conversation turns and tool output, and where routing to the underlying model, serving tier and region is decided inside the provider’s trust domain. Problem: It is treated as a larger version of a conventional SaaS API dependency, and it is not. The payload is partly authored by a retrieval step rather than by the application, retries are a cost and quota control as well as a reliability one, and the provider’s status plane and serving plane fail independently. Why it matters: Each of those differences changes a control. Data classification has to move upstream of the call; failure-domain isolation becomes a reliability requirement with a security benefit; and an availability figure for "the provider" is a measurement of one endpoint, not of the service. Example: RELIASTRA’s public record for OpenAI observes https://status.openai.com from one region. That record is evidence about the status site. It is not evidence about the inference API, and the public page says so rather than letting the vendor name imply otherwise. RELIASTRA approach: RELIASTRA monitors the externally observable endpoints of AI providers from its own infrastructure, names each endpoint and region explicitly, and keeps the status plane and the serving plane as separate records rather than one vendor-level availability figure. URL: https://reliastra.com/glossary/ai-api-dependency ### Model routing Model routing is the set of provider-side decisions that map an API request to a serving path: which model version, which serving tier, which region, and whether the request is served directly, queued, cached or redirected to a different backend. It happens inside the provider’s trust domain. Problem: The consumer addresses a model name and observes a response. Everything between the two is invisible unless the provider chooses to disclose it in response metadata, so a change of underlying version, tier or region is not detectable at the API boundary in advance. Why it matters: Routing is where behavioural and reliability differences originate. An application pinned to a model name can experience a change it did not request and cannot see, and an incident attributed to "the model" may in fact be a routing change. Example: Latency and error-rate shifts that correlate with nothing the consumer changed are the signature of a routing or serving-tier change. Detecting them after the fact requires capturing response metadata, not just status codes. RELIASTRA approach: RELIASTRA records what it can observe - endpoint, region, status, latency, timestamp - and states explicitly what its record does not cover. Model-level endpoints and per-route API latency are not part of the public observatory today, and the hub says so in its own sections rather than in a footnote. URL: https://reliastra.com/glossary/model-routing ### Observability blind spot An observability blind spot is a class of failure that a monitoring system cannot report, not because of a configuration gap but because of what it measures. The classic case: an availability metric cannot report the absence of measurement, because a missing probe produces no failed observation. Problem: Blind spots are invisible by definition. A dashboard that has never shown a particular failure mode looks complete, and the gap is discovered during the incident it failed to report. Why it matters: A blind spot is a property of the instrument, so it cannot be closed by adding more of the same signal. It needs a different measurement - density against expectation, control-plane health, an independent observation from outside the system being watched. Example: A monitoring system that watches only your own services has a blind spot shaped exactly like your dependency graph. A scheduler that stops shows a healthy availability record and no observations. A cadence estimated from bucketed telemetry reports the chart resolution rather than the probe interval. RELIASTRA approach: RELIASTRA observes dependencies from outside both stacks, publishes the observation count beside every percentage, states what its records do not cover, and publishes audits of its own instrument when one is found - including the estimator defect documented in the probe-interval paper. URL: https://reliastra.com/glossary/observability-blind-spot ### Explicit deny An explicit deny is a statement in any applicable policy whose Effect is Deny. In AWS IAM policy evaluation it is checked first, across every policy type in scope, and a match ends the request: no later stage is reached and no Allow anywhere in the set survives it. It is the only mechanism in the procedure that overrides a grant rather than capping one. Problem: Deny is the one mechanism that cannot be worked around by adding a grant elsewhere, which makes it the most dangerous line in a policy set. A Deny written to exclude a handful of principals can, through the NotPrincipal and permissions-boundary interaction, exclude every governed principal in the account - and still read correctly in review. Why it matters: A denial caused by a matching Deny and a denial caused by an absent Allow produce the same API response and opposite fixes. The first is repaired by narrowing or removing a statement; the second by adding a grant, which changes nothing at all against a matching Deny. Telling them apart is the first step of any authorisation investigation. Example: An identity policy allows s3:GetObject and a bucket policy denies the same action for the same principal. The request is denied at stage one, before the identity-based Allow is consulted - and re-granting in the identity policy cannot change the outcome. RELIASTRA approach: RELIASTRA keeps the same distinction in its own records: a dependency refusing a request is a different observation from a request that was never made, and neither is inferred from the other. An absence is reported as an absence. URL: https://reliastra.com/glossary/explicit-deny ### Implicit deny Implicit deny is the absence of an Allow. AWS denies every request by default, with the single documented exception of the account root user, so a request succeeds only if some applicable policy grants it and no statement denies it. Nothing was evaluated against the request except a search for a matching Allow, and the search came up empty. Problem: Implicit deny produces no statement to point at. The defect is a missing line rather than a present one, and the absence usually sits in a different policy class from the one being read - most often a resource-based policy on the other side of the search, or a ceiling two stages earlier in the procedure. Why it matters: Implicit deny is a safety property and an audit hazard at once. It is why an unattached role has no permissions and fails closed, and it is why "nothing denied it" is weak evidence of anything. A system that defaults to deny must record what granted each allowed request, or the grant stays invisible until it is wrong. Example: A new IAM role with no policies attached returns AccessDenied on every call. So does a role whose identity policy allows the action but whose request is stopped by a service control policy two stages earlier. Both are implicit denials, at different stages, and only the deciding stage distinguishes them. RELIASTRA approach: RELIASTRA applies the same default to observation: a dependency that has never been checked is reported as unobserved rather than healthy, and a missed probe is never backfilled with a synthesised result. Absence of evidence is recorded as absence. URL: https://reliastra.com/glossary/implicit-deny ### Identity-based policy An identity-based policy is attached to an IAM user, group or role and grants or denies actions to the principal it is attached to. Inside one account it is one of the two granting classes: with resource-based policies it combines by union, so an Allow in either is sufficient, and an explicit Deny in either overrides the Allow. Problem: Because the union is easy to forget, teams search the class they author most often. A role found reading a bucket it should not is usually blamed on its identity policy while the grant sits in the bucket policy - equally sufficient, and invisible from the identity side. Why it matters: The class a grant lives in decides who owns it, who reviews it and what caps it. An identity-based grant travels with the principal and is capped by that principal’s permissions boundary and session policies. A resource-based grant does not, and can bypass ceilings the author of the identity policy assumed applied. Example: The same s3:GetObject Allow written in a role policy is capped by the boundary attached to that role. Written instead in the bucket policy naming the role session ARN, it is not. The two grants are one ARN format apart and behave differently under the same boundary. RELIASTRA approach: RELIASTRA treats the two planes as separate objects of evidence. When a dependency refuses a call, the record shows the outcome and its timestamp; which policy on the dependency side produced it is a claim RELIASTRA does not make without evidence that reaches it. URL: https://reliastra.com/glossary/identity-based-policy ### Resource-based policy A resource-based policy is attached to the resource - a bucket policy, a KMS key policy, an IAM role trust policy, a queue policy - and names the principals that may act on it. Inside one account it is a granting class and combines with identity-based policies by union. Across accounts it is the trusting side of a two-evaluation conjunction: the request is allowed only if both accounts allow it. Problem: Its meaning changes with the principal form it names and with the account boundary it sits on. The same document is a grant in one row of the evaluation matrix and a ceiling in the next, and inside one account it cannot reduce what an identity-based policy grants at all: the tightening design most teams intend is a union, not an intersection. Why it matters: It is the only class a resource owner controls without editing anyone else’s identity policies, which is why it is the correct plane for cross-account sharing - and why a restrictive resource policy written to constrain a colleague’s role inside one account constrains nothing at all. Example: A bucket policy naming arn:aws:iam::111122223333:role/examplerole is capped by that role’s permissions boundary. The same policy naming arn:aws:sts::111122223333:assumed-role/examplerole/sessionname is not. Both read, in review, as "the bucket allows the role". RELIASTRA approach: As with identity-based policies: RELIASTRA records the outcome a dependency produced and the moment it produced it, and keeps that record separate from any claim about the dependency’s own policy set, which RELIASTRA does not observe. URL: https://reliastra.com/glossary/resource-based-policy ### Permissions boundary A permissions boundary is attached to an IAM user or role and sets the maximum permissions that principal may have. It is a ceiling, not a grant: it removes permission an identity-based policy would otherwise give and can never add any. Whether it also caps a resource-based grant depends on which document it is attached to and which principal form the grant names. Problem: It is routinely described as limiting identity-based policies only, which is incomplete in a way that produces real defects. The same bucket policy caps one role and not another depending on whether it names the role or the role session, and a boundary attached to the principal is invisible to the trusting account’s evaluation in a cross-account request. Why it matters: The boundary is the per-principal ceiling: it travels with the principal, unlike a service control policy (per account) or a resource control policy (per resource). Choosing between the three is an architecture decision with different blast radii, and it cannot be made correctly while the boundary is modelled as a filter on identity policies alone. Example: A role whose boundary allows read-only S3 actions is granted s3:PutObject by its identity policy: the write is denied at the boundary stage. The same grant arriving from a bucket policy that names the role session ARN bypasses the boundary entirely. RELIASTRA approach: The boundary is why RELIASTRA’s attribution habit starts with the CloudTrail principal type rather than with a policy: whether any ceiling could have applied to a request is a property of the identity that made it, and only the record says which identity that was. URL: https://reliastra.com/glossary/permissions-boundary ### Non-human identity A non-human identity is any principal that is not a person at a keyboard: service-linked roles, assumed roles in CI pipelines, federated sessions minted by GetFederationToken, and agents holding temporary credentials. Authorisation systems evaluate them with the same procedure as human principals; what differs is the population’s shape - short-lived sessions, grants chosen in code, and review cadences that do not match grant cadences. Problem: Sessions outnumber identities, and the principal making a request under an assumed role is the role session ARN, not the role ARN. A resource-based policy naming the session form bypasses ceilings that would have applied to the role form, so a population of short-lived sessions is systematically less constrained by boundaries than a population of users. Why it matters: Most access in a modern account is machine access, and most of it is granted at session-mint time in code that no policy review reads. The interaction that decides effective permissions - which principal form the resource-based policy names - is chosen by whoever writes the assume-role call. Example: A CI pipeline assumes a role and passes the session ARN to a downstream integration, which writes it into a bucket policy. The grant now bypasses the boundary attached to the role. No policy changed; the effective permissions did. RELIASTRA approach: RELIASTRA’s own checks are non-human callers of other companies’ control planes - scheduled workers rather than people - so the population this term describes is the population RELIASTRA adds to the internet, and the same principal-type rules apply to its credentials as to anyone else’s. URL: https://reliastra.com/glossary/non-human-identity ## Research hubs - AI Infrastructure Status & Reliability: Live status records, measured reliability windows, incident history and technical methodology for AI API providers - independently observed by RELIASTRA, not read from vendor status pages. - https://reliastra.com/research/ai-infrastructure (live hub: renders current measurement data, revalidated every 60 seconds) - Measurement integrity: What a reliability record actually measures, what it silently omits, and the audits that expose the difference. Papers here treat RELIASTRA’s own public record as the primary subject. - https://reliastra.com/research/measurement-integrity - Cloud & AI infrastructure security: Trust boundaries, failure domains and attack surface in architectures that depend on cloud control planes and hosted model APIs. - https://reliastra.com/research/cloud-security ## Research index - The Dependency Gap (Research, 2025-11-18): Why an outage you caused and an outage your vendor caused look identical from inside your own monitoring - and what it takes to tell them apart. - https://reliastra.com/research/the-dependency-gap - How RELIASTRA measures vendor reliability (Methodology, 2025-11-18): The measurement methodology behind every check: where probes originate, retry semantics, the incident detection rule, and the cases we deliberately refuse to call an outage. - https://reliastra.com/research/how-reliastra-measures-vendor-reliability - The RELIASTRA research agenda (Research, 2025-11-18): What we intend to publish, what we will not, and the standards we hold our own reliability data to. - https://reliastra.com/research/reliastra-research-agenda - “Is OpenAI down?” - how to answer the question honestly (AI infrastructure, 2026-09-10): The question hides three different claims - API, consumer app, status site. What an outside observer can measure, what RELIASTRA actually measures today, and a probe you can reproduce in thirty seconds. - https://reliastra.com/research/ai-infrastructure/is-openai-down - When an AI API misbehaves: an evidence playbook (AI infrastructure, 2026-09-10): What to capture in the first ten minutes of an AI-provider incident so the window is still checkable a month later - and how independent observations turn a bad evening into an attributable record. - https://reliastra.com/research/ai-infrastructure/ai-api-outage-evidence ### What a status-page payload actually asserts URL: https://reliastra.com/research/ai-infrastructure/status-page-payload-anatomy Published: 2026-09-11 Category: AI infrastructure · Type: Measurement · Evidence basis: measured Domains: AI infrastructure, Incident engineering, Observability Research question: What does a hosted status-page payload actually assert, and how much incident evidence does it contain? Abstract: Status pages are routinely treated as incident evidence. They are better than that framing suggests in one respect and far worse in another. On 11 September 2026 RELIASTRA read the machine-readable summary payload of OpenAI’s status site and found 25 provider-defined components, every one marked operational, under a single aggregate indicator of "none". The payload’s structural content is genuinely useful: it is a service inventory, and it names components - Codex API, Realtime, Batch, Embeddings, Deep Research - that no independent observer would guess. Its temporal content is close to empty: the page and all 25 components carry the identical timestamp 2026-07-09T19:25:56Z, sixty-three days and sixteen hours before the read, and that timestamp corresponds to the creation of the newest component. The payload therefore asserts a current state without asserting when that state was last established. This paper separates the three things a status payload carries - a taxonomy, a current declaration, and a history - and states what each can and cannot support as evidence. Scope: One hosted status page, read once, at one timestamp. The findings describe this payload as returned on 11 September 2026. This paper does not evaluate OpenAI’s reliability, does not claim the provider failed to report anything, and does not generalise the timestamp semantics to other status-page hosts without evidence. Methodology: A single unauthenticated HTTPS GET of the status site’s machine-readable summary endpoint, captured verbatim with its response body versioned in this repository, followed by structural analysis of the returned JSON: component count, status distribution, timestamp distribution, and comparison of page-level and component-level timestamps against component creation times. Key findings: 1. [measured] The payload returned 25 components and one aggregate indicator. The indicator is a single value over the whole page; the components are the only granularity at which a partial failure can be expressed. 2. [measured] page.updated_at and the updated_at of all 25 components were identical: 2026-07-09T19:25:56Z, sixty-three days and sixteen hours before the read. The newest component in the list carries the same value as its created_at, so the most recent change to the page was the addition of a component, not a change of status. 3. [measured] The summary payload carries no incident history at all. History lives on a separate endpoint. A reader who consumes only the summary - which is the endpoint most integrations poll - receives a current state and no record of the interval it covers. 4. [reasoned] An unchanged updated_at is consistent with sixty-three days without a declared status change, but it is not proof. The timestamp semantics are not contractually documented for this use, and a component that degraded and recovered inside one polling interval would be indistinguishable from one that never changed. 5. [derived] The component taxonomy is the most valuable part of the payload for an independent observer: it is a provider-authored statement of which services the provider considers separately reportable, which is exactly the granularity an availability record needs and almost never has. 6. [measured] None of the 25 components is the endpoint RELIASTRA observes. The record labelled "OpenAI" measures https://status.openai.com - the site that carries this payload - and is evidence about that site. Entities: vendor=OpenAI; endpoint=https://status.openai.com/api/v2/summary.json (the machine-readable summary payload); organization=Atlassian (Statuspage, the host that defines the payload shape); endpoint=https://status.openai.com (the endpoint RELIASTRA observes for this vendor) Measurement window: 2026-09-11T11:36:00Z to 2026-09-11T11:36:00Z · source https://status.openai.com/api/v2/summary.json · protocol HTTPS GET, JSON response, unauthenticated · observation points unspecified - single request, origin not recorded (region labels identify the worker; 1 observation point is deployed today) · observations 1 Dataset: OpenAI status-page summary payload, 11 September 2026 (application/json, Captured verbatim from a public endpoint; quoted for analysis. Copyright remains with the publisher.) at research/availability-record-audit/data/openai-statuspage-summary-2026-09-11T1136Z.json in the ReliaAstra/Reliastra repository Artifacts: dataset: Captured status-page summary payload (research/availability-record-audit/data/openai-statuspage-summary-2026-09-11T1136Z.json); diagram: Figure 1 - what a status payload carries Limitations: - One read. A single timestamp cannot establish how often the payload changes, and this paper makes no claim about the interval between updates. - The inference that an unchanged updated_at implies an unchanged status rests on observed correlation - the timestamp moved when a component was added - not on documented semantics. Statuspage does not publish a guarantee that every status change advances it. - A status change that occurred and was resolved between two reads is invisible to any polling observer. This is a property of polling, not of this provider. - The absence of incident history in the summary payload is a statement about this endpoint. The history endpoint exists and was not captured here. - RELIASTRA observes this site as a dependency and is also analysing it. The two roles are separate: the analysis uses one captured payload, not the observation record. Recommendations: - Treat the component taxonomy as data, and the indicator as opinion: Harvest the component list as a provider-authored service inventory - it tells you what the provider considers separately reportable. Treat the aggregate indicator as a single unqualified claim about the whole page. - Poll the history endpoint, not only the summary: The summary carries a current state and no interval. Without the history endpoint you cannot distinguish a long stable period from a change that was resolved between two polls. - Store the payload, not the interpretation: A status page is a counterparty record. Archive the raw response with its fetch timestamp so a later reader can tell what was declared from what was concluded. - Never merge a status declaration into a measured availability figure: They are different kinds of evidence with different authors. Reconcile them on a shared timeline and keep both; the disagreement is the interesting part. References: [1] OpenAI status site - machine-readable summary payload, OpenAI, https://status.openai.com/api/v2/summary.json, accessed 2026-09-11 [2] Statuspage API - summary, status and incidents endpoints, Atlassian, https://developer.atlassian.com/cloud/statuspage/rest/intro/, accessed 2026-09-11 [3] How RELIASTRA measures vendor reliability, Reliastra, Inc., https://reliastra.com/research/how-reliastra-measures-vendor-reliability, accessed 2026-09-11 [4] RELIASTRA public measurement API - vendor detail, openai, Reliastra, Inc., https://api.reliastra.com/v1/vendors/openai, accessed 2026-09-11 ### How much evidence stands behind a published availability figure? URL: https://reliastra.com/research/measurement-integrity/availability-record-audit Published: 2026-09-11 Category: Measurement integrity · Type: Audit · Evidence basis: measured Domains: Measurement integrity, Observability, Reliability Research question: Can a reader of a published availability record determine, from the record itself, how much evidence stands behind each percentage it publishes? Abstract: Availability percentages are published without their denominators, so a reader cannot tell a 90-day figure computed from 25,920 observations from one computed from 595. RELIASTRA audited its own public availability record for OpenAI on 11 September 2026 and found three properties that are invisible on the rendered page but recoverable from the measurement API: the 30-day and 90-day windows return aggregates byte-identical to the 7-day window; the returned history covers roughly 2.1 days of observations for an endpoint that has been configured for 26.5 days; and the observation cadence the record states is five times shorter than the cadence its own timeline implies. None of the three is a defect in the arithmetic. All three are defects in what the record discloses. This paper gives the three checks that expose them - window monotonicity, history depth, and expected-versus-observed density - as a reproducible audit any engineer can run against any availability record, including their own monitoring vendor’s. Scope: The publicly readable availability record for one dependency (OpenAI, observed via https://status.openai.com) on the RELIASTRA public measurement API, read on 11 September 2026. The audit method itself is general and applies to any availability record that exposes per-window aggregates. This paper does not evaluate the endpoint’s reliability, does not evaluate OpenAI, and does not claim the record is inaccurate - it claims the record is under-described, and quantifies the gap. Methodology: Six read-only GET requests against public endpoints, captured with their raw JSON at fixed UTC timestamps and versioned in this repository. Expected observation counts are computed from the configured probe interval declared in this repository’s source, not from the record’s stated cadence. History depth is inferred from the identity of aggregates across windows plus count-over-interval arithmetic. Every claim is labelled measured, derived, sourced or reasoned; the audit script re-derives all of it from the captured bytes. Key findings: 1. [measured] The 30-day and 90-day windows of the public record returned observation counts, availability, mean latency and 95th-percentile latency identical to the 7-day window: 595 observations, 100.0%, 570.67 ms mean, 840.33 ms p95. The three windows describe the same set of observations. 2. [derived] At the configured 300-second interval, 595 observations span about 49.6 hours. The record’s "90 days" availability figure is therefore computed over roughly 2.1 days of evidence - 2.3% of the 25,920 observations the label implies. 3. [derived] The 24-hour window returned 277 observations against 288 expected at a 300-second interval (96.2% density, 11 observations missing). The 7-day window returned 595 against 2,016 expected (29.5%). Density falls with window length, which is the signature of shallow history rather than of a failing endpoint. 4. [measured] The rendered public record states that checks arrive "about every 60 seconds per region". The same record’s timeline for the same hour contains 12 points, each holding one observation, spaced 300 seconds apart. The stated cadence is five times shorter than the measured one. 5. [measured] Availability was 100.0% in every window. Nothing in this audit contradicts that figure - the endpoint responded to every probe that was issued. The finding is about the size of the sample the figure was computed from, not about its correctness. 6. [measured] A record that publishes availability without observation count, window bounds and probe interval cannot be audited by a reader. RELIASTRA publishes the first two on the rendered page and does not publish the third on any public endpoint. Entities: vendor=OpenAI (the dependency under observation); endpoint=https://status.openai.com (the single observed endpoint for this vendor record); region=us-east (the only observation origin in the record); system=RELIASTRA public measurement API (GET /v1/vendors/{name}/metrics, /timeline, and the vendor catalog); system=RELIASTRA public vendor record (the rendered page at /observatory/openai) Measurement window: 2026-09-11T11:34:00Z to 2026-09-11T11:39:46Z · source https://api.reliastra.com/v1/vendors/openai/metrics · protocol HTTPS GET, JSON response, unauthenticated · observation points us-east (region labels identify the worker; 1 observation point is deployed today) · observations 595 Dataset: RELIASTRA availability-record audit, OpenAI, 11 September 2026 (application/json, text/csv, CC-BY-4.0) at research/availability-record-audit/data in the ReliaAstra/Reliastra repository Artifacts: script: audit.py - availability-record audit (research/availability-record-audit/audit.py); dataset: Captured payloads and derived audit table (research/availability-record-audit/data); repository: Availability-record audit (research/availability-record-audit/README.md) Limitations: - One dependency, one endpoint, one observation origin, one read session. Nothing here establishes that the same properties hold for other dependencies or at other times. - The inference that the stored history is about 2.1 days deep rests on aggregate identity across the 7-, 30- and 90-day windows plus a constant 300-second interval. A retention job, an aggregation cap and a scheduler that was not running for most of the period are indistinguishable from the public API alone. - The configured probe interval of 300 seconds is read from this repository’s schema default, not from a public endpoint. If the deployed dependency overrides it, every expected-count figure in this paper scales with it - the script takes the interval as an argument for exactly that reason. - A 100.0% availability figure over 595 observations is not a weak measurement of a healthy endpoint. It is a weak measurement of a 90-day period. This paper does not claim the endpoint was unavailable at any point. - RELIASTRA audited its own record. That is a conflict of interest in the reader’s favour but it is still self-assessment, and the captures are versioned so a third party can check the arithmetic independently. Recommendations: - Publish the denominator beside every percentage: An availability figure without its observation count, window bounds and probe interval is a claim a reader cannot check. Render all four together, or suppress the percentage for windows whose density falls below a stated threshold. - Refuse to render a window the store cannot fill: If the 30-day aggregate is identical to the 7-day aggregate, the record should say "history covers 2.1 days" instead of printing a 30-day figure. A window label that the data cannot honour is a defect, not a rounding issue. - Alarm on observation density, not on availability: Availability is blind to a scheduler that stopped. Observation count against expected count is not. A density ratio below 0.95 on a 24-hour window means probes were not issued, and that is a different incident from an endpoint failing. - Never take the cadence from the record: Derive expected counts from the configured interval in your own source of truth. This audit would have been wrong by a factor of five had it trusted the cadence the record states - see the companion paper on interval estimation. References: [1] RELIASTRA public measurement API - vendor metrics aggregate, openai, Reliastra, Inc., https://api.reliastra.com/v1/vendors/openai/metrics, accessed 2026-09-11 [2] RELIASTRA public measurement API - vendor timeline, openai, 1h at 1-minute resolution, Reliastra, Inc., https://api.reliastra.com/v1/vendors/openai/timeline?window=1h&resolution=1m, accessed 2026-09-11 [3] RELIASTRA public vendor record - OpenAI, Reliastra, Inc., https://reliastra.com/observatory/openai, accessed 2026-09-11 [4] backend/app/modules/dependencies/schemas.py - check_interval_seconds default, Reliastra, Inc., https://github.com/ReliaAstra/Reliastra/blob/main/backend/app/modules/dependencies/schemas.py, accessed 2026-09-11 [5] backend/app/modules/vendors/service.py - _WINDOW_HOURS, Reliastra, Inc., https://github.com/ReliaAstra/Reliastra/blob/main/backend/app/modules/vendors/service.py, accessed 2026-09-11 [6] Site Reliability Engineering, chapter 4: Service Level Objectives, O'Reilly Media / Google SRE, https://sre.google/sre-book/service-level-objectives/, accessed 2026-09-11 [7] ISO 8601-1:2019 - Date and time, representations for information interchange (ISO 8601-1:2019), International Organization for Standardization, accessed 2026-09-11 ### Why an interval estimated from bucketed telemetry converges on the bucket length URL: https://reliastra.com/research/measurement-integrity/probe-interval-from-bucketed-telemetry Published: 2026-09-11 Category: Measurement integrity · Type: Measurement · Evidence basis: measured Domains: Observability, Measurement integrity, Distributed systems Research question: Why does an observation interval estimated from bucketed telemetry converge on the bucket length, and what does that do to a published monitoring record? Abstract: RELIASTRA’s public vendor record derives the probe cadence it prints from the density of non-empty buckets in a timeline series: bucket length divided by the mean observations per occupied bucket. On 11 September 2026 that estimator printed "about every 60 seconds" for a dependency probed every 300 seconds - a fivefold understatement, on the same page where a second component of the same record printed 300 seconds for the same schedule. The cause is not a coding slip. An estimator built from occupied-bucket density is mathematically bounded above by the bucket length: when the true interval exceeds the bucket, every occupied bucket holds exactly one observation, the mean is 1, and the estimator returns the bucket length exactly. The estimator therefore computes min(interval, bucket) and cannot report an interval longer than the resolution it is fed. This paper states the bound, proves it from the captured series, shows the two cadences the production record published simultaneously, and gives the corrected estimator - median inter-bucket delta - now implemented in the observatory with a regression test built from the captured payload. Scope: One estimator, one production record, one captured series. The bound is proven for regular schedules and stated as approximate for irregular ones. This paper does not evaluate the probe schedule itself, does not claim the dependency was under-monitored relative to its contract, and does not generalise to estimators that operate on raw event timestamps rather than aggregates. Methodology: The estimator is read from source in this repository. The series it was fed is captured verbatim from the public API with its response body versioned in this repository. The bound is derived analytically and then checked against the captured series at two resolutions. The corrected estimator is implemented and its regression test is built from the captured payload, so the test fails if the captured behaviour is ever reintroduced. Key findings: 1. [measured] The one-hour timeline captured at 11:39:46 UTC on 11 September 2026 contains 12 points, each with observation_count = 1, at bucket starts 300 seconds apart (one gap of 360 seconds). Median inter-bucket delta: 300 s. Mean: 305.5 s. 2. [derived] The deployed estimator returns round(bucket_length / mean_observations_in_occupied_buckets). On that series: round(60 / 1.0) = 60 seconds. The published record therefore stated an interval five times shorter than the measured one. 3. [measured] The same rendered page simultaneously stated "about every 60 seconds per region" in its summary and observation-network table and "≈ every 300 seconds in this window" in its telemetry panel. Both figures came from the same estimator, applied to timelines at 1-minute and 5-minute resolution respectively. 4. [reasoned] For any regular schedule, the estimator returns min(interval, bucket_length). It is exact when the interval divides the bucket length, and saturates at the bucket length whenever the interval is longer. No input can make it report an interval above its resolution. 5. [measured] The API returns only occupied buckets: a one-hour window at one-minute resolution returned 12 points, not 60. Empty buckets - the actual evidence of a sparse schedule - never reach the estimator. 6. [derived] Two estimators recover the true interval from the same 12 points: median inter-bucket delta (300 s) and window length over observation count (3600 / 12 = 300 s). Neither depends on bucket resolution. Entities: system=observedCadenceSeconds (the estimator, in frontend/src/lib/track-api.ts); system=RELIASTRA public vendor record (/observatory/openai, the page that prints the cadence); endpoint=https://status.openai.com (the dependency whose cadence was misreported); region=us-east (the observation origin of the captured series) Measurement window: 2026-09-11T10:39:46Z to 2026-09-11T11:39:46Z · source https://api.reliastra.com/v1/vendors/openai/timeline?window=1h&resolution=1m · protocol HTTPS GET, JSON response, unauthenticated · observation points us-east (region labels identify the worker; 1 observation point is deployed today) · observations 12 Artifacts: dataset: Captured one-hour timeline, verbatim (research/availability-record-audit/data/reliastra-openai-timeline-1h-1m-2026-09-11T1139Z.json); script: audit.py - interval estimators compared (research/availability-record-audit/audit.py) Limitations: - The bound min(interval, bucket_length) is exact for a perfectly regular schedule. Under jitter, retries or a schedule that changed mid-window, the estimator’s output depends on the distribution of gaps and can land anywhere at or below the bucket length. - Median inter-bucket delta is itself an estimate. It reports the interval at which observations were recorded, which is the dispatch interval only if the scheduler is punctual; a worker backlog produces a longer median without any change of configuration. - The corrected estimator inherits the resolution ceiling of the data it is given. A series returned at five-minute resolution cannot establish a 30-second schedule, and this paper does not claim otherwise. - One dependency, one region, one hour. The captured series is regular enough that both corrected estimators agree; that agreement is a property of this window, not a guarantee. - The fix changes what the record prints. It does not change how often probes are issued. Recommendations: - Estimate rate from timestamps, never from post-aggregation counts: Bucketing destroys the information a rate estimate needs. If you must estimate from a bucketed series, use the delta between bucket starts, or window length over total count - both of which are resolution-independent. - Publish the configured interval instead of inferring it: RELIASTRA infers cadence because no public endpoint exposes the configured interval. Exposing it removes the estimation problem entirely; inference is a workaround for a missing field, and this paper documents what the workaround costs. - Compute one figure once, and render it everywhere from that one value: The production page published two cadences because two components each ran the estimator over a different window. A record that states a number twice should state it from one place. - Test estimators against captured payloads, not synthetic ones: A hand-written fixture with dense buckets cannot express the failure mode. The regression test added here is the captured 12-point series, verbatim. References: [1] RELIASTRA public measurement API - vendor timeline, openai, 1h at 1-minute resolution, Reliastra, Inc., https://api.reliastra.com/v1/vendors/openai/timeline?window=1h&resolution=1m, accessed 2026-09-11 [2] frontend/src/lib/track-api.ts - observedCadenceSeconds, Reliastra, Inc., https://github.com/ReliaAstra/Reliastra/blob/main/frontend/src/lib/track-api.ts, accessed 2026-09-11 [3] backend/app/config.py - CHECK_SCHEDULE_SECONDS and OBSERVATION_TOPOLOGY, Reliastra, Inc., https://github.com/ReliaAstra/Reliastra/blob/main/backend/app/config.py, accessed 2026-09-11 [4] Release It! - transparency and observability of production systems, Michael T. Nygard, Pragmatic Bookshelf, accessed 2026-09-11 [5] Prometheus documentation - rate() and the sampling-interval constraint, Prometheus project, https://prometheus.io/docs/prometheus/latest/querying/functions/#rate, accessed 2026-09-11 ### The trust boundary of an AI API dependency URL: https://reliastra.com/research/cloud-security/ai-api-trust-boundary Published: 2026-09-11 Category: Cloud security · Type: Architecture analysis · Evidence basis: reasoned Domains: Cloud security, AI infrastructure, Zero trust, Dependency security Research question: What changes about an application’s trust boundary when its model is a network call to a third party, and which controls that boundary used to imply no longer exist? Abstract: An AI API dependency is not a larger version of a SaaS API dependency. It moves prompt content, retrieval context and often customer data across a boundary the consuming organisation does not control, on a path whose routing the consumer cannot observe, at a cost model that makes retry behaviour a financial control as well as a reliability one. This paper enumerates the boundary as an architect would draw it - the zones, what crosses each of them, what is authenticated where, and what the consumer can and cannot verify - and derives the controls that follow. It is grounded in one concrete asymmetry that RELIASTRA’s own observatory makes visible: the endpoint RELIASTRA observes for OpenAI is https://status.openai.com, a status site in the provider’s reporting plane, while the endpoint an application actually depends on is the inference API. The two sit in different planes, fail independently, and only one of them is on any status page. The paper closes with the four properties that distinguish an AI API dependency from a conventional one, and the failure modes each introduces. Scope: The architecture of a production application that calls a hosted model API over HTTPS, with or without an intervening AI gateway. This paper does not evaluate any provider’s security posture, does not report a vulnerability, and makes no claim about any specific provider’s controls. It is an architectural analysis: every finding is reasoning from published documentation and standard trust-boundary practice, except the observation about RELIASTRA’s own observed endpoint, which is measured. Methodology: Trust-boundary decomposition of a reference architecture: enumerate zones, enumerate what crosses each boundary, state the authentication and authorisation that applies at each crossing, and identify the properties the consumer can verify versus those it must trust. Cross-referenced against NIST SP 800-207 for the zero-trust vocabulary, RFC 8446 for what TLS 1.3 does and does not establish about the peer application, and provider documentation for the disclosure boundary. The one measured element is the observed endpoint of RELIASTRA’s own OpenAI record, read from the public measurement API. Key findings: 1. [reasoned] An AI API dependency exposes prompt content to a third-party trust domain. Unlike a payment or auth call, the payload is not a small structured record: it routinely contains retrieved documents, prior conversation turns and whatever the retrieval layer happened to fetch. Data-classification controls that were adequate for a card token are not adequate for a prompt. 2. [reasoned] Model routing is inside the provider’s trust domain and invisible to the consumer. A request addressed to a model name is served by whatever the provider routes it to, and the consumer observes only the response. A change of underlying model, region or serving tier is not observable at the API boundary unless the provider chooses to disclose it. 3. [measured] The status plane and the serving plane are separate failure domains with separate availability. RELIASTRA’s public record for OpenAI observes https://status.openai.com from one region; that record is evidence about the status site, and is not evidence about the inference API. Treating the two as one availability figure is a category error that survives into incident reports. 4. [reasoned] Retry behaviour against a model API is a cost control as well as a reliability control. Unbounded retries on a degraded upstream multiply token spend and can exhaust quota, so the backoff policy that a conventional API treats as an availability concern is here also a financial and authorisation control. 5. [reasoned] Zero-trust principles that stop at the service mesh do not cover this boundary. Mutual TLS and workload identity establish who is calling; they say nothing about what the callee does with prompt content, which model serves it, or where inference is executed. The consumer’s enforceable controls are contractual and architectural - data minimisation, redaction before egress, provider pinning and an egress record - not cryptographic. 6. [reasoned] Dependency-graph reachability is an attack surface, not only a reliability surface. Every component between the application and the model - gateway, router, DNS resolver, TLS terminator, provider edge - is a point at which prompt content can be observed or altered, and most of them are outside the application team’s review scope. Entities: vendor=OpenAI (used as the reference provider; no evaluation of its posture is made or implied); endpoint=https://status.openai.com (the endpoint RELIASTRA observes - the status plane); endpoint=https://api.openai.com (the endpoint an application depends on - the serving plane); standard=NIST SP 800-207 (zero-trust architecture vocabulary); standard=RFC 8446 (TLS 1.3; what the handshake does and does not establish) Measurement window: 2026-09-11T11:39:38Z to 2026-09-11T11:39:38Z · source https://api.reliastra.com/v1/vendors/openai · protocol HTTPS GET, JSON response, unauthenticated · observation points us-east (region labels identify the worker; 1 observation point is deployed today) · observations 1 Artifacts: diagram: Figure 1 - the dependency chain from application to model serving plane; diagram: Figure 2 - trust zones across an AI API boundary; diagram: Figure 3 - failure propagation from provider degradation to application saturation Limitations: - This is an architectural analysis. No attack was performed, no vulnerability is reported, and no provider control was tested. Nothing here should be read as a finding about any provider. - The reference architecture is deliberately generic. A deployment behind a corporate egress proxy, a private interconnect or a self-hosted gateway has a materially different boundary, and several of the recommendations here are already satisfied there. - Provider behaviour changes faster than any paper. Claims about what a provider does or does not disclose are tied to the documentation accessed on the dates in the references and may not hold later. - The paper argues from what a consumer can verify. Where it says a property is unobservable, that is a statement about the public API contract, not about the provider’s internal instrumentation. - It does not address model output integrity - prompt injection, retrieval poisoning or output filtering - which is a distinct and larger subject. Recommendations: - Draw the boundary before you choose the provider: Enumerate the zones and what crosses each one. The exercise usually shows that prompt content leaves the trust domain carrying data nobody classified, and that is cheaper to fix before integration than after. - Treat the status plane and the serving plane as separate dependencies: Monitor them separately, attribute them separately, and never roll them into one availability figure. A green status site is not evidence about the inference path, and an availability record that conflates them will misdirect an incident. - Make egress to the model boundary explicit and recorded: A single named egress point with a logged, redacted record of what left the domain turns an unenforceable contractual control into an auditable one, and gives incident response something to reconstruct from. - Bind retries to a budget, not only to a backoff curve: A token and cost budget per request path converts retry storms from a financial incident into a degraded-mode decision the application can make deliberately. - Pin what you can, and record what you cannot: Model name, API version and endpoint host are pinnable. The serving region and the underlying model version usually are not. Record both the pinned value and the observed response metadata, so a routing change is at least detectable after the fact. References: [1] Zero Trust Architecture (NIST SP 800-207), National Institute of Standards and Technology, https://csrc.nist.gov/pubs/sp/800/207/final, accessed 2026-09-11 [2] The Transport Layer Security (TLS) Protocol Version 1.3 (RFC 8446), IETF, https://www.rfc-editor.org/rfc/rfc8446, accessed 2026-09-11 [3] OpenAI status site, OpenAI, https://status.openai.com/, accessed 2026-09-11 [4] OpenAI platform documentation - API reference and rate limits, OpenAI, https://platform.openai.com/docs, accessed 2026-09-11 [5] RELIASTRA public measurement API - vendor detail, openai, Reliastra, Inc., https://api.reliastra.com/v1/vendors/openai, accessed 2026-09-11 [6] OWASP Top 10 for Large Language Model Applications, OWASP, https://owasp.org/www-project-top-10-for-large-language-model-applications/, accessed 2026-09-11 ### AWS IAM policy evaluation logic: identity vs resource URL: https://reliastra.com/research/cloud-security/aws-iam-policy-evaluation-order Published: 2026-09-13 Category: Cloud security · Type: Architecture analysis · Evidence basis: sourced Domains: Cloud security, Zero trust, Dependency security Research question: What is the exact decision procedure AWS executes when identity-based and resource-based policies disagree, and which parts of that procedure can an engineer verify before deployment rather than after a denial? Abstract: AWS evaluates every request against a single deterministic procedure spanning seven classes of policy, and the order is published: an explicit deny short-circuits across all of them, then Organizations resource control policies, then service control policies, then resource-based policies, then identity-based policies, then permissions boundaries, then session policies. Only two of the seven can grant anything; four are ceilings that can only subtract. This paper restates the procedure as an algebra - short-circuit, cap, grant - and works through three consequences that summaries of the documentation omit. First, the union of identity-based and resource-based permissions inside one account means a restrictive resource policy cannot tighten a permissive identity policy; reduction requires a ceiling or an explicit Deny. Second, whether a resource-based Allow survives an implicit deny in a permissions boundary or session policy depends on the principal form the policy names: a grant to an IAM user ARN or to a role session ARN is not capped, a grant to a role ARN is. Third, no verification route available before deployment evaluates all seven classes - the IAM Policy Simulator does not evaluate RCPs, does not accept session policies and does not simulate resource-based policies for IAM roles, while Access Analyzer custom policy checks take policy documents rather than request contexts. The paper closes with the attribution consequence: the decoded authorization message distinguishes an explicit deny from an absent allow but does not name the deciding class, so the CloudTrail principal type is the input that selects which branch of the procedure applied. Nothing here was measured. No AWS account was used, no simulator response was captured and no policy was evaluated against a live control plane; every finding is cited to an AWS primary source or argued from one, and the two places where the documentation does not settle a question are reported as unsettled rather than resolved. Scope: The single-account authorisation procedure and the cross-account conjunction, as AWS documents them, together with the verification and attribution consequences of both. Per-service semantics, privilege escalation paths, VPC endpoint policies and attribute-based access control as a design pattern are out of scope. So is any measurement: no AWS account was used for this paper, no request was issued and no policy was evaluated against a live control plane. Methodology: Close reading of AWS primary documentation - the IAM User Guide pages on policy evaluation logic, cross-account evaluation and permissions boundaries, the Organizations User Guide pages on SCPs and RCPs, and the API and CLI references for each verification route - restated as an algebra over policy classes and then applied exhaustively to enumerate a decision matrix of twenty-six request contexts. The documented exceptions are expressed as predicates that fire before the general procedure is allowed to conclude anything about a grant. Verification routes are compared by the shape of question each can answer rather than by feature list, which is what exposes the gap. Peer-reviewed accounts of the engine AWS operates against its own policy language are cited for the complexity of the underlying problem. All sources were read on 13 September 2026. Key findings: 1. [sourced] The documented procedure evaluates seven policy classes in a fixed order - explicit deny first across all of them, then Organizations RCPs, then SCPs, then resource-based policies, then identity-based policies, then permissions boundaries, then session policies - and only two of the seven can grant anything. An Allow written into an SCP, an RCP, a permissions boundary or a session policy is inert by construction. 2. [sourced] Inside one account the two granting classes combine by union, so a restrictive resource-based policy cannot reduce what a permissive identity-based policy grants. The common design of a broad role policy plus a tight bucket policy does not narrow effective permissions; only a ceiling or an explicit Deny does. 3. [sourced] Whether a resource-based Allow survives an implicit deny in a permissions boundary or a session policy is a function of the principal form the policy names. A grant to an IAM user ARN or to an IAM role session ARN is not so limited; a grant to an IAM role ARN is; and a grant made through the aws:PrincipalArn condition key with a wildcard Principal is limited only by an explicit deny in the identity-based policies. 4. [reasoned] The documented order of RCPs before SCPs cannot change any verdict. Both are ceilings that deny only when no applicable Allow exists, and an explicit Deny short-circuits the whole procedure at stage one, so the two commute. The order describes the implementation rather than a priority, which matters when a denial has to be attributed to one of them. 5. [sourced] A cross-account request is two independent evaluations - the trusted account on the principal side and the trusting account on the resource side - and the request is allowed only if both return Allow. The same-account union rule does not survive the trust boundary, which is why a caller-side policy validated in isolation still produces a denial. 6. [sourced] No verification route available before deployment evaluates all seven classes. The IAM Policy Simulator does not evaluate RCPs, does not accept session policies, and - in AWS words - does not support simulation of resource-based policies for IAM roles; Access Analyzer custom policy checks compare policy documents and take no request context, so no principal and no ceiling is in scope. 7. [sourced] Attributing a denial requires more than the denial itself. The decoded authorization message states whether the request was denied by an explicit deny or by the absence of an explicit allow, and names the principal, action, resource and condition values, but it does not name the deciding policy class. The CloudTrail principal type is what selects the branch of the resource-based rule the request took, and it is usually read last. Entities: vendor=Amazon Web Services (the control plane whose authorisation procedure is analysed); system=AWS Identity and Access Management (the service that evaluates the request; the procedure under analysis); system=AWS Organizations (attaches the two organisational ceilings above the account); system=Resource control policy (ceiling attached on the resource side; evaluated second); system=Service control policy (ceiling attached on the principal side; evaluated third); system=IAM permissions boundary (ceiling on an IAM user or role; caps the identity-based grant); system=AWS STS session policy (ceiling carried by a temporary session; evaluated last); system=IAM Policy Simulator (SimulatePrincipalPolicy and SimulateCustomPolicy; a verification route, not the enforcement engine); system=IAM Access Analyzer (custom policy checks: check-no-new-access and check-access-not-granted); system=Zelkova (the SMT-based policy analysis engine behind Access Analyzer); system=AWS CloudTrail (the record from which the principal type is read); system=sts:DecodeAuthorizationMessage (returns explicit deny versus absent allow, not the deciding policy class); dependency=Amazon S3 (the example resource carrying a resource-based policy); dependency=AWS KMS (the documented exception in which the key policy is authoritative); standard=NIST SP 800-207 (zero-trust vocabulary: per-request authorisation, no trust by location) Artifacts: repository: Paper artifact directory (research/aws-iam-evaluation-order); script: Figure exporter (research/aws-iam-evaluation-order/figures/export-figures.mjs); diagram: Figure 1 - the seven stages of the single-account procedure (research/aws-iam-evaluation-order/figures/fig-1-evaluation-pipeline.svg); diagram: Figure 2 - union, ceilings, and the cross-account conjunction (research/aws-iam-evaluation-order/figures/fig-2-policy-algebra.svg); diagram: Figure 3 - the same-account tightening fallacy (research/aws-iam-evaluation-order/figures/fig-3-tightening-fallacy.svg); diagram: Figure 4 - the verification gap (research/aws-iam-evaluation-order/figures/fig-4-verification-gap.svg); diagram: Figure 5 - the attribution path (research/aws-iam-evaluation-order/figures/fig-5-attribution-path.svg) Limitations: - AWS publishes the evaluation algorithm as a specification and does not publish the enforcement code. Every claim here is about documented behaviour, not about an implementation, and the difference is not recoverable from documentation. - This paper measured nothing. No AWS account was used, no request was issued, no simulator response was captured and no policy was evaluated against a live control plane. Findings are cited or reasoned and are labelled as one or the other. - Two cases are left unsettled because AWS does not settle them: whether a permissions boundary or session policy caps a resource-based grant written against an IAM role ARN in the presence of an identity-based implicit deny, and the third bullet of the session-policy stage, which read in sequence appears to allow a role session that the preceding bullet has already denied. Both are reported rather than resolved. - Behaviour is service-specific. Which actions support resource-based policies, and how a given service combines them with identity-based policies, is documented per service. This paper names S3, KMS and IAM role trust policies as examples and does not enumerate services. - The verification-capability matrix reflects published documentation and third-party reports as of the access dates shown. AWS changed the simulator surface in July 2026 and can change it again; two entries in that matrix rest on third-party reports and are labelled as reports at the point of use. - No customer policy, account identifier, principal name or credential appears in this paper or in its artifact directory. Every ARN, principal name and bucket name in an example is an invented fixture and is presented as one. Recommendations: - Decide which plane is primary, at design time: For a resource shared across accounts or teams the resource is the control plane and its policy is the authoritative statement; for a workload inside one account the identity is primary and resource policies are additions rather than constraints. Writing the choice down is the cheapest control available and it is what makes the other five reviewable. - Stop tightening with resource policies inside one account: A restrictive bucket policy against a permissive role policy is a union, and the permissive side wins. Use a permissions boundary, a service control policy, a resource control policy or an explicit Deny - the only four mechanisms that reduce effective permissions inside an account. - Name the principal form deliberately in every resource-based policy: A grant to a role ARN is capped by the boundary and session policy attached to that role; a grant to the role session ARN is not. If the boundary is meant to apply, the policy has to name the role, and that decision is currently made in code and reviewed nowhere. - Gate policy changes with a diff check rather than a simulation: check-no-new-access answers the question a pipeline can actually ask, and it answers it formally. Reserve the simulator for request-shaped questions and accept that it cannot answer the ones involving RCPs, session policies or resource-based grants to IAM roles. - Write Deny conditions with BoolIfExists: Bool treats an absent context key as no match, so a Deny guarding MFA written with Bool does not fire for the session that has no MFA context - the session the statement was written to stop. BoolIfExists treats the absent key as a match. - Attribute a denial from the record, not from the message: Read the CloudTrail principal type first, then the decoded authorization message if the operation returned one, then the policy inventory. Reading policies first is how an hour disappears into a permissions boundary that never applied to the principal that made the request. References: [1] Policy evaluation logic, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html, accessed 2026-09-13 [2] How AWS enforcement code logic evaluates requests to allow or deny access, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic_policy-eval-denyallow.html, accessed 2026-09-13 [3] Cross-account policy evaluation logic, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic-cross-account.html, accessed 2026-09-13 [4] Permissions boundaries for IAM entities, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html, accessed 2026-09-13 [5] AWS JSON policy elements: Principal - role and role session principals, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html, accessed 2026-09-13 [6] Cross account resource access in IAM, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html, accessed 2026-09-13 [7] Resource control policies, Amazon Web Services, https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html, accessed 2026-09-13 [8] Service control policies, Amazon Web Services, https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html, accessed 2026-09-13 [9] Key policies, Amazon Web Services, https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html, accessed 2026-09-13 [10] AWS JSON policy elements: NotPrincipal, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html, accessed 2026-09-13 [11] SimulatePrincipalPolicy - AWS IAM API Reference, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/APIReference/API_SimulatePrincipalPolicy.html, accessed 2026-09-13 [12] SimulateCustomPolicy - AWS IAM API Reference, Amazon Web Services, https://docs.aws.amazon.com/IAM/latest/APIReference/API_SimulateCustomPolicy.html, accessed 2026-09-13 [13] check-no-new-access - AWS CLI Command Reference, Amazon Web Services, https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/check-no-new-access.html, accessed 2026-09-13 [14] DecodeAuthorizationMessage - AWS Security Token Service API Reference, Amazon Web Services, https://docs.aws.amazon.com/STS/latest/APIReference/API_DecodeAuthorizationMessage.html, accessed 2026-09-13 [15] CloudTrail userIdentity element, Amazon Web Services, https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-user-identity.html, accessed 2026-09-13 [16] Semantic-based Automated Reasoning for AWS Access Policies using SMT (DOI 10.23919/FMCAD.2018.8602994), IEEE, Formal Methods in Computer-Aided Design (FMCAD), https://ieeexplore.ieee.org/document/8602994 [17] Stratified Abstraction of Access Control Policies (DOI 10.1007/978-3-030-53288-8_9), Springer, Computer Aided Verification (CAV 2020), LNCS 12224, https://link.springer.com/chapter/10.1007/978-3-030-53288-8_9 [18] A Billion SMT Queries a Day (Invited Paper) (DOI 10.1007/978-3-031-13185-1_1), Springer, Tools and Algorithms for the Construction and Analysis of Systems (TACAS), https://link.springer.com/chapter/10.1007/978-3-031-13185-1_1 [19] Zero Trust Architecture (NIST SP 800-207), National Institute of Standards and Technology, https://csrc.nist.gov/pubs/sp/800/207/final, accessed 2026-09-13 [20] iam simulate-principal-policy and simulate-custom-policy ignore --resource-policy for sts:Assume* actions, aws-cli issue #10314, filed by a third party, https://github.com/aws/aws-cli/issues/10314, accessed 2026-09-13 [21] IAM Policy Simulator has migrated to the IAM console, Classmethod DevelopersIO, https://dev.classmethod.jp/en/articles/iam-policy-simulator-iam-console-update/, accessed 2026-09-13 [22] The RELIASTRA research agenda, Reliastra, Inc., https://reliastra.com/research/reliastra-research-agenda, accessed 2026-09-13 [23] The trust boundary of an AI API dependency, Reliastra, Inc., https://reliastra.com/research/cloud-security/ai-api-trust-boundary, accessed 2026-09-13 ## Public observatory - Index: https://reliastra.com/observatory - Detail pattern: https://reliastra.com/observatory/{vendor} (only for vendors with real telemetry; empty or fabricated vendors are never generated) - Incident search: https://reliastra.com/observatory/incidents - the cross-vendor public incident search. Filters: vendor, category, region, status (open|resolved); an RSS feed of recent detections is at /observatory/incidents/feed.xml. Records are endpoint scoped single-region measurements with the detection rule attached, never vendor-wide outage claims. - Incident pattern: https://reliastra.com/observatory/{vendor}/incidents/{incident-id} - only for incidents RELIASTRA actually holds on its public incident channel; pages exist exactly when records exist, and a record is published for the evidence-retention window the API documents (365 days), after which the URL 404s. These pages are not described as permanent, because they are not. - Incident record JSON sidecar: https://reliastra.com/observatory/{vendor}/incidents/{incident-id}/index.json - the same record the HTML page renders, as JSON, resolved through the same reads (never a scrape of the page). 404 when the record does not exist; 5xx when the API is unreadable. noindex by design: the HTML record is the indexable unit. - Incident evidence artifact: https://reliastra.com/api/v1/public/incidents/{incident-id}/evidence - the frozen, hashed document of one observed incident: the claim, the detection rule and provenance, and every raw observation row of the window. Immutable per version; a resolution freezes a new version that supersedes (never edits) the open freeze, and https://reliastra.com/api/v1/public/incidents/{incident-id}/evidence/versions/{n} pins any version. The served body's sha256 is in the ETag header and inside the document's "verification" block, which also carries the recipe to recompute it. 404 while no artifact is frozen yet. - Direct answer pattern: https://reliastra.com/down/{vendor} - the answer to "is {vendor} down?", composed from the same record read and the same answer functions as the vendor record's masthead, so the two surfaces state one answer. Endpoint scoped; a stale or absent observation publishes "unknown" rather than an old state; a category slug or an untracked name 404s; a failed read serves 5xx rather than an answer. JSON twin: https://reliastra.com/down/{vendor}/index.json (noindex; carries the question, the lead answer, the measured facts, the caveats and the freshest observation's own timestamp). - Feeds (RSS 2.0): https://reliastra.com/observatory/incidents/feed.xml - cross-vendor detected incidents (guid = incident id, description = the exact measurement statement). https://reliastra.com/observatory/{vendor}/incidents/feed.xml - the same items for one vendor (404 for untracked names). https://reliastra.com/observatory/catalog.xml - tracked-dependency announcements (guid = vendor slug, pubDate = the catalog row's own date or none). An unreadable API degrades every feed to a valid empty document, never a 5xx. - Each vendor page exposes: current state, availability windows with the observation count behind every figure, latency (mean/p95), monitored endpoints with the observation point that probed them, incident history, methodology note, the observation interval as measured from the record's own telemetry, and all timestamps in UTC. The deployed default probe interval is 300 seconds; a record prints the interval it can measure rather than asserting a schedule it cannot see, so a page may report a different number. - The enumerated list of published records lives in https://reliastra.com/llms.txt, which reads the same catalog the sitemap does. This file documents the patterns; it does not repeat the list, so the two cannot drift. - A window with no observations reads "insufficient data". It never reads 0% or 100%. - IMPORTANT - what the public records measure: scheduled HTTP GETs against the vendor's *listed public endpoint* (currently vendor status sites such as https://status.openai.com), recording HTTP status, latency and transport errors. A page never asserts that the vendor's API or product is up or down beyond the listed endpoint, and RELIASTRA does not read the status text the vendor publishes at those URLs. State word "Responding" = the endpoint answered with the expected response in the last five observations. ## Verification checklist for agents 1. Fetch https://reliastra.com/ (expect H1 + proposition in initial HTML, no JS required). 2. Fetch https://reliastra.com/sitemap.xml (expect canonical HTTPS URLs only). 3. Fetch https://reliastra.com/robots.txt (expect private paths disallowed, sitemap listed). 4. Fetch https://reliastra.com/llms.txt and https://reliastra.com/llms-full.txt (expect 200 text/plain). 5. Fetch a vendor page and confirm uptime/latency/incidents render server-side. 6. Confirm /login, /admin, /dashboard, /portal/*, /reports/* are noindex / gated. 7. Validate JSON-LD blocks parse (Organization, WebSite, SoftwareApplication, BreadcrumbList, TechArticle, FAQPage). ## Contact - support@reliastra.com (product), security@reliastra.com (vulnerability reports), https://github.com/ReliaAstra, https://github.com/EmmanuelAdesina (maintainer) ## Retired URLs (308 redirects in next.config.ts) /track and /track/* -> /observatory and /observatory/*; /external-dependency-intelligence and /dependency-monitoring -> /product; /incident-evidence and /sla-evidence -> /product/evidence.