First public release. Web admin for Apache SkyWalking 10.5+'s runtime-rule hot-update + DSL-debugging surfaces. Distroless container, stateless BFF, browser-local debug history.
Auth & RBAC
- Local accounts in
studio.yamlwith argon2id-hashed passwords; bring-your-own via thevsadmin:hashCLI. - Default admin/admin on first run with a forced-rotation banner.
- Cookie-based session store (in-memory,
Secure+HttpOnly+SameSite=Strict). - Six RBAC verbs gating every BFF route:
rule:read,rule:write,rule:debug,rule:dump,rule:storage_change,rule:revert_bundled. - JSONL audit log for every state-changing request (
actor/verb/outcome/clientIp).
Catalog editor
- Three runtime-rule catalogs surfaced from the admin-server:
otel-rules,log-mal-rules,lal. Plus a read-onlyoalcatalogue for the bundled.oalsource files. - Sidebar grouped under DSL Management:
MAL · OTEL/MAL · Telegraf/LAL/LAL → MAL(log-mal-rules, placed below LAL to reflect the data-flow direction) /OAL · read-only. - Monaco YAML editor with bundled MAL / LAL DSL grammars and per-catalog autocomplete.
- Hot-update through
runtime/rule/{addOrUpdate, inactivate, delete}; "filter-only edit" path detected and pushed without bumping the alarm window or triggering DDL. - Bundled-vs-runtime side-by-side diff when an override exists.
- Search + status facets (active / inactive / bundled / modified) + "+ new rule" inline form with name validation.
Live debugger (MAL · LAL · OAL)
Per-DSL views over OAP's SWIP-13 /dsl-debugging/* flow.
Common
- Per-cluster install ack strip (
installed/already_installed/failed/timeoutper peer). - Defaults match
SessionLimits.MAX_RECORD_CAP = 100for both default and hard ceiling; 5 min retention default, 1 h hard cap. BFF rejects out-of-range with400 invalid_recordCap. - Auto-save to browser-local capture history (see below).
- Deep-link from catalog rows + Monaco gutter glyphs.
MAL
- Per-record card with rule-meta strip (
metric/filter/exp/suffix). - 3-column stage grid per step:
label · rail · rows-table. - Rows-table:
name | labels | value(left-aligned, capped at 50 rows + "+ N more"). - Click a step → its
sourceText<mark>'d in the rule-meta strip above. - Output meter renders only what the wire serialises:
metric,function,value(when present — scalarnumber,stringfor non-finite, orRecord<string, number>for histogram-percentile /*Labeled),timeBucket. Entity card collapses null fields with ashow alltoggle. - Per-record fold/expand with subhead
fold all/expand all.
LAL
- Per-record × per-block matrix with sticky leftmost block-label column and sticky top record-header row.
- Statement-mode function rows split per
sourceLineand carry the verbatim DSL slice (tag stage: 'extractor'…) as their name; block-mode collapses to one row labelledextractor. - Search filter on log body / content / tags (case-insensitive);
show first Ncap (default 20, max 100). - Foldable side pane on the left renders the captured rule body line-by-line. Statement lines carry an accent
▶jump-hook; the block-mode anchor (extractor {opening line) carries a red▶. Click → matrix scrolls the matching step row into view with a 1.5 s flash highlight. Pane folds to a 28 px "Captured DSL" stub via a chevron toggle in its header. - Cell tag groups split into
carried(status:original) and+ added(lal-added+lal-override, with the override flagged amber). Input cell renders LogData kv + body preview; function / output cells render LogBuilder kv + tag chips + content preview. - Click
⤢on a record header to expand it to a full-width single column (sticky block column + DSL pane stay mounted);↩collapses back.
OAL
- Per-record card with the same 3-column stage grid as MAL.
- Source / metric payloads render every primitive top-level field as
key=value. - IDManager
entityId/entity_iddecoded inline alongside the raw value, e.g.Y2hlY2tvdXQ=.1 (checkout · real). Six scopes supported: Service / ServiceInstance / Endpoint / ServiceRelation / ServiceInstanceRelation / EndpointRelation. Decoder mirrors OAP'sIDManager+isNormalboolean. - Metric
id(<timeBucket>_<entityId>) decoded as2026-05-09 10:36 · checkout · realwith bucket-only fallback when the entity portion fails to parse.
Capture history
- New sidebar entry
Capture history(/debug/history). - Auto-save to
localStorage(keyvs:debug-history:v1) on every poll; upsert by(widget, sessionId)so polls update the same entry in place. Skip-if-unchanged write avoidance. - Cap 20 entries per widget (oldest dropped on overflow / quota error). Storage is local-only — nothing leaves the browser.
- Cross-DSL list with chip-row filter (all / mal / lal / oal), newest first.
- Active entries (retention deadline still in the future) carry a
livebadge + 1 Hz countdown; resume → routes to/debug/{widget}?resumeSessionId=<id>and reattaches polling on OAP without re-allocating a session. - Completed entries route via
?historyId=<id>for read-only replay with an amber "viewing saved capture" banner. - Per-row delete + confirm-gated "clear all".
Cluster status
/clusterpage lists every OAP peer the BFF can reach with version / uptime / role.- Per-node DSL-debugging health (probes injected, active sessions, cap remaining).
Dump
/dumppage exports the live ruleset across catalogs as atar.gz(gated behindrule:dump).
Docker image
ghcr.io/wu-sheng/vantage-studio:0.1.0
ghcr.io/wu-sheng/vantage-studio:latest
gcr.io/distroless/nodejs24-debian12:nonrootruntime base.- Two-stage build (Node 24 builder → distroless runtime), ~150 MB compressed.
- Tags:
:0.1.0and:lateston this release;:<full-commit-sha>on every push to main. - Cosign keyless signing + CycloneDX SBOM attestation on every release tag. Verify with:
cosign verify ghcr.io/wu-sheng/vantage-studio:0.1.0 \ --certificate-identity-regexp 'https://github.com/wu-sheng/vantage-studio/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com - Configurable via
STUDIO_CONFIG(path tostudio.yaml) +STUDIO_UI_DIR(where the SPA bundle lives) +STUDIO_CONFIG_EXAMPLE(first-run seed). - Listens on
:8080for the SPA +/api/*; talks to OAP on:17128(admin-server) +:12800(query-graphql).
CI
- Lint: ESLint flat config + Vue plugin.
- License headers:
apache/skywalking-eyesaction. - Tests: 174 across the workspace (UI 63 + BFF 82 + api-client 24 + design-tokens 5).
- Per-commit image (
:<full-commit-sha>) on every push to main; release image (:<X.Y.Z>+:latest, cosign-signed + SBOM) onv*.*.*tag pushes.
Wire types (@vantage-studio/api-client)
- New exports:
MAX_RECORD_CAP,MAX_RETENTION_MILLIS(mirrors of OAP'sSessionLimits.java). MalOutputPayload.value:number | string | Record<string, number>(per OAP's holder switch — scalar / non-finite-double sentinel /DataTablefor labeled / percentile metrics).SessionRecord.dslcarries a per-record snapshot of the rule body so hot-update edits show up record-by-record without a separate fetch.
Documentation
README.md— overview, quick start, doc index.docs/install.md— OAP image build + bringing up Studio.docs/configure.md—studio.yamlschema reference.docs/auth.md— local accounts, argon2id, RBAC verb table, deferred LDAP / OIDC design + IAP workaround.docs/docker.md— image internals, env vars, override patterns (compose / k8s with init-container).docs/operator-workflows.md— five common paths through the UI; the live-debugger + capture-history sections rewritten to match the SWIP-13 wire shape that ships in 10.5.docs/compatibility.md— required SkyWalking version + module selectors.
Required OAP modules
SWIP-13 selectors all default to disabled upstream; OAP operator opts in:
SW_ADMIN_SERVER=defaultSW_RECEIVER_RUNTIME_RULE=defaultSW_RECEIVER_DSL_DEBUGGING=default
Deferred to a later release
- LDAP / OIDC auth (designed in
docs/auth.md; IAP-style workaround for SSO sites). - Whole-bundle dump → restore (per-rule restore is wired; bundle restore is designed but not in this release).
- Runtime-rule history / diff / rollback (requires OAP-side store that doesn't exist yet).
- OAL hot-update (read-only this release; the live debugger binds to the recorder, but adding / replacing
.oalfiles at runtime is not yet supported upstream).
Acknowledgements
- Built on Apache SkyWalking (SWIP-13 — DSL debugging + admin-server).
- License headers verified by
apache/skywalking-eyes.