Repository navigation
feat: artifacts, and a universal public-exposure gate — TeamWork is trusted, a public link needs a person's decision - #260
Merged
Merged
Conversation
…ork, public only by a person's decision - artifact_service: self-contained HTML pages in the workspace (artifacts/<id>/index.html + manifest), every write a git commit, size and id limits. Tools artifact_publish / artifact_list / artifact_share_public / artifact_unshare, and /teamwork/artifacts routes for TeamWork's viewer. - A public link has no password, so artifact_share_public is an always-on hard floor (holds with HARD_FLOORS_ENABLED off): a person approves that exact share in TeamWork (timed grants don't count) or asks for it by name. Links expire (ARTIFACT_PUBLIC_HOURS, max 168) and can be revoked. - /shared serves HTML with CSP 'sandbox allow-scripts' (artifacts: no network too) and nosniff. - Fix: at the hub the floor gate and the HIGH-risk gate keyed one call differently (expected_observation popped in between), so a person's floor approval was asked for again. The key now ignores expected_observation. ARTIFACTS_ENABLED defaults off. Idea credit: Telepath's Television.
…link needs a person's decision TJ: TeamWork is the trusted surface (the deployer must secure it); a public (ngrok) link has no password, so putting anything there needs an explicit approval, every time. - Every publishing tool is an always-on hard floor: artifact_share_public, workspace_share_file, course_publish(public=True). A person approves that exact call in TeamWork (timed grants don't count; the prompt says it will be PUBLIC) or asks in their own words naming the thing. - The share registry refuses any public share made outside a person's decision (exposure_gate); a new or plugin path fails closed. Shares record approved_by. - workspace_send_file no longer falls back silently to a public link. - Over a tunnel, Prax's private routes are closed when PRAX_API_KEY is unset (PRAX_TUNNEL_REQUESTS_NEED_KEY, default on); TeamWork's direct calls are unaffected. - docs/security/public-exposure.md: the rule, and securing TeamWork as the deployer's job.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits:
ARTIFACTS_ENABLED, default off.Guides:
docs/guides/artifacts.md,docs/security/public-exposure.md.1. Artifacts
artifact_servicekeeps self-contained HTML pages in the workspace (artifacts/<id>/index.html+manifest.json).ARTIFACT_MAX_BYTES), and ids can't escape the folder.artifact_publish(title, html, artifact_id="")creates an artifact, or makes a new version of one;artifact_list;artifact_share_public(artifact_id, hours)andartifact_unshare(artifact_id).[artifact:<id>]on its own line. TeamWork renders it live, in a sandboxed iframe with no network./teamwork/artifactsand/teamwork/artifacts/<id>[?meta=1]sit behind the existingPRAX_API_KEYcheck.ARTIFACT_PUBLIC_HOURS, default 24, at most 168), always show the latest version, and are revoked byartifact_unshare./sharedserves HTML withContent-Security-Policy: sandbox allow-scriptsandnosniff.2. The universal public-exposure gate
TJ: TeamWork is considered secure, so the deployer has to secure it, and the docs now say so in both repos. A public (ngrok) link is not secure: there is no password, so anyone with the link can open it. Putting anything there needs an explicit approval.
HARD_FLOORS_ENABLEDoff. The tools areartifact_share_public,workspace_share_fileandcourse_publish(public=True);public=Falsestays in TeamWork and is not gated.prax/services/exposure_gate.py). A plugin or a future feature that tries to publish directly getsExposureNotApproved, not a link. Every share recordsapproved_by.workspace_send_fileused to make a public link whenever it couldn't deliver a file directly. Now the file stays in TeamWork's file browser, and Prax offers a link the user would approve.PRAX_API_KEYunset, a request to/teamwork/*,/plugins/*or/api/users/*that carries forwarding headers (X-Forwarded-*,Forwarded,X-Real-IP) gets 403. Setting:PRAX_TUNNEL_REQUESTS_NEED_KEY, default on.public=True. A direct caller now gets "(not made public: …)" instead of a link.Behaviour changes to know before deploying
workspace_share_fileandcourse_publish(public=True)used to run on MEDIUM risk. Now they need the user's decision.PRAX_URLin TeamWork's.envpoints through a reverse proxy or tunnel (not straight at Prax), TeamWork's panels will now get 403 unlessPRAX_API_KEYis set in both.envfiles. After deploy, check that the TeamWork panels load. Setting the key is the recommended setup anyway.Fix found on the way (affects hard floors already on main)
expected_observation, and the HIGH-risk gate keyed it after. That gave one call two keys._trifecta_keynow ignoresexpected_observation. Spoke-layer floors (the browser credential tools) were not affected.Verified
public=Falsenot gated,public=Truerefused, allowed when the user names the course;send_filenever makes a link;make ci: green, 4103 passed, with 0 secrets-proxy requests during the run.Idea credit: Telepath's Television.