Skeleton Entities
Overview
In Witboost, a Skeleton Entity is an entity whose definition is provided by a Nunjucks-templated file. This file is stored within the entity's repository alongside a set of parameters required to render the final YAML definition, which is then supplied to the Witboost Catalog.
Entities such as Systems and Components can (and should) be defined using these skeleton (templated) definitions for better flexibility and maintainability.
Introduced in Witboost 2.3, Skeleton Entities provide a more dynamic and user-friendly approach to define systems and components. They seamlessly integrate with tools like the Editor Wizard and the Reverse Provisioning Wizard, allowing for easier entity management.
Why Skeleton Entities?
Before Skeleton Entities, systems and components were typically defined using static YAML files stored in a Git repository. For example, a system could be represented by a catalog-info.yaml
file like this:
kind: System
metadata:
name: finance.cashflow.2
description: This represents all the operating cashflows generating incoming or outgoing liquidity
spec:
type: dataproduct
lifecycle: experimental
owner: group:witboost
domain: domain:finance
mesh:
name: Cash Flow
version: 2.0.0
fullyQualifiedName: Liquidity Cash Flows
maturity: Strategic
As mentioned in the overview, an entity provider would read this file and generate or update the corresponding entity in the Catalog.
This approach was the standard way to define systems and components before Witboost 2.3. It remains useful for defining other types of entities such as domains, templates, types, and resources — which are often managed by the Platform Team.
However, systems and components are frequently created and modified by non-technical users who may lack the expertise to edit YAML files directly. To address this, tools like Creation Templates, Editor Wizard, and Reverse Provisioning Wizard offer a more intuitive, graphical way to create and modify entity definitions — without requiring direct interaction with YAML files or repositories. Skeleton Entities allow for improved separation of concerns between structure and data, safer editing through parameter files, and better integration with visual tools.
The benefits of Skeleton Entities
Skeleton Entities were introduced to:
- Provide better integration with Witboost's graphical tools.
- Simplify the workflow for non-technical users.
- Offer greater flexibility and power for technical users who prefer working directly in repositories.
With Skeleton Entities, the repository structure for the entity in our example would now look like this:
catalog-info.yaml
(Template / Skeleton)
%SKELETON
kind: System
metadata:
name: finance.cashflow.2
description: ${{ parameters.description }}
spec:
type: dataproduct
lifecycle: ${{ parameters.lifecycle }}
owner: group:witboost
domain: domain:finance
mesh:
name: ${{ parameters.displayName }}$
version: ${{ parameters.version.major }}.${{ parameters.version.minor }}.${{ parameters.version.patch }}$
fullyQualifiedName: Liquidity ${{ parameters.displayName }}s
maturity: Strategic
parameters.yaml
parameters:
description: This represents all the operating cashflows generating incoming or outgoing liquidity
lifecycle: experimental
displayName: Cash Flow
maturity: Strategic
version:
major: 2
minor: 0
patch: 0
How to define a Skeleton Entity
Defining a skeleton entity is straightforward. Just follow these steps:
- Add the
%SKELETON
directive at the top of thecatalog-info.yaml
file: it's important to keep this directive on the very first line of the file. - Define a
parameters.yaml
file that includes all the parameters required by the skeleton. - Parameterize any values that should be dynamic by using
Nunjucks
syntax (${{ parameters.xxx }}
). - Leave static values as they are — not everything needs to be parameterized.
With these steps, the entity's parameters become editable through the Editor Wizard and the Reverse Provisioning Wizard. These tools will never directly modify the skeleton catalog-info.yaml file itself, as they used to with static definitions. Instead, they operate on the parameters.yaml file, ensuring a cleaner and more maintainable workflow.
Learn more about setting up a Creation Template to instantiate a Skeleton Entity in Creating Use Case Templates.
Skeleton vs Legacy Entities
Since Skeleton Entities became the standard for defining systems and components starting with Witboost 2.3, this documentation uses the term Legacy Entities to refer to entities created without the %SKELETON
directive — typically before Witboost 2.3 — where all metadata is stored directly in a fully rendered catalog-info.yaml
file.
Best Practices and Tips
Escaping
When writing a catalog-info.yaml
file for a Skeleton Entity, you're not writing a static YAML file — you're writing a Nunjucks template that gets dynamically rendered into a YAML structure using values from parameters.yaml
.
To make this work correctly, especially across different data types, you often need to use Nunjucks filters and control structures. For example:
-
| dump
ensures values are correctly serialized into YAML, adding quotes around strings and properly escaping characters like:
or#
. This is critical to avoid syntax errors when rendering.name: ${{ parameters.name | dump }}
-
Loops (
{% for %}
) and conditionals ({% if %}
) are useful when injecting arrays or optional values:tags: {% if parameters.tags | length > 0 %}{% for tag in parameters.tags %}
- tagFQN: ${{ tag }}
source: Tag
{% endfor %}{% else %}[]{% endif %} -
Filters like
| length
,| lower
,| default
, etc., help with formatting and fallback behavior in the template logic.
Without these expressions, the rendered catalog-info.yaml
may:
- Break due to invalid YAML syntax
- Include incorrect values
- Miss optional fields or inject empty structures improperly
Using Nunjucks expressions correctly is what makes Skeleton Entities safe, reusable, and dynamic — especially when paired with form-driven tools like the Editor Wizard or Reverse Provisioning Wizard.
Skeleton Rendering Preview
If you are developing or editing a Skeleton Entity, the Skeleton Rendering Preview tool can help you visualize how your catalog-info.yaml
will be rendered using the values from parameters.yaml
.
You can use it to:
- Validate your Nunjucks templating
- Quickly test changes without committing to Git
- Spot missing or misnamed parameters
This tool is still in preview and will be better integrated in future releases.
In the meantime, you can try it directly at:
<witboost-url>/platform-settings/builder-tools/skeleton-rendering-preview
Migration
This section provides guidelines for migrating Legacy Entities (systems and components) and related tools to the Skeleton Entity model, which became the standard starting from Witboost 2.3.
From Legacy to Skeleton Entities
Migrating a Legacy Entity to a Skeleton Entity involves:
-
Enabling Skeleton mode:
Add the%SKELETON
directive at the top of the entity'scatalog-info.yaml
file. This activates dynamic rendering and marks the file as Nunjucks template. -
Removing hardcoded values and creating a
parameters.yaml
file:
Replace hardcoded values incatalog-info.yaml
with Nunjucks placeholders that reference parameters — e.g.,${{ parameters.email }}
— and move their actual values to a newparameters.yaml
file under theparameters:
block.
Learn more in the Skeleton Parameters section.
If your catalog-info.yaml
contains a witboost.parameters
section, that's a great starting point.
kind: Component
# ...
spec:
description: A component description (experimental)
tags:
- tagFQN: t1
source: Tag
- tagFQN: t2
source: Tag
# ...
witboost:
parameters:
lifecycle: experimental
description: A component description
tags:
- t1
- t2
- Copy its content under
parameters:
in the newparameters.yaml
file. - Remove the
witboost.parameters
block fromcatalog-info.yaml
.
parameters.yaml
parameters:
lifecycle: experimental
description: A component description
tags:
- t1
- t2
The witboost.parameters
section was originally generated by the creation template during instantiation.
To make migration easier, inspect the creation template's repository and open skeleton/catalog-info.yaml
.
This is the original template (with Nunjucks syntax) from which your entity's catalog-info was rendered.
skeleton/catalog-info.yaml
kind: Component
# ...
spec:
description: ${{ values.description | dump }}
tags: {% if values.tags | length > 0 %}{% for i in values.tags %}
- tagFQN: ${{ i }}
source: Tag{% endfor %}{% else %}[]{% endif %}
# ...
You'll likely see references to values.<key>
— these come from template.yaml > spec.steps[template].values
.
template.yaml
kind: Template
# ...
spec:
parameters:
- title: Metadata
properties:
lifecycle: # parameters.lifecycle
title: Lifecycle
type: string
description: # parameters.description
title: Description
type: string
tags: # parameters.tags
title: Tags
type: array
default: []
items:
type: string
# ...
steps:
- id: template
name: Fetch Skeleton + Template
action: fetch:template
input:
url: ./skeleton
targetPath: .
values:
description: '${{ parameters.description }} (${{ parameters.lifecycle }})' # values.description
tags: ${{ parameters.tags }} # values.tags
# ...
You now have two options:
-
Replace each value with its expression when copying the content of
skeleton/catalog-info.yaml
in your entity'scatalog-info.yaml
, so that only parameters are left:%SKELETON
kind: Component
# ...
spec:
description: "${{ parameters.description | dump }} (${{ parameters.lifecycle | dump }})"
tags: {% if parameters.tags | length > 0 %}{% for i in parameters.tags %}
- tagFQN: ${{ i }}
source: Tag{% endfor %}{% else %}[]{% endif %}
# ... -
Or, copy the value definitions into the
values:
section of yourparameters.yaml
:catalog-info.yaml
%SKELETON
kind: Component
# ...
spec:
description: ${{ values.description | dump }}
tags: {% if values.tags | length > 0 %}{% for i in values.tags %}
- tagFQN: ${{ i }}
source: Tag{% endfor %}{% else %}[]{% endif %}
# ...parameters.yaml
parameters:
lifecycle: experimental
description: A component description
tags:
- t1
- t2
values:
description: '${{ parameters.description }} (${{ parameters.lifecycle }})'
tags: ${{ parameters.tags }}
Creation Templates
To make a Creation template generate a Skeleton Entity, simply add the %SKELETON
directive at the very top of the catalog-info.yaml
file located in the template's skeleton
folder.
This instructs Witboost to create the entity by:
- Copying the
catalog-info.yaml
file as-is, preserving its Nunjucks expressions. - Generate a
parameters.yaml
file containing:- User-provided inputs defined under
spec.parameters
intemplate.yaml
. - Values from
spec.steps[template].values
.
- User-provided inputs defined under
Together, these files make the entity fully compatible with the Skeleton Entity model.
Learn more in Creating Use Case Templates.
Edit Templates
During the migration from Legacy Entities to Skeleton Entities, it's important to also understand how Edit Templates are affected — especially since v2 edit templates have been introduced and may behave differently from the v1
templates.
As your catalog evolves, it's likely that you'll end up with a mix of Legacy and Skeleton Entities in the same installation. This is expected and supported — but it's important to use the right type of Edit Template for each case.
For complete details about v1 and v2 Edit Templates, how they work and their compatibility settings refer to the Edit Templates section.
Key Differences: v1
vs v2
Edit Templates
Feature | v1 Edit Template | v2 Edit Template |
---|---|---|
Default entity support | Legacy Entities | Skeleton Entities |
Skeleton Entities support | ✅ Supported by default (with a UI warning) | ✅ Supported by default |
Legacy Entities support | ✅ Supported by default | ❌ Not supported unless explicitly enabled |
Steps (spec.steps ) in edit-template.yaml | Required (ignored for Skeleton Entities) | Optional (but required for Legacy compatibility) |
Needs edit-skeleton/ folder | ✅ Always required (ignored for Skeletons) | ❌ Not required (unless Legacy support is enabled) |
Where it writes | catalog-info.yaml (Legacy)parameters.yaml (Skeleton) | catalog-info.yaml (Legacy)parameters.yaml (Skeleton) |
Best used for | Legacy entities | Skeleton entities |
How v1
Templates Work
- Designed for Legacy Entities, where metadata is edited directly in
catalog-info.yaml
via anedit-skeleton
folder. - When used on a Skeleton Entity, they:
- By default support it — no config needed.
- Ignore the
edit-skeleton
folder. - Edit the
parameters.yaml
file instead. - Show a "compatibility warning" in the Editor Wizard (informing the user they're using a
v1
template on a Skeleton Entity).
If you want to avoid that warning, consider switching to a v2
template or disable it through the compatibility options.
How v2
Templates Work
- Designed for Skeleton Entities — editing happens only in the
parameters.yaml
file. spec.steps
inedit-template.yaml
is not needed, and there's no need for anedit-skeleton
folder.
If you want to also support Legacy Entities with a v2
template:
spec:
compatibility:
legacyEntities:
executionPolicy: ALLOWED
(edit-template.yaml
)
But in that case:
- You must provide both
spec.steps
and anedit-skeleton/
folder (used only for Legacy Entities). - When editing a Skeleton Entity, those sections are still ignored — only
parameters.yaml
is used.
Reverse Provisioning Templates and Tech Adapters
When migrating from Legacy to Skeleton Entities, Reverse Provisioning Templates and Tech Adapters may need adjustments.
What changes with Skeleton Entities?
- Skeleton Entities store editable data in
parameters.yaml
instead of directly incatalog-info.yaml
. - Reverse Provisioning still works, but the way updates are applied is different.
If you're using a v1
(legacy) Reverse Provisioning Template
- ✅ Legacy Entities: work as usual — updates go directly to
catalog-info.yaml
.