Multi-team config ownership
VectorStep has no accounts and no self-service user management — see Security. That’s a deliberate design choice, not a gap, once you separate two different things that “who can do what” actually means here:
- Who can author a pipeline or step. Low-risk, and — as of
security.allow_shell_checksdefaultingfalseandsecurity.template_sandboxdefaultingtrue— genuinely containable per team. - Who can mint a credential, and at what role. High-risk: an
admintoken is equivalent to shell on the host (see Threat model).
Conflating those two is what makes “no accounts” feel like a gap. Split them,
and a plain git repo with CODEOWNERS covers the first one completely, while
the second one staying centralized to one platform team is the correct
answer, not a limitation to work around.
The model
Section titled “The model”One platform (or “owning”) team runs the VectorStep instance. Other teams
don’t log into it to manage their own access — they get handed a
webhook-role token, same as Team attribution
already describes: “onboarding a team” is synonymous with “issuing them a
token.” What this page adds is where that token lives and who gets to
change what, using the same git repo your CI/CD already deploys config from.
Repo layout
Section titled “Repo layout”vectorstep-config/ config.yaml # server, database, auth, executors, notifications pipelines/ platform/ 10-self-monitoring.yaml payments/ 10-fraud-check.yaml 20-chargeback-alert.yaml fulfillment/ 10-shipping-delay.yaml steps/ platform/ restart-service.yaml payments/ verify-transaction.yaml fulfillment/ check-carrier-status.yaml CODEOWNERSpipeline_config_dir and step_library_dir already load every *.yaml file
in their directory (recursively is not required — one subfolder per team under
each is enough) into one merged collection, so this layout needs no
VectorStep code changes: point pipeline_config_dir: ./pipelines and
step_library_dir: ./steps at the parent directories as normal, and file
ownership is entirely a git-repo concern from there.
config.yaml itself — and therefore auth.tokens — has no equivalent
multi-file mechanism; it’s loaded as exactly one file (CONFIG_PATH, see
Deployment). That’s what makes it the natural
place to draw the ownership line.
CODEOWNERS
Section titled “CODEOWNERS”# Platform team owns the credential list and everything security-relevant./config.yaml @org/platform-team
# Each team reviews changes to its own pipelines and steps./pipelines/payments/ @org/payments-team/steps/payments/ @org/payments-team/pipelines/fulfillment/ @org/fulfillment-team/steps/fulfillment/ @org/fulfillment-team/pipelines/platform/ @org/platform-team/steps/platform/ @org/platform-teamPair this with branch protection requiring the matched CODEOWNERS review
before merge. A payments engineer can now ship a new pipeline without a
platform-team review on the pipeline logic itself — but cannot touch
config.yaml, so cannot grant themselves a higher-role token, change
security.allow_shell_checks, or add an admin credential. That boundary is
what makes the “self-service” half of this safe to actually delegate: the
directory split alone doesn’t guarantee it, the fact that allow_shell_checks/
template_sandbox live in the one file the team’s PR can’t touch does.
Requesting a token
Section titled “Requesting a token”There’s no issuance endpoint — a token is a plain shared secret (see Team attribution). The process is a request, not a self-service action:
- A team opens an issue or PR touching only their own
pipelines/<team>/orsteps/<team>/path, tagging the platform team if they need a newwebhooktoken to go with it. - The platform team generates the value (
openssl rand -hex 24) and adds the entry toauth.tokensinconfig.yaml— a PR only they can approve, perCODEOWNERSabove. - The raw value never appears in the git history.
config.yamlreferences it as${VECTORSTEP_WEBHOOK_TOKEN_PAYMENTS}; the platform team sets the actual value in whatever secrets store your deployment already reads${ENV}substitutions from (a sealed secret, Vault, CI secrets — the mechanism is already documented in Deployment). - The token value is delivered to the requesting team out of band — through the same secrets store, if they already have read access to their own secret, not pasted into the issue/PR that requested it.
Name each entry <team>-<role> (payments-webhook, payments-operator) —
there’s no schema-level team field outside webhook-role tokens (see
Security), so a consistent naming convention is
what keeps the audit log (GET /audit, token name on every row) readable
per team for operator/viewer/admin credentials.
What this doesn’t give you
Section titled “What this doesn’t give you”No in-product way for a team to request or rotate their own token without the
platform team’s involvement — that’s the point, not an oversight. If
self-service token issuance for low-risk (webhook-only) credentials becomes
worth building later, the natural extension is a directory-based loader for
auth.tokens mirroring pipeline_config_dir’s existing pattern, with
per-file validation rejecting anything above webhook/viewer role in a
team-owned file. That doesn’t exist today — this page describes the
git-review boundary you can use right now, not a roadmap item.