devguard

Trust Center

Publish your compliance posture as JSON and build your own public trust page.

Overview

The Trust Center exposes a curated, read-only view of your organization's compliance posture over a single public JSON endpoint. You choose exactly what to publish here: selected frameworks with their status, subprocessors, and downloadable certificates. Any website can fetch it and render a live "here's the compliance we fulfil" page. Any surrounding prose (an intro, disclosures, data-processing notes) is authored on your own site around this data.

devguard provides the API only. There is no hosted page and no embeddable widget: you fetch the URL and build the page in your own site, with your own branding. The payload contains no branding; it is pure compliance data.

Two rules define the whole surface:

  • Nothing is public unless you explicitly add it and enable the Trust Center.
  • The response is a strict field allowlist. Internal data (risk scores, owners, storage keys, per-control coverage) never crosses the wire.

Endpoint

GET https://app.devguard.ch/api/trust/{publicId}
  • No authentication. The data is public by design, and the response allows any origin (Access-Control-Allow-Origin: *) so you can call it directly from a browser.
  • {publicId} is an opaque, rotatable handle (e.g. trust_a1B2c3...) shown on this page. Rotating it immediately revokes the old URL.
  • Disabled or unknown handles return 404, indistinguishably, so the endpoint never reveals that a not-yet-public Trust Center exists.
  • Responses carry a short Cache-Control (max-age=60, stale-while-revalidate=300) and are rate-limited per IP.

Response shape

{
  "generatedAt": "2026-07-15T09:30:00.000Z",
  "frameworks": [
    {
      "id": "b7f1...",
      "name": "ISO 27001",
      "identifier": "ISO27001",
      "identifierColor": "#3b82f6",
      "version": "2022",
      "displayMode": "badge",
      "status": "on_track"
    },
    {
      "id": "c3a2...",
      "name": "SOC 2",
      "identifier": "SOC2",
      "identifierColor": "#8b5cf6",
      "version": "Type II",
      "displayMode": "certified",
      "certified": {
        "body": "Prescient Assurance",
        "date": "2026-03-01",
        "certificateItemId": "e5d4..."
      }
    }
  ],
  "subprocessors": [
    {
      "id": "d4c3...",
      "name": "Amazon Web Services",
      "website": "https://aws.amazon.com",
      "description": "Cloud infrastructure hosting.",
      "category": "CLOUD",
      "relationship": "SUB_PROCESSOR",
      "location": "AWS eu-central-1, Frankfurt"
    }
  ],
  "certificates": [
    {
      "id": "e5d4...",
      "title": "SOC 2 Type II Report",
      "documentKind": "SOC2",
      "issuedAt": "2026-03-01T00:00:00.000Z",
      "expiresAt": "2027-03-01T00:00:00.000Z",
      "downloadable": true,
      "downloadPath": "/api/trust/trust_a1B2c3.../certificate/e5d4..."
    }
  ]
}

The payload is a generatedAt timestamp plus three arrays — frameworks, subprocessors, and certificates. generatedAt is when the response was produced (accurate to the short cache window); show it as a "last updated" signal. Wrap the rest in your own page layout and copy.

Frameworks

Each framework carries a displayMode that controls what detail is exposed:

displayModeExtra fieldMeaning
badgestatusA status label only: completed, on_track, or in_progress.
percentagecompletionAn integer 0100 coverage percentage.
certifiedcertifiedA manual assertion (body, date) decoupled from computed coverage, optionally tied to a published certificate via certificateItemId.

A framework below the "in progress" threshold is never published in badge or percentage mode, so you can render any framework you receive with confidence. Use the framework's own identifierColor as a local accent (a chip, a meter fill, a seal), never as text on a filled background, so contrast holds whatever color the API returns.

Subprocessors

relationship is one of PROCESSOR or SUB_PROCESSOR. location is the location name only (never a full address). description is present only when you chose to publish it.

Certificates

Expired certificates are omitted automatically. When downloadable is true, the object includes a relative downloadPath. Prefix it with the same origin you fetched the payload from:

GET https://app.devguard.ch{downloadPath}

This mints a fresh, short-lived presigned URL per request and 302-redirects to it, so a plain link works. The download responds only while the Trust Center is enabled and the certificate is marked downloadable; otherwise it returns 404. The underlying storage key is never exposed.

Recreate this page yourself

Open Preview above and switch to the Source tab for a single, self-contained React component that fetches the API and renders the response: the same three arrays, mapped into markup you can style yourself. Copy it out and swap in your own header, brand and surrounding copy.

The steps below walk through how it works.

1. Fetch the payload

const API = 'https://app.devguard.ch';
const PUBLIC_ID = 'trust_a1B2c3...';

const res = await fetch(API + '/api/trust/' + PUBLIC_ID);
if (!res.ok) {
  // 404 = not published, disabled, or wrong handle
  throw new Error('Trust Center is not available');
}
const trust = await res.json();

2. Render frameworks by display mode

Each framework is one of three shapes. Branch on displayMode:

trust.frameworks.map((f) => {
  if (f.displayMode === 'badge') return renderStatusPill(f.status);
  if (f.displayMode === 'percentage') return renderMeter(f.completion);
  return renderCertified(f.certified.body, f.certified.date);
});

For a certified framework you can tie the claim to its downloadable proof: find the certificate whose id matches f.certified.certificateItemId and link to API + cert.downloadPath.

3. Render certificates

Every certificate is listed; downloadable decides whether you show a download link or an "available on request" note. Expired certificates are already removed, so you don't filter them yourself. downloadPath is relative, so prefix it with the API origin.

4. Render subprocessors

A flat list, ideal for a table. relationship is PROCESSOR or SUB_PROCESSOR; location is a name only; description is present only when you chose to publish it.

Everything else, from your logo and brand color to hero copy, data-region facts and footer, is yours to author around this data. Because the endpoint is CORS-enabled, the same fetch runs unchanged in the browser.

Enabling the Trust Center

  1. Add the frameworks, subprocessors, and certificates you want to publish (admins only).
  2. Use the Preview to confirm exactly what will be exposed.
  3. Toggle Public on and share the API URL with your site.

How is this guide?

On this page