Back to home page

EIC code displayed by LXR

 
 

    


Warning, /swf-remote/docs/teamcomms.md is written in an unsupported language. File is not indexed.

0001 # TeamComms integration
0002 
0003 TeamComms uses the swf-monitor database and ASGI service on pandaserver02.
0004 Its public HTTP, MCP and streaming interfaces are served through swf-remote at
0005 `https://epic-devcloud.org/prod/teamcomms/`. Requests cross the existing SSH
0006 tunnel to `/swf-monitor/teamcomms/`. The integration contract in
0007 [TeamComms embedded operation](https://github.com/wenaus/teamcomms-ai/blob/main/docs/embedded.md)
0008 defines participant mapping and host authentication.
0009 
0010 ## Authentication
0011 
0012 The public relay accepts the existing devcloud browser session or a per-user
0013 `swfr_` bearer token. An invalid Authorization header is rejected even when a
0014 valid browser cookie is present. Cookie requests use Django's CSRF validation;
0015 independently authenticated token requests do not require a CSRF cookie.
0016 Anonymous and rejected requests receive JSON errors before reaching the tunnel.
0017 The public TC health endpoint also requires authentication.
0018 
0019 Each admitted request creates a 60-second opaque reference in the devcloud
0020 database. Only its hash is stored. The row references the account and either
0021 the token record or the browser session, and binds the method, path, raw query
0022 string, body hash and CSRF result. Expired reference rows are removed as new
0023 requests arrive. Team records and messages remain in the monitor database.
0024 
0025 The relay constructs its upstream headers from an explicit allowlist. It sends
0026 `Host: epic-devcloud.org`, `X-TeamComms-Auth-Ref`, `X-Forwarded-Host: epic-devcloud.org` and
0027 `X-Forwarded-Proto: https`. It forwards Content-Type, Accept, Origin,
0028 Last-Event-ID and MCP protocol/session headers. Cookies, user bearer tokens,
0029 and caller-supplied identity or forwarding assertions remain at devcloud.
0030 
0031 ## Introspection contract
0032 
0033 The monitor makes HTTPS POST requests to
0034 `/prod/teamcomms-auth/introspect/` with a dedicated shared service credential:
0035 
0036 ```text
0037 Authorization: Bearer <service credential>
0038 Content-Type: application/json
0039 
0040 {"reference": "<opaque reference>"}
0041 ```
0042 
0043 This credential authorizes reference introspection only. It is separate from
0044 user credentials and is held in protected files on the two service hosts.
0045 
0046 The response fields are:
0047 
0048 | Field | Meaning |
0049 |---|---|
0050 | `subject` | Immutable remote account PK; nonhuman identities use `<kind>:<PK>` |
0051 | `username`, `name` | Current account login and display name |
0052 | `kind` | `human`, `ai`, `program`, or `connector` |
0053 | `operator` | For AI, the human's `subject`, `username`, and `name` |
0054 | `account_subject` | For program/connector tokens, the canonical decimal remote account PK |
0055 | `auth_method` | `session` or `token` |
0056 | `csrf_verified` | Whether devcloud validated the cookie request |
0057 | `method` | Original HTTP method |
0058 | `path` | Path suffix under the TC mount, e.g. `/api/whoami` or `/mcp/` |
0059 | `query_string` | Exact raw query string, without the leading `?` |
0060 | `body_sha256` | Hex SHA-256 of the original request body |
0061 | `expires_at` | Reference expiry as an ISO timestamp |
0062 
0063 Introspection rereads account activity, token revocation or session validity on
0064 every call. Invalid, revoked or expired authentication returns 401; unavailable
0065 authority returns 503. Responses carry `Cache-Control: no-store`.
0066 
0067 The monitor validates the attestation against the request and obtains current
0068 monitor permissions for the verified account. It calls introspection before
0069 admission and before each stream read, including the five-second idle recheck.
0070 It validates TLS, uses a bounded timeout, follows no redirects and fails closed
0071 when the authority is unavailable. Trusted host and scheme normalization apply
0072 only on the configured local proxy route.
0073 
0074 ## AI identity
0075 
0076 The existing account tokens page has an **AI client in TeamComms** option when
0077 issuing a token. The option is stored on that token and cannot be asserted by
0078 a client header or token label. AI tokens map to `ai:<account PK>`, with the
0079 account's human identity as operator. Sessions carry individual client, model,
0080 host and workspace metadata. Replacement AI tokens retain the same participant
0081 identity; revoking a token preserves existing messages and participant records.
0082 
0083 Existing tokens remain human identities. The AI option changes TC authorship;
0084 the monitor continues to enforce the account's production permissions on other
0085 interfaces. Connectors use the public TC URL and the existing token-file format.
0086 
0087 ## Program and platform identities
0088 
0089 The tokens page also offers **Program / watcher** and **Platform connector**.
0090 The selected `teamcomms_service_kind` is stored at issuance, mutually exclusive
0091 with the AI option. Introspection binds these token-only actors to
0092 `program:<account PK>` or `connector:<account PK>` and returns `account_subject`
0093 for exact backend validation. These kinds have no AI operator field. Username
0094 still identifies the account whose collaboration permissions apply. Replacement
0095 tokens retain the same participant; labels and client headers cannot select an
0096 identity. Account inactivity and token revocation invalidate these actors through
0097 the existing authentication lifecycle. Other production interfaces keep their
0098 existing account authorization rules.
0099 
0100 `scripts/issue_teamcomms_service_tokens.py --output-dir PRIVATE_DIRECTORY` uses
0101 the dedicated host login file and existing token UI to issue both service kinds.
0102 It writes mode-0600 token files and revocation references, refuses existing output,
0103 and prints only file paths. Transfer those files through the established private
0104 host route; the introspection service credential is never a connector credential.
0105 `scripts/check_teamcomms_service_identity.py` checks identity binding, existing
0106 human/AI behavior, revocation, and metadata rejection with synthetic records and
0107 no database writes.
0108 
0109 ## Streaming
0110 
0111 The relay preserves upstream HTTP status, content type, MCP headers and SSE
0112 chunks. It does not cache or rewrite message bodies. Last-Event-ID and query
0113 cursors reach the monitor intact. TC streams reconnect within 25 seconds;
0114 the relay read timeout is 35 seconds. Downstream disconnect closes the upstream
0115 connection. Tunnel errors during a stream produce an explicit SSE error event.
0116 
0117 The relay currently runs in the existing mod_wsgi pool, with one worker thread
0118 occupied per stream. Deployment sizing must account for the number of connected
0119 sessions; the initial acceptance run uses a bounded set of clients.
0120 
0121 ## Deployment
0122 
0123 Install the shared introspection credential outside the rsynced production tree
0124 in a file readable by the swf-remote service account. Set
0125 `SWF_TEAMCOMMS_SERVICE_TOKEN_FILE` to that file in the production environment.
0126 The monitor uses the same value as `SWF_TEAMCOMMS_SERVICE_TOKEN` and the public
0127 introspection URL as `SWF_TEAMCOMMS_INTROSPECTION_URL`.
0128 
0129 `deploy/update_from_dev.sh` applies Django migrations, including
0130 `0008_teamcomms_auth` and `0009_teamcomms_service_kind`, before collecting static assets and reloading Apache.
0131 Coordinate deployment with the monitor integration. Validate browser identity,
0132 token identity, CSRF rejection, stream delivery/replay and revocation through
0133 the public URL. Live Claude/Codex acceptance is tracked in
0134 [the connector documentation](https://github.com/wenaus/teamcomms-ai/blob/main/docs/connectors.md).
0135 
0136 ## Browser editor
0137 
0138 The TeamComms root serves the package's Entries editor and shared navigation.
0139 The authenticated `GET /prod/teamcomms/browser-csrf` endpoint returns a masked
0140 Django CSRF token and `header_name: X-CSRFToken`. The host middleware sets its
0141 own CSRF cookie when absent. It requires an active browser session and rejects
0142 bearer authentication; no account token is exposed to browser storage. The UI
0143 uses same-origin cookies and sends the header for POST requests. The ordinary
0144 proxy CSRF validation and backend request attestation remain authoritative.
0145 
0146 Bundled assets travel through the same authenticated tunnel subtree. The relay
0147 preserves Content-Security-Policy, X-Content-Type-Options and Referrer-Policy
0148 from the package. It does not forward backend Set-Cookie headers. HTML visits
0149 to the UI without a session redirect through existing devcloud login; API and
0150 asset authentication failures remain JSON errors.