Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

Sample: provisioning semantic layers via the FrontierOps Management API

A working example of CI/CD-driven semantic-layer provisioning. Merging to main applies every YAML file in this repo to the FrontierOps platform; pull requests dry-run-validate them first. No secrets are stored in this repo — the workflow authenticates with GitHub's OIDC identity against a trust binding configured on the platform.

Repository layout

orgs/
  test/                      ← the target organization's SLUG on FrontierOps
    connector-slug/          ← the database connector's SLUG in that org
      semantic-layers/
        analytics.yaml       ← the semantic layer's SLUG = the filename

The path encodes everything: orgs/<org-slug>/<connector-slug>/semantic-layers/<layer-slug>.yaml. Which org each file goes to is decided by the org folder; which connector the layer attaches to is decided by the connector folder. A folder for an org outside the trust binding's grant fails with 403 for that file only.

The connector is a directory level so an org with several connectors keeps each connector's layers separate (e.g. orgs/acme/snowflake/… and orgs/acme/postgres/…). The connector must already exist in the org and be a database-type connector; create it once in the dashboard (Connectors → Add) before provisioning layers that reference it.

One-time setup

  1. Platform (an org admin, on the parent org): Settings → Management API → New Trust Binding. Recommended pair for this repo:

    • Apply: branch ref refs/heads/main, scopes semantic layers read + write
    • Validate: no branch ref, scope semantic layers read only

    The token exchange picks the right one automatically (most specific wins).

  2. This repo: nothing to configure. The workflow file's id-token: write permission is the only "setup" — no secrets, no variables, no GitHub Apps.

  3. Create the database connector in each target org (dashboard → switch to that org → Connectors → Add), then name the connector folder in this repo to match its slug. In this sample, org test has a connector slugged connector-slug, so the folder is orgs/test/connector-slug/.

What happens on each event

Event Job Effect
Pull request validate Each YAML dry-runs against POST …/validate; broken YAML fails the check with errors in the log. Nothing is written.
Push to main provision Idempotent PUT …/by-slug/{slug} per file: unchanged YAML = no-op (version stays), changed = version bump, new file = created.

Deletes are deliberate: removing a YAML file does not delete the layer.

Tip: mark the validate job as a required status check in branch protection so an invalid semantic layer can never reach main.

Troubleshooting

  • 401 invalid_grant — no binding matches (check the repo is owner/repo exactly, branch pin, binding enabled) or the OIDC token was already used.
  • 403 on a PUT — that org isn't in the binding's grant, the binding was disabled, or the token lacks write scope.
  • 404 connector_not_found — the connector folder name doesn't match a connector slug in that org. Switch to the org in the dashboard, open Connectors, and confirm a database connector exists whose slug equals the folder name (connectors are per-org — one created in the parent org does not exist in a child).
  • 503 jwks_unavailable — transient GitHub keys outage; re-run the job.
  • Every applied change appears in Settings → Management API → the binding's Activity panel, with the GitHub run id and author.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors