Repository navigation
Owner-only /_api/logs for any container; ship-fix keeps the pod's logs private - #156
Merged
Merged
Conversation
…s private GET /_api/logs lists every container on the CVM and GET /_api/logs/<name> streams one container's full stdout/stderr (tail=all by default, since/until in unix seconds). Both take the owner token only. This replaces Phala's public_logs endpoint, which serves the same logs to anyone. ship-fix.sh passes --no-public-logs for the pod (phala deploy defaults it to true), and refuses to deploy when the local compose differs from the live one in anything but the daemon image.
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.
Phala's
public_logsflag is all or nothing. With it on, anyone who knows the CVM's instance id can download every container's full log, which for the daemon means its complete access log. With it off, nobody can read the logs, the owner included.phala deployalso defaults the flag to true, soship-fix.shhas been re-publishing the pod's logs on every deploy.The daemon already holds the Docker socket and the owner token, so it can serve the logs itself.
Change
GET /_api/logslists every container on the CVM (name, state, status, image).GET /_api/logs/<container>streams that container's stdout and stderr with timestamps.taildefaults toall, andsince/untiltake unix seconds. The response is streamed and demuxed frame by frame, since the pod's daemon log alone is several hundred MB./_api/statsand/_api/tokens.tail,sinceanduntilare checked the same way./_api/projects/<name>/logsstays as it is. It is capped at 2000 lines and only reaches a project's own container. The new route also reaches the daemon, the shared runtimes and the compose siblings such as the ingress.ship-fix.sh:--no-public-logs.phala cvms get --json), ignoring the daemon image, and refuses to deploy if anything else differs. The script only swaps the daemon digest, so any other drift in the local file was being shipped silently. The prod7 compose in hermes-agent is currently behind the pod: older daemon, noPROJECT_HOSTS, and one ingress domain instead of two. Shipping it would break private-agent's domains, so it has to be refreshed from the live compose before the next pod deploy.Upstream, Dstack-TEE/dstack#1469 (merged 2026-10-28) gates the guest agent's log route on a signed token in addition to
public_logs. That is the general fix, but it is not in any OS image Phala offers yet (newest is dstack-0.6.1).Tests
proxy/test_owner_logs.py, 7 tests:../), a badtailor timestamp, and a smuggled&follow=trueall get 400stream_logsruns against a fake Docker Engine on a unix socket. It demuxes stdout and stderr frames split across writes, including a 70 KB frame. TTY containers pass through raw, and a missing container raises before anything is written.python3 -m pytest proxy/).oauth3-prod7: it refuses the current localdocker-compose.prod7.yamland namestee-daemonandcpanel-ingressas differing. It accepts the live compose.Not deployed. Rolling it out to the pod means one CVM upgrade, which also turns
public_logsoff: refresh the local compose from the live one, then./ship-fix.sh pod.