Skip to main content

The management UI

A Vue 3 single-page application (tagshape-ui-management-web) — the only part of the product that is not C#. It is a client of the account, library set and audit APIs and holds no state of its own beyond the session.

Signing in​

The UI does not authenticate anyone itself. An unauthenticated visitor is sent to the auth UI, which runs the provider round-trip and drops an x-tagshape-auth cookie. A background service renews the token before it expires, which is why the token also travels as a cookie rather than a header alone.

The UI reads the permission catalogue from GET /permissions and its own permissions from the JWT, and hides what the caller cannot use. That is presentation, not enforcement — every one of these pages is calling an endpoint that checks the same permission server-side.

Pages​

RoutePageNeeds
/Home — panes summarising the library and recent activityVaries by pane
/librarysetsLibrary sets listVariableList
/librarysets/:idOne library set, its variables and their valuesVariableRead
/librarysets/newCreate a library setVariableCreate
/taggroupsTag groups listTagGroupList
/taggroups/:idOne tag group and its tagsTagGroupRead
/tagsAll tags across groupsTagList
/variablepreviewResolve a set of tags and see which value winsVariableRead
/batch/importImport a library fileBatchProcessingImport
/batch/exportExport tag groups and library sets to a fileBatchProcessingExport
/usersUsers listUserList
/users/:idOne account, its groups and its API keys — group membership can be edited here tooUserRead
/groupsGroups listUserList
/groups/:idOne group, its permissions and its membersUserRead
/organisationsOrganizations listGlobalOrganizationList (global)
/organisations/:idOne organization — providers, branding, patternsGlobalOrganizationRead (global)
/auditThe audit log, filtered and pagedAuditList
/profileYour own account and your API keysJWT only

Variables are reached through the library set that holds them rather than a page of their own — /variables redirects to /librarysets.

Notable pages​

Library set​

Adding a variable, editing one's values, deleting one, and reading a sensitive value each check library-set scope against this set's own ID, not just whether the permission is held somewhere. A caller whose VariableUpdate is scoped to other library sets sees the page (their VariableRead still covers it) but not the value editors on this one — the same as if they held no VariableUpdate at all. VariableCreate is the one exception: creating a library set (as opposed to a variable inside one) always needs it held unrestricted, so /librarysets/new and the page's own create/save distinction do not narrow by ID.

Variable preview​

Pick library sets and tags, and see what a consumer would be handed. It calls GET /variablevalues/preview, so each variable comes back as the whole winning value — its tags, whether it is sensitive, and its hint.

Each preview costs 10 credits, and is refused if the organization cannot afford it. (Opening a library set in the UI spends 1 credit too, since it is read with GET /variablesets/{id}; lists are free.)

This is the fastest way to diagnose an unexpected value: the tags on the winner tell you whether the problem is a mistagged value or a tag you forgot to ask for. See Resolution.

Batch​

The Batch section is shown to anyone holding BatchProcessingView, with an Import subsection and an Export subsection each gated on its own permission - someone holding only one still sees the section, with just the one subsection in it.

Import: a file picker, a summary of what the selected file holds (tag groups, tags, library sets, variables and how many are sensitive), and a replace toggle. It reports the same summary the API returns, including what a replacing import deleted. See Importing a library.

Export: two typeaheads for picking tag groups and library sets, and a choice of what a sensitive value writes in the downloaded file - its actual value, its hint, its hash, or blank. The actual-value option is offered only to someone holding VariableReadSecrets. See Exporting a library.

Group​

Permissions are offered by category, read from GET /permissions. The page uses the same catalogue's dependency graph to keep a group from being saved with a permission that would do nothing — rather than keeping its own copy of the graph, which would eventually disagree with the server's.

Permissions the caller cannot grant are shown but not editable, which matches the server's behaviour of preserving them on save.

A ticked permission the catalogue marks librarySetScopable grows an All library sets / Specific library sets choice beneath it. Choosing "Specific" reveals a chip-list-and-search picker — the same pattern the tag picker on a variable's value uses — for naming exactly which library sets it should apply to; leaving it on "All" (the default for anything not yet scoped) sends nothing extra, so an untouched permission behaves exactly as it always has. See Library-set scoping.

Organization​

Identity providers, logo and custom CSS. The Check credentials button calls POST /organizations/identityproviders/check, which tries the credentials against the provider without saving them — so a mistyped secret is found here rather than at somebody's login.

The custom CSS editor is a Monaco instance. Rules are filtered against an allow-list rather than injected wholesale.

The Client certificates section shows the primary and replacement slots, each with a badge for whether it is TagShape-generated or client-provided, its valid-from/to dates, and its thumbprint — never a way to download it. Generate and Upload (two text boxes for pasting a certificate and private key as PEM) fill an empty slot; Remove clears one; Rotate certificates swaps the two once both are filled. All four need GlobalOrganizationCertificateManage, shown but disabled without it — viewing the slots only needs GlobalOrganizationRead, which the page already required to be here at all. See Client certificates.

Profile​

Your own account, your linked identities, and your API keys. Creating a key is the one place the key itself is ever shown — copy it then, because only its hash is stored. The never-expiring option appears only if you hold ProfileNeverExpiresApiKey.

A service account's page lists its keys in the same way, and shows the same New API key form to anyone holding UserCreateServiceAccountApiKey — a service account has no login to make its own with. The form is not shown on a person's page, because a person's key is theirs to make. Removing a key from either page needs UserDelete.

Audit​

Paged and filtered against POST /filter. Entries whose before and after state you may not read are shown with the state withheld rather than hidden, so you can see that something happened even where you may not see what.

Variable types in the UI​

A variable's type and whether it is sensitive are set once for the variable, next to its name, not per value. The type selector offers String, Multiline, Number, Boolean, JSON and Certificate; once a variable has been saved as Boolean the selector is locked, and Boolean is removed from the choices for every other variable's selector — neither direction can be switched into or out of after saving. The Sensitive checkbox is hidden entirely for a Boolean variable, and once ticked and saved it can no longer be unticked.

Each value's editor follows the variable's type: a plain text box for String, a number input for Number, a tick box for Boolean. Multiline, JSON and Certificate get a five-line box inline, with an Expand button that opens a larger popover editor for the same value — JSON's popover is a full Monaco instance (the same editor used for custom CSS on the organization page), so it gets syntax highlighting and folding; Multiline and Certificate get a bigger plain text area.

Sensitive values in the UI​

Sensitive values render as a masked input with a reveal control. Where the caller lacks VariableReadSecrets there is nothing to reveal — the API returned an empty value — and the hint is shown instead. See Sensitive values.

Running it locally​

cd src/tagshape-ui-management-web
yarn install
yarn serve

Under the Aspire host it is started as ui-management with its API references wired up. See Architecture.