Skip to content
Talk to our solutions team

Product Repository Layout

A product is one repository. Each top-level folder belongs to a block; a block only ever reads its own folder.

myproduct/
.kisai/ # product metadata
config.yaml # product-level config (name, …)
data/
datastores/
datastores.yaml # entity definitions → data.svc
plugins/ # data plugins (code/js, code/go)
access.yaml
iam/
realms.yaml # who authenticates, with which providers
providers.yaml # auth method declarations
token.yaml # token expiry + claims
federation.yaml
access.yaml # authorization predicates
config.yaml
extend/ # entity overlays
plugins/
content/ # content.svc apps + stores
workflow/
workflows/ # workflow definitions
automate/ # distributed automation flows
notification/ # notify.svc templates + channels
pages/ # UI pages
forms/ # UI forms
i18n/ # translations
themes/ # UI themes
dependencies/
bffs/ # backend-for-frontend definitions
jobs/ # job definitions
search/ # search configuration
integrations/ # third-party integrations
ai/
bots/ # bot definitions
tests/
functional/
load/

Only include the folders your product uses — a minimal product is just:

myapp/
config.yaml # name: myapp
pages/home.yaml
data/customer.yaml
FolderConsuming block
data/datastores/Data API (data.svc) — see Entities
iam/IAM (iam.svc) — see IAM Configuration
pages/, forms/, i18n/, themes/UI runtime
workflow/workflows/workflow.svc
content/content.svc
bffs/bff.svc
jobs/jobs.svc
notification/notify.svc
ai/bots/ai-bot.svc

Blocks additionally ship embedded base definitions inside their own binaries (base entities, pointcuts, APIs). The product folder layers on top of that base; tenant-level extensions layer on top of the product (delivered as data, not files — see the consuming block’s docs).

Meta serves any branch or tag of the repository:

  • Every read accepts ?version=<name>&versionType=branch|tag.
  • Per-repo allowedversions allow-lists what may be requested — exact names or regex patterns.
  • pinversion pins a repo to a fixed ref regardless of what callers ask for.
  • Version-pinned reads are served from an isolated in-memory checkout — they never disturb the live worktree.

A repository can declare reusable components (component.yaml files) with name, category, icon, tags, and license. Meta indexes them at load time and serves them through the component endpoints — this is how the marketplace and the forge authoring UI discover installable pieces.