Skip to content
Select theme

Host your own app (experimental)

View Markdown

Experimental: External app hosting and integration are still evolving. This guide covers the current backend SDK and service-identity path. Public package distribution and delegated per-user sign-in are not yet available; interfaces and setup may change.

Host your app on infrastructure you choose, and use OpenEngineering for its engineering data, relationships and change control.

For example, build a supplier portal, a verification dashboard or a specialised part review interface. Its objects can be the same objects your team uses in the OpenEngineering workspace.

Your browser interface calls your app’s backend. The backend uses the platform SDK over HTTPS to call the OpenEngineering API host.

Your browser interface
|
Your app backend, hosted by you
| SDK + platform authentication over HTTPS
OpenEngineering API host
|
Common branchable, secure engineering data plane

Your app owns its interface and hosting. The platform owns its object model, access checks, validation, attribution and engineering history.

The current repository provides the SDK modules and HTTPS transport. A public package installation and third-party user sign-in quickstart depend on their release and distribution; the package names below describe the repository modules.

ModuleUse it for
ObjectsRead, query and change objects; follow relationships and structures; execute typed actions
BranchesCreate a branch, inspect differences, submit a proposal and merge authorized work
OntologyDraft, validate and publish type and view configuration
AdministrationManage projects, membership and service identities

Use the typed module methods. The server checks the caller’s permissions for each operation; naming a project or branch does not grant access.

A server app can use the current Node HTTPS transport. Browser-direct transport and cross-origin setup should be verified against your target deployment before choosing that architecture.

For a backend job or an internal app with deliberately shared application-level access, use a service identity.

An administrator creates the identity, grants it the project or organisation capabilities it needs, and issues a credential. A new service identity has no grants. Store the issued secret in your backend’s secret store.

  1. In the intended organisation, open Admin and choose Service identities.
  2. Under Create a service identity, enter a Service identity name and choose Create. Keep the returned identity reference.
  3. Grant its initial project membership through the Administration SDK or CLI, using the identity reference, project identifier and the deployment’s role key. The current Organisation members picker only offers identities already in its member list, so it cannot perform the first grant for a new identity. Prefer project scope for a single-project integration.
  4. Return to Service identities and choose Issue credential for that identity. Copy the secret and credential reference into your backend secret store, then close the dialog with Done. The secret is shown once.
  5. Exchange the credential and test a read against the intended project. Check that the granted access matches the integration’s needs before adding writes.

An administrator with a supported CLI session can inspect the current input shape and make the initial grant:

Terminal window
oe2 help admin-sdk grantMembership
oe2 admin-sdk listMembers --selector '{"projectId":"<project-id>"}' --input '{}' --json
oe2 admin-sdk grantMembership --input '{"principalId":"<identity-id>","scopeKind":"project","scopeId":"<project-id>","roleKey":"<role-key>"}'

Replace every placeholder with the platform’s returned identifiers and an available role key. Use the roles returned by listMembers, or ask its administrator, for the role keys; do not assume a display label is a key.

Credential issuance and membership grants are separate actions. Issuing a credential does not add data access. For exact programmatic equivalents, use oe2 help admin-sdk createServiceIdentity, grantMembership and issueServiceCredential. Access and permissions explains membership scope.

The backend exchanges that credential for a short-lived platform session, then constructs the SDK client with its access token. The session is attached to the service identity’s organisation.

This example reads one object using the current SDK interfaces:

import {
createHttpsTransport,
createObjectsTransportClient,
serviceCredential,
toCredential,
} from "@oe2/objects-sdk";
export async function readEngineeringObject(config: {
origin: string;
credentialId: string;
credentialSecret: string;
projectId: string;
objectId: string;
}) {
const transport = createHttpsTransport(config.origin);
const session = await serviceCredential(transport, config.origin, {
input: {
credentialId: config.credentialId,
secret: toCredential(config.credentialSecret),
},
});
if ("refusal" in session) {
throw new Error(`Platform sign-in refused: ${session.refusal.kind}`);
}
if ("replayed" in session) {
throw new Error("Expected a fresh service session");
}
const objects = createObjectsTransportClient(
transport,
config.origin,
session.result.accessToken,
);
const answer = await objects.readObject({
selector: { projectId: config.projectId, ref: "main" },
input: { objectId: config.objectId },
});
if ("refusal" in answer) {
throw new Error(`Object read refused: ${answer.refusal.kind}`);
}
if ("replayed" in answer) {
throw new Error("Expected an object read response");
}
return answer.result;
}

This is a server-side integration example, not a public HTTP handler. Your backend’s own authenticated routes decide who may use its application-level access. The example opens a session per call for clarity; a deployed backend can manage sessions until their reported expiry and exchange the credential again when needed.

Keep the service credential and access token on the backend. Revoking the credential ends the sessions issued from it.

External apps with individual user permissions need delegated sign-in: a person signs in to OpenEngineering, authorizes your app, and the app makes SDK requests with that person’s platform permissions.

Delegated sign-in for external apps is not available yet. The current integration path is a backend service identity. It suits automation and apps where access is intentionally granted to the application itself. It does not provide each user’s individual platform permissions.

A per-user external app therefore depends on the delegated authentication feature. Until that is available, use the OpenEngineering workspace for workflows that require individual platform identity and permissions.

Use the Branches module to create a working branch. Send mutations through the Objects module with that ref, then inspect the diff and submit the proposal through the platform.

Honor project protection and controlled types. An external interface uses the same merge rules as the workspace.

Handle the platform’s outcomes explicitly:

  • A confirmed success updates the interface with the confirmed result.
  • A refusal shows the reason and preserves the person’s draft.
  • An uncertain write outcome is recovered or inspected by its correlation identity before any retry.

Start with a read-only view over one project and a service identity granted only the required access. Confirm that the objects in your app match those in the workspace.

Then add a branch-based editing workflow and test the intended identity’s refusals. Add per-user interaction when delegated authentication is available in your release.

CLI and SDK explains the developer surfaces. Branching and change control explains the engineering workflow your app participates in.