Backstage Plugin Installation & Configuration¶
Beta
The SkillMeat Backstage plugins (@skillmeat/backstage-plugin and
@skillmeat/backstage-plugin-scaffolder-backend) are currently in early
release (v0.1.0). APIs and configuration keys are stable for the documented
scenarios below, but minor changes may occur before a 1.0 release. Pin plugin
versions in production and review the changelog when upgrading.
Walkthrough available
See the Backstage Platform Engineer Walkthrough for a complete Backstage integration journey.
This guide walks platform engineers through installing both SkillMeat Backstage plugins into an existing Backstage app and verifying that the integration is working. By the end you will have:
- The frontend plugin (
@skillmeat/backstage-plugin) serving entity cards, drift status views, and optional telemetry dashboards on your entity pages. - The scaffolder backend plugin
(
@skillmeat/backstage-plugin-scaffolder-backend) registering three custom scaffolder actions so your templates can inject AI context packs and register deployments with SkillMeat.
Prerequisites¶
Before starting, confirm that the following are in place.
Backstage Version¶
The plugins target Backstage v1.27.x (RHDH 1.3+ is also supported). Run the following from your Backstage root to confirm the installed Backstage CLI version:
Check that the version satisfies ^0.30.0. The frontend plugin lists its
Backstage peer dependencies explicitly:
| Dependency | Required Version |
|---|---|
@backstage/core-plugin-api |
^1.10.0 |
@backstage/core-components |
^0.16.0 |
@backstage/plugin-catalog-react |
^1.14.0 |
@backstage/catalog-model |
^1.7.0 |
The scaffolder backend plugin requires:
| Dependency | Required Version |
|---|---|
@backstage/backend-plugin-api |
^1.0.0 |
@backstage/plugin-scaffolder-node |
^0.6.0 |
If your Backstage version is older, upgrade it first using the standard Backstage upgrade guide.
Node.js Version¶
Both plugins require Node.js v18.x or later. Check your runtime:
SkillMeat API¶
Your SkillMeat API server must be reachable from the host running the Backstage backend process:
- API URL known: you need the base URL of the SkillMeat API
(e.g.,
https://sam.internalorhttp://localhost:8080for local dev). - SkillMeat API v1.0.0+: verify with a health check:
A 200 OK response with {"status": "ok"} confirms the API is reachable.
Admin Access to Backstage Repo¶
You need the ability to:
- Modify
packages/app/src/App.tsx(frontend route registration) - Modify
packages/app/src/components/Root/Root.tsx(sidebar) - Modify
packages/backend/src/index.ts(new backend system) orpackages/backend/src/plugins/scaffolder.ts(legacy backend) - Add keys to
app-config.yaml - Run
yarnto install packages
SkillMeat API Token¶
The scaffolder backend plugin makes server-to-server requests to the SkillMeat API. You need a service account token generated in SkillMeat before configuring the plugin. See Authentication Setup for how to create API tokens.
Tip
For local development you may omit the token if your SkillMeat instance is running in zero-auth mode. For production always use a service account token.
Step 1: Install the Frontend Plugin¶
The frontend plugin provides entity page tabs, drift status cards, and optional telemetry dashboards.
1.1 — Add the Package¶
From the Backstage monorepo root, install into the packages/app workspace:
Confirm the package appears in packages/app/package.json.
1.2 — Register Routes in App.tsx¶
Open packages/app/src/App.tsx and add the SkillMeat imports and routes. The
demo app at demo/backstage-app/packages/app/src/App.tsx is the canonical
reference:
// packages/app/src/App.tsx
import {
PlatformHealthDashboardPage,
GlobalROIDashboardPage,
} from '@skillmeat/backstage-plugin';
// ... existing imports ...
Inside the <FlatRoutes> block, add the two standalone dashboard routes:
const routes = (
<FlatRoutes>
{/* ... existing routes ... */}
{/* SkillMeat: Platform Health dashboard (KPI header, catalog health, drift alerts) */}
<Route path="/platform-health" element={<PlatformHealthDashboardPage />} />
{/* SkillMeat: Global AI ROI dashboard (enterprise-wide workflow effectiveness) */}
<Route path="/skillmeat-roi" element={<GlobalROIDashboardPage />} />
</FlatRoutes>
);
The entity-page tabs (EntitySkillMeatContent, EntitySkillMeatIntelligenceContent)
are registered per entity kind in your entity page configuration — covered in
Catalog Integration.
Note
The plugin also exports skillmeatPlugin which self-registers its API
factories when any of its components are imported. You do not need to
add it manually to createApp({ plugins: [...] }) — Backstage's tree-shaking
mechanism handles this automatically when you use the route components.
1.3 — Add Sidebar Entries¶
Open packages/app/src/components/Root/Root.tsx and add sidebar items for the
two dashboard pages. Import a suitable Material UI icon:
// packages/app/src/components/Root/Root.tsx
import DashboardIcon from '@material-ui/icons/Dashboard';
import AssessmentIcon from '@material-ui/icons/Assessment';
// Inside the <SidebarGroup label="Menu" ...> block:
<SidebarItem
icon={AssessmentIcon}
to="platform-health"
text="Platform Health"
/>
<SidebarItem
icon={DashboardIcon}
to="skillmeat-roi"
text="AI ROI Dashboard"
/>
Place these items in the SidebarScrollWrapper or in the main menu group,
depending on your sidebar structure. The exact position is at your discretion.
Step 2: Install the Scaffolder Backend Plugin¶
The scaffolder backend plugin registers three custom actions for use in Backstage scaffolder templates:
| Action | Purpose |
|---|---|
skillmeat:bundle:validate |
Validates a bundle exists in SkillMeat before scaffold steps run |
skillmeat:context:inject |
Fetches and injects a rendered Golden Context Pack into the workspace |
skillmeat:deployment:register |
Links a newly created repository to a SkillMeat deployment record |
Note
The scaffolder backend plugin also exports skillmeat:attest and
skillmeat:bom:generate actions. These are available for use in templates
but are not shown in the minimal install below.
2.1 — Add the Package¶
From the Backstage monorepo root, install into the packages/backend workspace:
2.2 — Register with the Backend¶
New backend system (recommended) — edit packages/backend/src/index.ts and
add skillmeatScaffolderModule after the scaffolder plugin registration:
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { skillmeatScaffolderModule } from '@skillmeat/backstage-plugin-scaffolder-backend';
const backend = createBackend();
// ... other plugins ...
backend.add(import('@backstage/plugin-scaffolder-backend'));
backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
// SkillMeat scaffolder actions
backend.add(skillmeatScaffolderModule);
await backend.start();
The skillmeatScaffolderModule registers all SkillMeat actions with the
scaffolder's scaffolderActionsExtensionPoint automatically.
Legacy backend system — if your Backstage app still uses the legacy backend,
import the action factory functions directly in
packages/backend/src/plugins/scaffolder.ts:
// packages/backend/src/plugins/scaffolder.ts (legacy backend only)
import {
createSkillMeatValidateBundleAction,
createSkillMeatInjectAction,
createSkillMeatRegisterAction,
} from '@skillmeat/backstage-plugin-scaffolder-backend';
// Inside createRouter({ ..., actions }):
const actions = [
...builtinActions,
createSkillMeatValidateBundleAction(),
createSkillMeatInjectAction(),
createSkillMeatRegisterAction(),
];
Tip
If you are unsure which backend system your app uses, check whether
packages/backend/src/index.ts contains createBackend() from
@backstage/backend-defaults (new system) or createRouter calls in
separate plugins/ files (legacy system).
Step 3: Configure app-config.yaml¶
Both plugins read from the skillmeat key in app-config.yaml. Add the
following block, substituting your real values:
# app-config.yaml
skillmeat:
# Required: base URL of your SkillMeat API instance.
# No trailing slash. Used by both the frontend and scaffolder backend plugins.
baseUrl: https://sam.internal
# Recommended for production: service account token for machine-to-machine auth.
# Set via environment variable — never commit the raw token value.
serviceAccountToken: ${SAM_SERVICE_ACCOUNT_TOKEN}
# Legacy token config (backward compatible). If serviceAccountToken is set,
# it takes precedence over this value.
# token: ${SAM_API_TOKEN}
Optional: Telemetry Proxy Configuration¶
The frontend plugin's telemetry widgets (workflow effectiveness cards, agentic metrics, global ROI dashboard) route API calls through the Backstage proxy. If you plan to enable telemetry dashboards, add a proxy entry:
# app-config.yaml
proxy:
'/telemetry':
target: 'https://sam.internal'
changeOrigin: true
allowedMethods: ['GET']
allowedHeaders: ['Content-Type', 'Authorization']
# If your SAM backend enforces bearer auth, inject the token here:
headers:
authorization: 'Bearer ${TELEMETRY_API_TOKEN}'
The telemetry widgets construct requests to
/telemetry/integrations/idp/telemetry/* relative to the Backstage backend.
Optional: Enable Telemetry Feature Flag¶
All telemetry widgets (the analytics dashboard, workflow effectiveness cards,
and agentic metrics tabs) are gated behind a Backstage feature flag called
backstage_analytics_widgets. Without this flag enabled the plugin loads
normally but does not render any telemetry components — no empty
placeholders are shown.
To enable telemetry widgets:
Note
The three core entity cards (SkillMeatContextCard, SkillMeatBomCard,
SkillMeatDriftCard) and EntitySkillMeatContent are not gated by
this feature flag and are always available once the plugin is installed.
Authentication Priority for Scaffolder Actions¶
The scaffolder backend resolves auth credentials in the following order. Higher-priority sources override lower ones, and per-step template inputs override all global config:
- Per-step
tokeninput in the template YAML — highest priority skillmeat.serviceAccountToken— recommended for production (service-to-service)skillmeat.token— legacy fallback- Unauthenticated — if all token config is omitted (only appropriate for zero-auth SkillMeat deployments)
Step 4: Configure Authentication¶
Generating a Service Account Token¶
The scaffolder backend requires a token with sufficient scope to call the SkillMeat scaffold, validate, and deployment registration endpoints. To generate a token:
- Open the SkillMeat web UI and navigate to Settings → Authentication.
- Create or select a service account.
- Generate an API token with at minimum
artifacts:read,deployments:write, andintegrations:idpscopes.
For detailed token management steps, see Authentication Setup.
Injecting the Token as an Environment Variable¶
Never commit token values directly to app-config.yaml. Inject them at
runtime using environment variables and the ${VAR_NAME} substitution syntax
that Backstage supports natively.
For local development, create app-config.local.yaml (this file is
git-ignored in the default Backstage setup):
# app-config.local.yaml — not committed to source control
skillmeat:
baseUrl: http://localhost:8080
token: your-dev-token-here
For production and CI/CD, set the environment variable before starting Backstage:
Or in your container/Kubernetes deployment, inject SAM_SERVICE_ACCOUNT_TOKEN
as a secret environment variable and reference it with ${SAM_SERVICE_ACCOUNT_TOKEN}
in app-config.yaml as shown above.
Warning
If you deploy Backstage as a Docker container, ensure the environment
variable is available to the backend process, not just the build step.
Backstage evaluates ${...} substitutions at server startup, not at build
time.
Step 5: Start Backstage and Verify¶
5.1 — Start the Development Server¶
From your Backstage root:
This starts both the backend (port 7007) and the frontend (port 3000) simultaneously.
For production:
5.2 — Verify the Frontend Plugin Loaded¶
- Open your browser to
http://localhost:3000(or your Backstage URL). - Check the sidebar for the Platform Health and AI ROI Dashboard items you added.
- Navigate to Platform Health (
/platform-health). The page should render the platform health dashboard. If telemetry is enabled you will also see the KPI header row with aggregate metrics. - Navigate to
/skillmeat-roito confirm the Global ROI dashboard renders.
For entity-level cards, navigate to any Backstage catalog entity and follow the steps in Catalog Integration to add the SkillMeat tab to your entity page.
5.3 — Verify the Scaffolder Backend Plugin Loaded¶
Check the backend process logs for a line confirming SkillMeat actions were registered:
[skillmeat-scaffolder-module] Registered actions: skillmeat:context:inject,
skillmeat:deployment:register, skillmeat:attest, skillmeat:bom:generate
The exact log format depends on your Backstage version. To confirm actions are available via the API:
curl -s http://localhost:7007/api/scaffolder/v2/actions \
| jq '[.[] | select(.id | startswith("skillmeat:"))]'
A successful response lists all registered SkillMeat actions:
[
{ "id": "skillmeat:bundle:validate", ... },
{ "id": "skillmeat:context:inject", ... },
{ "id": "skillmeat:deployment:register", ... },
{ "id": "skillmeat:attest", ... },
{ "id": "skillmeat:bom:generate", ... }
]
5.4 — Verify SkillMeat API Connectivity¶
The frontend plugin calls skillmeat.baseUrl directly from the browser using
the Backstage fetchApi. Confirm the URL is reachable from the browser host
(not only from the backend):
Expected response includes {"version": "1.x.x", ...}.
Health Check and Troubleshooting¶
Plugin Not Appearing in Sidebar¶
Symptom: The Platform Health or AI ROI Dashboard items are missing from the sidebar.
Check:
- Confirm
@skillmeat/backstage-pluginis listed inpackages/app/package.json— if missing, re-run theyarn addstep. - Confirm the
<SidebarItem>entries were added toRoot.tsxand that the file was saved. - Check the browser console for JavaScript import errors.
CORS Errors¶
Symptom: Browser console shows CORS policy errors when the frontend plugin
calls the SkillMeat API.
Resolution: The SkillMeat API must include Access-Control-Allow-Origin
headers that permit requests from the Backstage frontend origin
(e.g., http://localhost:3000).
For the telemetry endpoints, route calls through the Backstage backend proxy
instead of calling the API directly. Add the proxy configuration described in
Step 3 and ensure changeOrigin: true is set.
For the core plugin (context cards, BOM, drift), the SkillMeatClient uses
the Backstage fetchApi which inherits the frontend origin. Ensure your
SkillMeat API is configured to allow CORS from your Backstage origin.
Authentication Token Missing¶
Symptom: Scaffolder templates using skillmeat:context:inject or
skillmeat:deployment:register fail with a 401 Unauthorized response from
the SkillMeat API.
Check:
- Confirm
SAM_SERVICE_ACCOUNT_TOKEN(orSAM_API_TOKEN) is exported in the environment where the Backstage backend process runs. - Verify the variable name in your environment matches the
${VAR_NAME}reference inapp-config.yaml— variable names are case-sensitive. - Restart the Backstage backend process after setting the environment variable
— Backstage reads
app-config.yamlsubstitutions at startup.
Scaffolder Actions Not Found¶
Symptom: Scaffolder templates referencing skillmeat:* actions fail with
"Action not found".
Check:
- Confirm
@skillmeat/backstage-plugin-scaffolder-backendis listed inpackages/backend/package.json. - For the new backend system, verify
skillmeatScaffolderModuleis added withbackend.add(skillmeatScaffolderModule)inpackages/backend/src/index.ts. - For the legacy backend, verify the action factories are imported and
included in the
actionsarray passed tocreateRouter. - Run the
curlverification command from Step 5.3 to confirm the actions appear in the scaffolder API.
Version Mismatch¶
Symptom: TypeScript compilation errors in packages/app or
packages/backend after installing the plugin, referencing mismatched
Backstage API types.
Resolution: The plugins target Backstage v1.27.x. If your Backstage
version is older, run backstage-cli versions:bump to update all Backstage
packages to a compatible version. Check the compatibility table:
| Plugin Version | Backstage Version | RHDH Version |
|---|---|---|
0.1.x |
1.27.x |
1.3+ |
SkillMeat API Unreachable from Backend¶
Symptom: Scaffolder actions fail with connection-refused or timeout errors, but the API is accessible in the browser.
Explanation: The scaffolder backend plugin runs in the Backstage backend
process (Node.js), not in the browser. The skillmeat.baseUrl must be
reachable from the backend host, not only from the client browser.
Resolution:
- Test connectivity from the backend host:
- If the API is only accessible internally, adjust the
skillmeat.baseUrlto use the internal service DNS name or IP. - If DNS resolution is the issue, add the hostname to
/etc/hostsor use an IP address directly.
Next Steps¶
With the plugins installed and the basic configuration verified, continue to:
-
Catalog Integration — Set up the entity provider to expose SkillMeat artifacts in Backstage's software catalog, add
EntitySkillMeatContenttabs to your entity pages, and configure entity refresh triggers. -
Developer Portal Integration — Configure the developer portal surface so that developers can discover, browse, and adopt SkillMeat artifacts within their IDP workflow.
-
Governance & Permissions — Define organizational policies, role/group mappings, and audit configuration for controlled artifact adoption.