Skip to content

Core concepts and boundaries

Use this page to decide which object to change and which permission controls it. You need no account to read the model. To inspect a real project, you need a platform session and membership; changing content needs project developer or above, and publishing needs project admin or owner.

An instance is a server deployment. It owns platform accounts, activation, server configuration, and the PostgreSQL platform database. Multiple server processes may share that database; creating another project is not creating another server.

A project owns its API assets and collaborator memberships. Its slug is unique within the instance. The public prefix is /p/<slug>; management routes use /projects/<slug>. A project slug is not a bearer credential.

An endpoint tree organizes a project’s routes. New projects have a default tree at the root mount. Directory nodes organize descendants; callable leaves have a method and target. A path segment is not necessarily a script name. The same script can back multiple endpoints with different methods or access rules.

Example:

ObjectExampleMeaning
Instance base URLhttps://api.example.comDeployment to connect to; replace with your own URL
Project slughello-labProject namespace
Script assethelloReusable executable definition
EndpointPOST /helloPublished HTTP contract inside the project
Caller URLhttps://api.example.com/p/hello-lab/helloComplete public request URL

A reverse-proxy mount prefix belongs in the instance base URL too. Do not add /ui or /p/<slug> to a CLI login’s server URL.

PlaneWho it representsHow access is decided
Platform userA person signing in to the console, CLI, or native appPlatform role: owner, admin, developer, operator
Project collaboratorA platform user enrolled in one projectIndependent membership role: owner, admin, developer, operator
Project end user / machine callerA consumer of published project APIsProject authorizer, end-user role/attributes, and authorization model

A platform operator can be a project owner. A platform owner is not automatically a collaborator in every project. Changing a platform user’s role does not change their membership role, and adding an end user does not give console access.

viat user manages platform people; viat project member manages collaborators; viat p-user, viat role, and viat authorizer operate on a project’s caller identities. See Platform users and Create and collaborate for complete procedures.

A script is a named executable asset with a language and version. A workflow coordinates targets and control flow; it is not a folder of endpoints. Testing a draft invokes current definitions and can have real side effects—it is not automatically an offline simulation.

A resource holds a reusable connection or platform-managed capability: a database, HTTP API, storage, mail service, cryptographic key, and so on. Resource configuration separates non-secret plain data from secret fields. Ordinary management reads redact secret values, and brokered operations apply credentials on the platform side.

That is not a universal credential-free script-view guarantee in 1.1.0: some legacy database, cache, messaging and S3 projections still contain credential-bearing fields. Prefer brokered helpers, never return/log resource objects, and read the per-kind resource reference. Intentionally secret-valued secret/config resources have a separate contract from provider authentication credentials.

Do not confuse a PostgreSQL resource that stores your business tables with the PostgreSQL platform database. Likewise, a sqlite resource accesses an approved server-side file; it does not replace the platform database.

Editing an endpoint’s target, authentication, or input contract changes a draft. Public dispatch serves an active published snapshot. Publication captures the route contract and target definition; a test run is not publication. Review viat publish plan before viat publish apply.

Dependency handling is important:

  • A published script endpoint captures ordinary Python/TypeScript uses: imports when its dependency graph has no (live) reference.
  • Workflow-step scripts are an exception in 1.1.0: their main sources are baked at publish, but their uses: dependencies—including nested workflow steps—are resolved live before each workflow run.
  • A directive such as # uses: shared/util (live) resolves live source at each run and uses a fresh worker rather than the warm-pool path.
  • Draft tests and direct schedule targets resolve dependencies live because they do not execute an endpoint’s frozen snapshot.
  • Old snapshots without frozen dependency data also fall back to live resolution. Republish when upgrading an old endpoint to an explicitly frozen dependency graph.

Thus, do not promise that “every import is live” or that “every dependency is rolled back.” The endpoint snapshot and the dependency mode determine the result. Resource credentials and upstream configuration remain live: credential rotation is not an endpoint-code deployment.

Publication is not guaranteed to mean successful runtime preparation under every deployment setting. Defaults build synchronously, but VIAT_PUBLISH_BUILD_BLOCK=0 permits publication despite a failed dependency build; VIAT_PUBLISH_BUILD_ASYNC=1 permits background builds. Review build results before calling a release healthy.

An authorizer answers who the caller is. An endpoint’s nearest declared authorizer list replaces ancestor lists. It is not a union of every parent’s accepted credential type.

An authorization gate (authz_gates, a list of {type, action}) answers whether the identified caller may call the route. Gates accumulate up the tree until override_permissions stops inheritance. They are evaluated against the subject, before a business object exists. Object/row permissions belong to the authorization model and the relevant operation as well.

The built-in anonymous authorizer makes explicitly public routes possible; it is not a substitute for checking permissions on confidential business data. A console login token is not interchangeable with a project end-user token or API key.

An execution record carries a request_id, status, timing, and other metadata. Line logs are the target’s captured output. Endpoint refusals can create execution records without launching a worker. Logs may be persisted through a configured backend and retention policy; do not assume they are permanent backups.

After the login/project-selection procedure in Your first endpoint, inspect without editing:

终端窗口
viat project list
viat endpoint list --json
viat publish plan --json
viat logs query --limit 10 --json

Expected results are accessible projects, editable endpoint records, pending publication work, and an execution page with items and next_before. An empty list is valid for a new project. None of these commands publishes or runs a script.

SymptomCheck
Platform Admin sees no projectsEnroll that account in the project; platform role does not bypass membership
Developer edits successfully but cannot publishAsk a project Owner/Admin, not merely a platform Admin
Valid end-user token gets 403Check the published authorizer list and all inherited gates
Draft response changed, caller response did notPublish; inspect the selected instance/project and active snapshot
Rollback did not revert an upstream credentialCredentials are live resource state, not snapshot contents
sqlite was configured but server still needs PostgreSQLResource databases and platform persistence are separate

For cleanup, unpublish a disposable route before deleting its endpoint and target. Removing a project member does not delete their project content, and clearing a CLI session does not delete the project. Use the task-specific cleanup in Your first endpoint.

Contract source 03751a67: crates/viat-core/src/types/{project,script,resource,snapshot}.rs, crates/viat-db/src/projects.rs, crates/viat-db/src/endpoints.rs, crates/viat-api/src/handlers/snapshots.rs, and crates/viat-cli/src/main.rs.