Repository navigation
Bud 1.2.0
Bud 1.2.0 adds access control with groups and policies, run notifications to Microsoft Teams, Slack, Discord or any JSON endpoint, an audit log, S3-compatible storage, Robot Framework runs through bud-runner, and report requests from Bloom.
Highlights
- Access control: permissions are grouped into policies and policies into groups, with a new
developerrole, separate Users and Access pages, and access requests from a run you may not open. - Run notifications per channel to Teams, Slack, Discord or any JSON endpoint, optionally signed: every run, failures only, or the first failure after a green run.
- Audit log of security-relevant events, read under Audit log and pruned on the operator's schedule.
- S3-compatible storage for run artifacts and generated reports, with the local directory kept as a mirror. Local storage stays the default.
- Robot Framework runs from bud-runner 1.2.0 keep
log.htmlandreport.htmlwith the run; every artifact is downloaded as an attachment under a sandbox policy. - Report requests from Bloom, a company logo on PDF reports, and profile pictures.
Upgrade notes
- Back up the database and the uploads volume first. Migrations
017_release120and018_report_requestsrun from 1.1.0 (016_key_station_name). Migration 017 checks the 1.1.0 schema before it changes anything and stops with "Source schema fingerprint does not match its revision" when that schema was altered by hand. A downgrade below 017 is refused once the database holds what 1.1.0 cannot represent: execution requests,developeraccounts, or group access that was changed or goes beyond Results. - Only Test Stations submit execution results and upload artifacts:
POST /api/uploadsanswers 403 for every user,adminincluded (1.1.0 accepted uploads from administrators). Move stations to bud-runner 1.2.0, which sends these with the station token even when a user session is configured. - Links in emails (invitations, verification, password resets) and report links use
APP_BASE_URL.FRONTEND_BASE_URLis still read, but only whenAPP_BASE_URLis not set; an install that sets both should check thatAPP_BASE_URLis its public address. - S3 storage is optional:
BUD_STORAGE_BACKEND=s3(orSTORAGE_BACKEND) withBUD_S3_BUCKETand the otherBUD_S3_*settings listed in.env.example.python -m app.storage migrate --to s3copies existing files. - PyJWT replaces python-jose; boto3 and Pillow are added.
Compatibility
| Component | Version |
|---|---|
| Container image | ghcr.io/mbedlabs/bud:1.2.0 (also 1.2, 1, stable) |
| bud-runner | 1.2.0 for station-token uploads and Robot Framework, pytest and Behave runs |
| budtestlibrary | 1.2.0 |
| Bloom (optional) | 1.2.0 for report requests |
Added
- Report requests from Bloom appear for report publishers on the dashboard and run page, and notify active publishers through configured SMTP. Publishers fulfill requests through report publishing or refuse with a reason; status returns to Bloom.
- Company logo on test-run PDF reports: a user with
settings.edituploads a company logo in Settings; it renders on the report letterhead (top-left) alongside the EmbedLabs tamper-evidence footer, which is always present. The Settings preview loads through the authenticated client so the uploader sees exactly what was stored. - S3-compatible object storage:
STORAGE_BACKEND=s3keeps run artifacts and generated reports in a bucket (AWS S3, MinIO, Hetzner, Ceph) under a per-instance prefix, with the local directory as a mirror that reads fall back to when the bucket does not answer (STORAGE_LOCAL_MIRROR, default on).python -m app.storage migrate --to s3copies existing files and checks their sizes; cleanup reconciles the bucket;/api/readyreports the storage. Local storage stays the default and is unchanged. Adds boto3 to the locked dependencies. - Robot Framework runs (bud-runner
run-robot): HTML artifacts (text/html, Robot's log.html and report.html) are accepted. Every artifact download is an attachment sent withContent-Security-Policy: sandboxandX-Content-Type-Options: nosniff, so user-supplied HTML or SVG never runs in the Bud origin. The Bloom sync event says how many results had no Bloom tc_id and how many skipped results were not sent. - Access control: permissions are
resource.actionpairs:evidence.view,reports.export,products.view,products.manage,stations.view,stations.manage,custom_runs.create,bloom_publish.execute,settings.view,settings.edit,audit.view,access.manage. A policy is a named set of permissions, a group is a named set of policies, and a user can be in several groups. A user's permissions are those of their role plus those of all their groups. Roles:viewerhas the Results policy,developeralso has Custom runs and Reports publishing,adminhas every permission. 8 default policies and 5 default groups (Results Viewers, Test Operators, Station Managers, Access Managers, Application Administrators) are created; changing or deleting one returns 409,POST /{id}/duplicatecreates an editable copy. A group containingstations.managecan only be given toadminordeveloperusers (422). Onlyadmincan give Application Administrators and change policies (403). A user withaccess.managecan only create, change, delete or give groups whose permissions they have themselves (403). User management and deleting runs and artifacts stayadminonly. Access is not limited by product. - Access endpoints:
/api/policies(with/catalogueand/{id}/duplicate),/api/groups(policies, members,/{id}/duplicate) andGET /api/access/users.GET /api/auth/mereturns the user'spermissions. - Separate Users and Access pages:
/usersmanages accounts;/access, foradminand users withaccess.manage, provides Assignments with group rosters, Groups with policy bundles, Policies with a Read/Write editor and Requests. - Run notifications: when a run finishes, Bud posts it to every enabled channel under Settings, Notifications: Microsoft Teams (an Adaptive Card for a Power Automate Workflows URL, a MessageCard for a classic connector URL, chosen from the URL), Slack (Block Kit), Discord (embed) or plain JSON for any endpoint. The message carries the run, product, station and software under test, the counts and duration, up to five failed tests, the Bud link and the Bloom link or sync failure. A channel sends all runs, failures only, or the first failure after a green run; its URL is stored encrypted and shown as a prefix; an optional secret signs the JSON body (
X-Bud-Signature). Each delivery is attempted up to three times and recorded, shown as a notify stage on the run timeline; Send test message checks a channel. Routing per product and per station is not in this release. - Audit log: security-relevant events (authentication, accounts, groups, station registration, enrolment keys and station removal, configuration, deletions, exports, imports, attachments) are recorded with the acting user, the request id, the client address, the outcome and details without secrets; a failed sign-in is recorded although the request fails. Users with
audit.viewread it under Audit log (GET /api/audit, filtered by actor, action, target, product, outcome and time). No endpoint changes or deletes an event;python -m app.audit prune --older-than-days Nremoves old events on the operator's schedule. Event times are shown in the viewer's time zone. - Run access requests: a run that returns 403 or 404 shows a page with a Request access button (
POST /api/access-requests,resource_type=test-run). Everyadminand every user withaccess.managegets an email with a link to/access. One request per user and resource per 24 hours. Requests are decided withPOST /api/access-requests/{id}/decision. Requests and decisions are written to the audit log; if the email fails, the request is kept and the user is told. - Publish to Bloom requests: a user without
bloom_publish.executesees Request access instead of Publish on a run (resource_type=publish-to-bloom). Granting requires agroup_idof a group that hasbloom_publish.executeand adds the user to it (422 otherwise). - Database: migrations
017_release120and018_report_requestsupgrade from 1.1.0 (016_key_station_name), including report requests. A database created by a pre-release 1.2.0 development image is converted as well: members of its development groups are moved to Test Operators (developer groups) or Results Viewers (viewer groups); the old group tables are kept and no longer used. - Profile picture: a signed-in user uploads, replaces or removes their own picture under Settings, Account (PNG, JPEG or WebP up to 2 MB; stored as a PNG of at most 256 x 256 pixels without metadata, with the camera orientation applied).
GET,PUTandDELETE /api/auth/me/picture;/api/auth/mereportshas_profile_picture. Saved pictures appear in Users, the account menu, group memberships, audit actors and access requesters, with initials when none is stored. Replacing or removing a picture refreshes these identity views while preserving unrelated cached data.
Changed
- Custom Run stores a human execution request and shows its assigned station; the execution link appears when that station claims it. Only authenticated Test Stations create execution records, update their execution state, submit raw results and upload artifacts;
POST /api/uploadsreturns 403 for every user,adminincluded. Queued requests do not appear as completed or pending executions in reports and dashboard totals. Dashboard totals classify claimed executions as in progress until the station acknowledges completion, and a nonzero exit or execution error counts as failure even when no method results were produced. - Run page and PDF reports: a skipped assertion and an information entry (a Robot keyword that checks nothing) are not counted as assertions; the run page shows them in neutral colour, the reports leave them out.
- Times written for people are given to the second, in UTC: the start, completion and generation times on PDF reports and the time in access-request emails.
Fixed
- Signing out, and a session check that fails while a user is signed in, now reload the page, and a tab reloads when it next renews its session and finds it belongs to another user signed in from another tab. Nothing cached for the previous user stays in memory, and signing in empties the cache as well. Before, the next user in the same tab could be shown data cached for the previous one for up to five minutes.
- A database error while committing a request, such as a constraint violation, is answered with 409 or 500 and the request id; the commit now runs before the response is built instead of after it had started.
- Orphan cleanup measured its grace period from a UTC time read as local time, so on a host not running in UTC it was off by the UTC offset.
- User and runner API key timestamps in API responses carry the UTC marker (
Z); without it the Users page showed the time of an email change request shifted by the viewer's UTC offset.
Full changelog: v1.1.0...v1.2.0