Dashboard User Guide
OGC API Processes — Secure Dimensions GmbH · index.html (same origin as the API)
Getting started
The OGC Processes Dashboard lets you deploy geospatial processing tasks as Docker containers, execute them with custom inputs, and retrieve results stored on IPFS — all through a standard-compliant OGC API Processes interface.
Sign in
index.html on the same host as the API (e.g.
http://localhost:3000/index.html when running locally).
The dashboard always calls the API at window.location.origin — no separate server URL to configure.
openid scope only).
To deploy processes or use bridge networking, request access from an admin —
see Requesting access below.
Dashboard overview
The sidebar contains eight tabs:
| Tab | What it does | Requires |
|---|---|---|
| Dashboard | Metrics overview, recent jobs, activity log | openid |
| Deploy | Register a new Docker image as an OGC process | ogcapi:deploy |
| Execute | Run a deployed process with custom inputs | ogcapi:execute |
| Process list | Browse all deployed processes; delete your own | openid |
| Job monitor | Track job status and retrieve IPFS result links | openid |
| Callbacks | View webhook notifications received by the dashboard | openid |
| API Docs | Endpoint reference and link to Swagger UI | — |
| Admin | Manage user privileges (admin password required) | admin login |
| Settings | Token info, privilege requests, Forget Me | openid |
Tabs requiring privileges you do not yet have are dimmed in the sidebar. The Deploy and Execute buttons are disabled with a tooltip explaining the required scope.
Deploying a process
Deploying registers a Docker image as a named process. The server pulls the image and verifies its sha256 digest before registration.
ogcapi:deploy privilege. See Requesting access.
Fields
| Field | Description |
|---|---|
| Process ID | Unique identifier, alphanumeric + hyphens/underscores. Must be unique on this server. |
| Title | Human-readable name shown in the process list. |
| Description | Short explanation of what the process does. |
| Docker image | Full image reference, e.g. docker.io/myorg/myprocess:1.0. |
| Image digest | The sha256:… digest of the image. Used to verify the pulled image. Get it with docker inspect --format='{{"{{"}}index .RepoDigests 0{{"}}"}}' IMAGE. |
| Network mode | none (fully isolated, default) or bridge (outbound internet). Bridge is image-specific and one-time — requires an admin grant for the exact image and digest. |
| IPT compliant | When checked, deploy sends iptCompliant: true. The image must have OCI label ogcapi.describeProcessing=true and implement describeProcessing. Leave unchecked for standard OGC processes (echo, transform, etc.). |
| Contact email | Required when requesting privileges. Used so the administrator can contact you and to send the outcome email (accepted or denied). |
| Inputs schema | JSON object describing process inputs in OGC schema format (see below). |
| Outputs schema | JSON object describing expected outputs. |
Input/output schema format
Each field in the schema is an object with a title and a JSON Schema schema:
{
"name": {
"title": "User name",
"schema": { "type": "string", "minLength": 1 }
},
"count": {
"title": "Number of results",
"schema": { "type": "integer", "default": 10 },
"minOccurs": 0
}
}
Set "minOccurs": 0 to mark a field as optional.
Process image I/O contract
Your Docker image must follow the stdin → stdout convention. stderr has several distinct roles (see next subsection).
| Stream | Direction | Content |
|---|---|---|
stdin | server → container | JSON inputs (execute), or describe context JSON (IPT second container) |
stdout | container → server | Result bytes → IPFS on success; UTF-8 error text on failure (Redis errorOutput, not IPFS) |
stderr | container → server | Structured machine lines under worker runs — not human logs (see below) |
Exit code 0 = success. Non-zero = failed job.
stderr: multiple purposes (worker / IPT)
When the worker runs a container it sets OGC_JOB_ID and PYTHONUNBUFFERED=1 (Python).
Parse stderr as one prefix per line. Do not write human progress logs to stderr in production —
use them only for local CLI testing.
| Line prefix | Example | Purpose |
|---|---|---|
OGC_PROCESSING_PROGRESS: |
OGC_PROCESSING_PROGRESS:42 |
Async job progress 0–100. Updates Redis processProgress and the dashboard progress bar while the job runs. |
OGC_PROCESSING_META: |
OGC_PROCESSING_META:{"bbox":[…]} |
Execute-phase metadata for IPT describeProcessing (parsed into stdin processing). |
| (human text) | [INFO] Fetching… |
Local development only. Avoid under OGC_JOB_ID when stdout is binary (e.g. GeoPackage). |
OGC_PROCESSING_PROGRESS=42 and OGC_PROCESSING_PROGESS:42 are accepted aliases.
Emit progress lines as they happen (flush after each line).
Creating compliant echo processes (Node.js)
An echo process is the smallest useful example: it reads the JSON inputs object from
stdin, then writes a JSON object to stdout. Use it to verify deploy and execute
before building more complex geoprocessing logic.
Below are two variants:
| Variant | Deploy checkbox | Dockerfile | Runtime |
|---|---|---|---|
| 1 — OGC API Processes | IPT compliant unchecked (iptCompliant: false) |
No special OCI label | Only the execute path: stdin JSON → stdout JSON |
| 2 — IPT extension | IPT compliant checked (iptCompliant: true) |
LABEL ogcapi.describeProcessing=true |
Execute path and describeProcessing when OGC_ACTION=describeProcessing |
stdout (JSON, GeoPackage bytes, …).
On failure under the worker, write the error message to stdout (not stderr).
Use structured lines on stderr for progress and IPT metadata — see
stderr: multiple purposes.
1. OGC API Processes echo (standard)
On execute, the server writes the process inputs object to stdin and closes it.
Your script parses that JSON and echoes it back on stdout (any valid JSON shape is fine for a smoke test).
index.js'use strict';
function runExecution() {
const chunks = [];
process.stdin.on('data', (c) => chunks.push(c));
process.stdin.on('end', () => {
let inputs = {};
try {
inputs = JSON.parse(Buffer.concat(chunks).toString('utf8'));
} catch (_) {
/* empty or invalid stdin → treat as {} */
}
// Echo: return the same object the server sent on stdin
process.stdout.write(JSON.stringify(inputs));
process.exit(0);
});
process.stdin.resume();
}
runExecution();
DockerfileFROM node:20-alpine
WORKDIR /app
COPY index.js ./
USER node
CMD ["node", "index.js"]
Example local test (inputs on stdin, result on stdout):
echo '{"message":"hello"}' | docker run --rm -i docker.io/myorg/echo-ogc:1.0
# → {"message":"hello"}
On the Deploy tab, leave IPT compliant unchecked.
Example output schema: a single result field is optional for a raw echo; many processes use:
{
"result": {
"title": "Echo output",
"schema": { "type": "object", "contentMediaType": "application/json" }
}
}
2. IPT-compliant echo (two containers)
IPT deploys require LABEL ogcapi.describeProcessing=true and a
describeProcessing handler. Production flow:
- Execute — inputs on stdin; result on stdout; on stderr:
OGC_PROCESSING_PROGRESS:0…:100thenOGC_PROCESSING_META:{…}. - IPFS — server uploads stdout (success only).
- describeProcessing — second container with
OGC_ACTION=describeProcessing; stdin carriesprocessing,iptLabels,execution(IPFS, hash, size); stdout is a STAC Item. Server merges IPFS links andfile:*onassets.PRODUCT.
index.js'use strict';
function describeProcessing(context) {
return {
type: 'Feature',
stac_version: '1.0.0',
id: `${context.processId}-${context.jobId}`,
geometry: null,
properties: { datetime: new Date().toISOString(), ...(context.iptLabels || {}) },
assets: {},
};
}
function emitProgress(pct) {
if (!process.env.OGC_JOB_ID) return;
process.stderr.write(`OGC_PROCESSING_PROGRESS:${pct}\n`);
}
function emitMeta(obj) {
process.stderr.write(`OGC_PROCESSING_META:${JSON.stringify(obj)}\n`);
}
function runExecution() {
const chunks = [];
process.stdin.on('data', (c) => chunks.push(c));
process.stdin.on('end', () => {
let inputs = {};
try { inputs = JSON.parse(Buffer.concat(chunks).toString('utf8')); } catch (_) {}
emitProgress(0);
emitProgress(50);
process.stdout.write(JSON.stringify({ result: inputs }));
emitProgress(100);
emitMeta({ probe: true });
process.exit(0);
});
process.stdin.resume();
}
function runDescribeFromStdin() {
const chunks = [];
process.stdin.on('data', (c) => chunks.push(c));
process.stdin.on('end', () => {
let ctx = { jobId: process.env.OGC_JOB_ID };
try { if (chunks.length) ctx = JSON.parse(Buffer.concat(chunks).toString('utf8')); } catch (_) {}
process.stdout.write(JSON.stringify(describeProcessing(ctx)));
process.exit(0);
});
process.stdin.resume();
}
if (process.env.OGC_ACTION === 'describeProcessing') {
runDescribeFromStdin();
} else {
runExecution();
}
DockerfileFROM node:20-alpine
LABEL "ogcapi.describeProcessing"="true"
WORKDIR /app
COPY index.js ./
USER node
CMD ["node", "index.js"]
Test the IPT metadata handler locally (see processes/README.md for the stdin schema):
echo '{"jobId":"local","processId":"demo","inputs":{},"execution":{"outputSha256":"sha256:00","outputBytes":1,"mediaType":"application/json","ipfs":{"cid":"bafy","ipfsUri":"ipfs://bafy","gatewayUrl":"https://example"}},"iptLabels":{}}' \
| docker run --rm -e OGC_ACTION=describeProcessing -i docker.io/myorg/echo-ipt:1.0
# → STAC Item (type Feature)
Test execute (simulate worker — note stderr progress + meta lines):
echo '{"name":"Ada"}' | docker run --rm -e OGC_JOB_ID=test-1 -i docker.io/myorg/echo-ipt:1.0
# stdout → {"result":{"name":"Ada"}}
# stderr → OGC_PROCESSING_PROGRESS:0 … :100, OGC_PROCESSING_META:…
On deploy, enable IPT compliant. Without the label, deploy fails with
422 (missing ogcapi.describeProcessing).
processes/ogc-api-process/ (OGC core) and
processes/ogc-api-process-ipt/ (IPT).
Build, push, and deploy
docker build -t docker.io/myorg/echo-ogc:1.0 .
ALLOWED_REGISTRIES, if configured).
docker inspect --format='{{"{{"}}index .RepoDigests 0{{"}}"}}' docker.io/myorg/echo-ogc:1.0
— copy the sha256:… part into Image digest.
{"message": "test"}, and confirm the job result on IPFS matches the echo output.
ALLOWED_REGISTRIES
(e.g. docker.io/securedimensions). Images outside the allowlist are rejected with
400 Registry Not Allowed.
hello-user
example process. Click Clear to reset all fields.
Executing a process
The Execute tab lets you run any deployed process with custom inputs.
Choose Execution mode: Async (default, Prefer: respond-async)
returns a job ID and runs in the background, or Sync waits for the result inline
(IPFS link in the response when successful).
Monitoring jobs
The Job monitor tab lists all your jobs and their current status.
| Status | Meaning |
|---|---|
| accepted | Job is queued, waiting for the worker to pick it up. |
| running | Container is executing. Stdout is being streamed. |
| successful | Container exited with code 0. Result is available on IPFS. |
| failed | Container exited with a non-zero code. Check the error message. |
| dismissed | Job was dismissed via DELETE /jobs/{id}. No results; polling and success callbacks stop. |
Click the IPFS link next to a successful job to open the result in the IPFS gateway. The result is a JSON document (or binary file, e.g. GeoPackage) stored at the shown CID.
The job list auto-refreshes every few seconds while running jobs are present.
Click Dismiss to mark a job as dismissed (OGC dismiss); it stays in the list
with status dismissed but results are no longer available.
Process list
The Process list tab shows all deployed processes in two sections:
- My processes — processes you deployed. A Delete button is shown. Deleting a process does not affect already-running jobs.
- Other users' processes — deployed by other users. You can execute them but not delete them. The owner's sub is shown in abbreviated form.
Click Run next to any process to jump straight to the Execute tab with that process pre-selected.
API documentation
The API Docs tab shows a quick endpoint reference table and provides three action buttons:
- Open Swagger UI — opens
ogc-api-docs.htmlin a new tab with the live OpenAPI 3.0 spec loaded from the server. You can use Try It Out for any endpoint after entering your Bearer token in the Authorize dialog. - Download JSON — downloads the raw
openapi.jsonspec. - Copy URL — copies the OpenAPI spec URL to the clipboard.
The OpenAPI spec is at GET /api/1.0/openapi.
The service landing page is GET / (JSON by default, or HTML with
?f=html or Accept: text/html per OGC API Common).
Admin panel
The Admin tab is for server administrators. It requires a separate username and password (not your AUTHENIX credentials).
Admins can toggle two privileges per user:
| Privilege | Grants | Type |
|---|---|---|
ogcapi:deploy | Deploy, replace, and undeploy process images | Blanket (persistent) |
bridge | Deploy one specific process image with outbound network access (e.g. fetching SensorThings API data). The tag latest is not permitted. | Image-specific, one-time |
How bridge grants work
Unlike ogcapi:deploy, a bridge grant is not a standing permission.
Each grant is tied to a specific Docker image name and sha256 digest
and is consumed after a single successful deploy. A new grant must be requested
and approved for each distinct image+digest that needs bridge networking.
To add a bridge grant in the Admin panel, click + Grant bridge next to the user, enter the full image reference and its sha256 digest, then click Grant. The grant appears in the table and can be revoked before it is consumed.
:1.2)
to ensure the grant is pinned to a known, auditable image.
Users appear in the admin table as soon as they make their first authenticated API request. Privilege changes take effect immediately — no restart required.
Settings & privacy
The Settings tab shows:
- Your authenticated identity (sub, name, email) and current effective privileges
- Your raw access token (click to copy)
- Decoded ID token claims
- AUTHENIX endpoint information
Forget Me
The Forget Me button permanently deletes all personal data held about you on this server — name, email, subject identifier, privilege requests, privilege grants, and job history. You must undeploy all your processes first before this is permitted. After deletion you are automatically signed out.
See the Privacy Notice for full details of what data is stored and why.
Requesting access
New users have read-only access by default. To deploy processes or use bridge networking, go to Settings → Request additional privileges:
Requesting ogcapi:deploy
Privilege request workflow (admin)
Pending requests appear in Admin → Pending privilege requests.
- Click Handle on a request.
- In the detail panel, use Set privileges for this user (deploy toggle, bridge grant form pre-filled from the request).
- Optionally add a message, then Notify user (access granted) or Deny and notify user (explanation required).
- The user is highlighted in the User privileges table below.
Revoking existing access
When you revoke a grant that is already active (deploy, execute, or a bridge grant), the dashboard opens Revoke access and notify user. Enter a reason and click Revoke and notify user — the user receives an email explaining what was removed and why.
Requesting bridge network access
latest tag is not accepted — use an explicit version tag.
docker.io/myorg/sta-fetcher:1.2 — not :latest.
sha256:abc123….
Get it with: docker inspect --format='{{"{{"}}index .RepoDigests 0{{"}}"}}' IMAGE
FAQ
Why is the Deploy button greyed out?
You do not yet have the ogcapi:deploy privilege. Request it from an admin via Settings → Request additional privileges.
Why is the bridge network option not visible?
The bridge option only appears in the network selector when an admin
has granted you a bridge privilege for a specific image and digest.
Bridge grants are one-time and image-specific — the option disappears
again after you deploy with it, because the grant is consumed.
Request a new bridge grant for each image+digest you need bridge networking for.
What does IPT compliant mean on deploy?
It enables the IPT extension: the image must carry label ogcapi.describeProcessing=true.
After a successful execute the server runs describeProcessing in a second container.
Execute may emit OGC_PROCESSING_PROGRESS and OGC_PROCESSING_META lines on stderr
(see stderr roles). Standard processes without the label should leave the checkbox unchecked.
See Creating compliant echo processes for Node.js examples.
How does async job progress work?
During execute, the process writes lines OGC_PROCESSING_PROGRESS:<0–100> to stderr.
The worker updates the job record and the dashboard progress bar. Poll
GET /api/1.0/jobs/{jobId} for processProgress and jobProgress.
Why must I enter a contact email?
So the administrator can reach you with questions and so you receive the outcome email (approved or denied). If AUTHENIX provides an email, it is pre-filled; you may change it.
My job is stuck at "accepted" — what happened?
The worker process may not have started a listener for your process yet. This can happen if the process was deployed very recently. Wait a few seconds and refresh. If it remains stuck, check the worker logs.
Where is the process result stored?
Results are stored on IPFS (InterPlanetary File System) via the locally operated Kubo node. Each result is identified by a content hash (CID). The gateway URL shown in the job results lets you open it directly in a browser.
How long are job results kept?
Job records are retained for 7 days, after which they are automatically deleted from Redis. The IPFS content may persist longer depending on pinning configuration.
Can I execute another user's process?
Yes — all deployed processes are visible in the Process list and can be executed by any user with the ogcapi:execute scope. You cannot delete another user's process.
How do I delete my data?
Use the Forget Me button in Settings after undeploying all your processes. See the Privacy Notice for your full GDPR rights.