Concepts

The terms the rest of these docs use, each defined in a few lines and linked to the page that covers it in full. Read the first two sections before getting started . The rest can wait until a page uses them.

Infrastructure

Service

One kind of infrastructure GenoaCMS needs: storage, database, authentication, secrets, deployment, and languages for dynamic components. GenoaCMS defines what each service must do, and leaves how it is done to an adapter.

Adapter

A package that implements one service for one platform, for example @genoacms/adapter-gcp/storage for Cloud Storage or @genoacms/adapter-postgres for PostgreSQL. An adapter is written against the contracts in @genoacms/contracts and depends on nothing else, so you can write your own. See adapters .

Adapter suite

The set of adapters genoa init picks for one platform: GCP or AWS. It is a starting point only, and each service's adapter can be changed afterwards.

Provider

One configured instance of an adapter: which adapter, and its options. Providers are named by a key you choose, and a service may have several, even two of the same adapter. See providers .

Deployment target

A provider of the deployment service. It decides how GenoaCMS is built and where it runs: Cloud Run functions, Lambda or a plain Node server. genoa deploy uses it.

Secret reference

How a config names a credential without holding it. secret('KEY') reads it from the secrets provider and env('VAR') from an environment variable, both when the server starts using the provider, never during the build. inline(value) writes the value into the build, visibly. See secrets .

Your data

Bucket

A storage container that already exists in your storage provider, bound to the provider that serves it. The default bucket also holds GenoaCMS's own data under .genoacms/, so it should be private. See what GenoaCMS stores .

Collection

A description of a table or collection that already exists in your database: its name, its primary key, and a JSON Schema of its documents. GenoaCMS edits the documents in place and migrates nothing. Collections live in genoa.config/collections.ts. See services .

Users and permissions

Subject

The stable identifier your authentication provider issues for a user. Every permission is granted to a subject, never to an email address, because addresses change hands. See identity and sessions .

Permission, grant and role

A permission is one fixed action, such as db:collection:write or pages:publish. A grant applies a permission to a resource: a bucket, a collection, or the whole instance. A role is a named set of grants.

Assignment

The roles a subject holds. A new instance needs at least one assignment in the config, or nobody can administer it. See roles and permissions .

Session

What a sign-in becomes: a short-lived access token and a longer-lived refresh token. GenoaCMS checks the user again with the authentication provider at every refresh, so a disabled user loses access when the access token expires, 15 minutes by default.

Configuration

Tier 1 and Tier 2

GenoaCMS is configured in two places. Tier 1 is genoa.config, in your repository, changed by a deployment. It is the only place adapters and credentials can be set. Tier 2 is a set of signed documents in the default bucket, changed by administrators at runtime. Tier 2 may add to what Tier 1 declares, never override it. See configuration .

Declaration and seed

Tier 1 holds two kinds of setting. A declaration (the authorization stanza: roles and assignments) is re-read on every check, so deleting a line takes back what it granted. A seed (the security stanza: token lifetimes, key rotation, component limits) only sets the values a new instance starts from. Afterwards they are changed in the CMS.

Pages and components

These matter only if you compose pages in GenoaCMS. Editing a database or a bucket needs none of them.

Component

A reusable building block of a page, with named, typed attributes that editors fill in. A component is one of two kinds:

  • Prebuilt. Its code lives in your application, in your application's own language and framework. GenoaCMS holds only a description of its attributes, and your application supplies the code by name when it renders.
  • Dynamic. Its code is written in the CMS, after your application has shipped. A language adapter compiles it, and the compiled code is published with the page.

Language adapter

The piece that checks and compiles dynamic components written in one language. @genoacms/language-adapter-ts handles TypeScript. Prebuilt components need no language adapter. See adding a language .

Page

A tree of components with their attributes filled in. Editors compose it in the CMS, and publishing it makes it readable by your applications.

Publication

One released version of a component, written once and never changed. A published page pins the exact publication of every component it uses, so a later change to a component does not alter a page that was already published.

Consumer

Your own application, the one that renders published pages. It is not a plugin and does not run inside GenoaCMS. It reads the published files from storage and renders them with a client SDK.

Client SDK

The library a consumer uses to read, verify and render pages. @genoacms/sdk is the JavaScript one. See rendering pages in your app .

Component limits (fuel)

The ceilings a dynamic component runs under, set by security: fuel is the number of loop iterations and recursive branches per render, beside the maximum call depth and memory. They are compiled into the component and signed with it, so a consumer can lower them and never raise them.

Data bridge

The only way a dynamic component can reach the network. It is built into the signed component and refuses every origin not listed in security.fetchOrigins, which by default lists none.

Passthrough

The object a consumer hands to every dynamic component on a page: a date formatter, an icon set, whatever your application chooses to grant. Nothing checks what you put in it, so it is your security decision. Prebuilt components never receive it.

Signing

Signed document

A document stored with a signature over its content. Published pages, component publications and GenoaCMS's own Tier-2 documents are signed, so a reader can tell them from anything else written to the same bucket.

Root trust anchor and root public key

The instance's top-level key pair. Its only job is to sign the key registry. Consumers embed the root public key when they are built, which is why replacing the root means rebuilding every consumer. Replacing it is genoa rotate-root. See signing keys .

Key registry

The signed list of subordinate keys the instance currently uses, and of those it no longer trusts. A consumer fetches it and checks it against the root public key.

Subordinate key

A key that signs everything except the registry. Subordinate keys rotate on their own, every 90 days by default, and no consumer notices. A leaked one is revoked, and everything it signed must be signed again.