Release, URLs, and Access Control

Once an application is written, three things decide whether it can go live safely: how it's released, where users come in, and who can access what.


The release flow

Submit a version from the Builder's Publish tab.

  1. Record a version number and a changelog
  2. Behavior depends on permission:
    • With builder.publishpublishes directly
    • Without → creates a publish request for review

Requests can be approved, rejected (with a reason), or cancelled by the requester. This makes "who can push code to production" a controllable responsibility rather than something every developer holds.

What release freezes

Publishing does more than ship code — it freezes an authorization snapshot:

  • Reference declarations (which tables, which columns, which operations)
  • Scope declarations

Which means changing reference settings during development does not affect the live version. A new release is required. That is deliberate: it prevents anyone from quietly widening permissions in development and having it take effect against production data immediately.

Blocking pre-release checks

The platform detects configuration gaps at release time and blocks:

CheckWhy it blocks
External service not authorizedCode calls an external service whose domain hasn't been added to the allowlist
Fewer actions than beforeThis version dropped actions — possibly by accident; explicit confirmation required

Both are classic "blows up in front of users after go-live" failures, hence catching them before release.

Note: the pre-release check only verifies that a service is authorized (domain allowlist). The platform neither stores nor validates external service credentials — they live in App Secrets, and each action reads them out and assembles its own Authorization header. If an external API returns 401 after go-live, the application's own credentials are at fault; that is outside what the pre-release check can catch.


URLs and identifiers

Every application carries two identifiers with different purposes:

Random identifierReadable name
Chosen byThe systemYou
MutableNoYes, before release
Used forPermanently stable internal identityThe public URL

Readable name rules:

  • 4–63 characters, lowercase alphanumerics and hyphens, not starting or ending with a hyphen
  • Case-insensitive (MyApp normalizes to myapp)
  • Reserved words are blocked (admin, api, www, login, and others)
  • Globally unique across organizations; collisions are rejected

If your organization has chosen a workspace name, the public subdomain carries an organization prefix (of the form {workspace}-{app}). Always use the URL the system returns rather than deriving it from the organization name — existing applications are never renamed, so old and new conventions can coexist.

After release the URL is the user's entry point. Administrators copy it from the Dashboard and distribute it.


Lifecycle management

OperationEffect
RepublishShips a new version; users get it on next load
SuspendHolders of the URL can no longer sign in; settings and code are retained
DeleteRemoves the application and its URL. Data Center data is not deleted

Deleting an app without deleting data is deliberate — data belongs to the organization, not to an application. It's the same principle that makes custom tables organization-level.


Four layers of access control

What an application can touch is decided by four stacked layers. All four must pass.

Layer 1: who can see the application

Internal apps can be restricted to specific roles — only members holding those roles see it in the application list and can sign in.

To a user who lacks access, the application is indistinguishable from nonexistent: it isn't listed, opening the URL directly is refused, and the response matches "no such application" so its existence isn't leaked.

Layer 2: reference declarations (data scope)

An application must declare which ERP tables, columns, and operations it needs:

{
  "table_name": "customers",
  "columns": ["id", "name", "email", "custom_data"],
  "permissions": ["read", "create", "update"]
}

Undeclared tables are unreachable. Declared tables with undeclared columns return nothing on read and silently drop them on write.

Permission values:

ValueAllows
readQuery
createInsert
updateUpdate
deleteDelete

Practical advice: do not grant delete to ordinary operational applications. Model voiding as a status change and leave real deletion to administrators in a controlled environment. That preserves the audit trail and prevents accidents.

Core system tables (authentication, tenant management, permission settings, audit records) can never be referenced.

Layer 3: scope approval (capability scope)

References govern which data. Scope governs which capabilities.

An application declares the scopes it needs (a code scan backfills them at release), and an administrator approves them in the Builder's Scope tab.

High-risk scopes require an extra gate: expanding into db.write, erp.*, secret.read, http, knowledge.read, and similar requires the owner to enter their password on the spot. This defends against authorization being widened quietly — even a compromised administrator account cannot escalate without the password.

External and Self-Built applications require explicit administrator approval and do not use the simplified internal flow.

Every scope grant change is recorded — who, when, and which scope — and is queryable in the audit log.

Layer 4: user permissions (RBAC)

Even when the application is authorized, actual operations remain bound by the user's roles. Internal apps can read the triggering user's permission tags and decide what to show and allow.

Final server-side adjudication uses the triggering user's identity — a hidden front-end button is not a boundary.


The three access modes compared

InternalExternalSelf-Built
Use caseInternal toolingCustomer / supplier applicationsThird-party system integration
AuthenticationOrganization member accountsThe app's own user systemAPI key
Code locationAI GO BuilderAI GO BuilderDeployed by the third party
Data accessInternal ProxyExternal ProxyOpen Proxy
References need publishingNo (immediate)No (immediate)Yes (published snapshot)

Self-Built serves the case of "we don't want to write code inside AI GO, we just want the data". It has no Builder and no front end — only an API key and data access. See Chapter 11.


Auditing

All of the following are recorded:

  • Application creation, release, suspension, deletion
  • Reference declaration changes
  • Scope grant changes (including who performed them)
  • Every SDK call

Audit records are queryable under System & Operations → Audit Log with the system.audit_log permission.