Skip to content

Rewrite the privacy policy against the privacy review - #114

Open
aterga wants to merge 4 commits into
mainfrom
claude/connector-marketplace-publish-p4el4n
Open

Rewrite the privacy policy against the privacy review#114
aterga wants to merge 4 commits into
mainfrom
claude/connector-marketplace-publish-p4el4n

Conversation

@aterga

@aterga aterga commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Rewrites the served privacy policy (/privacy-policy) and its source text against the privacy review of 2026-07-31 (one critical, five high-severity findings), then against three follow-up Copilot review rounds. The page is live on staging and ships to production at the next release-* tag, so this should land before that tag.

What the privacy review found, and what changed

Severity Issue Fix
Critical Contradictory key custody Long-term credentials never leave Internet Identity; the Service holds a delegated session signing key it generates itself (no secret crosses a network in either direction — only the public half travels, for II to sign); per-application keys, also server-generated, do the actual request signing; the assistant separately holds an OAuth access token
High Recipients understated Section 2 covers the assistant and its provider, the network's nodes and API boundary nodes, application operators, websites fetched during discovery, the two DFINITY-operated metadata services, and AWS as hosting processor
High No legal bases, rights, or complaint route Section 1 gives a basis per purpose (Art. 6(1)(b) per EDPB Guidelines 2/2019; 6(1)(f)/Recital 49 for security logging and metrics); section 7 enumerates the GDPR rights and names the FDPIC plus the user's EU/EEA supervisory authority
High "Questions only" sounds safer than it is Says plainly that read access can retrieve private, account-specific data and return it to the assistant, and that the authorization is not restricted to particular applications
High Data categories omitted results Covered, with what they can contain
High No cross-border disclosure Section 3 names Germany (AWS eu-central-1, Frankfurt) — established via AWS's published ip-ranges.json; EEA-adequate under the Swiss list, with a residual-access sentence for AWS's processing terms
Med–high Pseudonymous identifiers treated casually OAuth registrations are pseudonymous personal data, not "no personal data"
Med–high Cross-application correlation Section 6 documents what the Service can see and the three things limiting linkage
Medium Retention incomplete Per-category table, stating plainly that OAuth registrations currently have no time limit
Medium Absolute logging claims unaudited Section 5 is a line-by-line account backed by a recorded audit
Medium Scope and domains Both served domains named; unauthenticated use covered
Low–med Open-ended change clause Updated effective date + reasonable advance notice for material changes

Corrections from the Copilot review rounds (all verified against the implementation)

  • Per-application connection material is its own data category and retention row: the session cache keeps each application's domain, account number, server-generated per-app key, and II's signed delegation until session end (src/identities.rs:312-325, 1048-1092).
  • Revocation is two-step: ≤5 minutes for anything new; already-issued app delegations remain usable until they expire (≤1 hour, II's default TTL) because they are reused without an II round-trip. Sections 4 and 7 state this consistently.
  • Logs carry the ephemeral session-key principal, not the stable own-origin identity — so log entries from different sessions cannot be linked.
  • The session key does not sign application calls; per-application keys do. The custody paragraph describes both tiers.
  • Metrics: gauges computed on demand; the status dashboard keeps its most recent health report in memory until replaced — "held in memory only, never written to disk".
  • Log scoping: /status/* bypasses the application (no routine log line); reverse-proxy failure diagnostics can include request URIs with query strings.

Open-items status

All four original [NEEDS INPUT] items are resolved or relocated; the published page contains no markers:

  1. Hosting locations — resolved with evidence (Frankfurt; see above).
  2. Legal bases — adopted with reasoning recorded in the source doc's header; overall legal sign-off of the document remains the human review gate on this PR.
  3. Metrics retention — resolved with evidence.
  4. EU representative (Art. 27) — off the page (the text asserts nothing either way; the FDPIC/EU-authority complaint sentence is accurate regardless) and tracked in the source doc's header for DFINITY legal: name a representative in section 7, or record a reasoned Art. 3(2) non-applicability position.

Engineering follow-ups worth separate issues

Both would let the policy make stronger promises: pass a short max_ttl (~5 min) to mcp_prepare_delegation so cached delegations cannot meaningfully outlive revocation, and purge a session's cached state when an Unauthorized is observed.

Related issues

Follows #109 (submission package), #112 (the page and route), #111 (retention bound).

Changes

  • src/assets/privacy-policy.html: rewritten; adds table and callout styling.
  • docs/icp-mcp-privacy-policy-draft.md: rewritten to match, plus the logging audit.

Testing

  • cargo build --locked --bin imcp2
  • Served locally after each round and asserted the substantive changes appear in the rendered text, __LOGO__ substituted, no em-dashes, zero [NEEDS INPUT] on the page
  • Rendered in Chromium: retention table and callout styling display correctly
  • npm test --prefix monitoring/mcp-status — n/a, dashboard unchanged

Checklist

  • I have read the Contributing guidelines.
  • Docs (README / comments) updated for any user-visible change.
  • No secrets, credentials, or internal-only information are included.

Addresses every item in the review. The substantive ones:

CRITICAL, key custody. The policy said no private keys are shared with
the Service while also saying it holds a session key and signs calls.
It now states precisely that long-term authentication credentials never
leave Internet Identity, that the Service holds a DELEGATED SESSION
SIGNING KEY bounded by scope and expiry, and that the assistant
separately holds an OAuth access token.

HIGH, recipients. Section 2 now covers the assistant and its provider,
the network's nodes and API boundary nodes, application operators,
websites fetched during discovery, the two DFINITY-operated metadata
services, and hosting processors.

HIGH, legal bases, rights, complaints. Section 1 gives a basis per
purpose; section 7 enumerates access, rectification, erasure,
restriction, objection and portability, and names the FDPIC plus the
user's EU/EEA authority.

HIGH, 'Questions only' oversold. It now says read access can retrieve
private account-specific data and return it to the assistant, and that
the authorization is NOT restricted to particular applications.

HIGH, results were undisclosed. The data category now covers responses,
not just arguments, and lists what they can contain.

HIGH, cross-border. New section 3, with the hosting locations marked
as needing input.

MEDIUM-HIGH, identifiers. OAuth registrations are treated as
pseudonymous personal data rather than 'no personal data'. New section 6
documents what the Service could correlate and what limits it.

MEDIUM, retention. A table with a maximum or a deletion criterion per
category, stating plainly that OAuth registrations have no time limit.

MEDIUM, absolute logging claims. Section 5 replaces them with a
line-by-line account, backed by an audit recorded in the source file:
tool-performing modules contain zero tracing calls, and Caddy is
configured without access logging. 'Not systematically' is gone; source
IPs are acknowledged as processed in transit and possible in
diagnostics.

MEDIUM, scope. Both served domains are named, and unauthenticated use
is covered.

LOW-MEDIUM, change clause. Replaces 'at our discretion' with an updated
effective date plus reasonable advance notice for material changes.

Four [NEEDS INPUT] markers remain for what engineering cannot decide:
hosting locations, confirmation of the legal bases, metrics retention,
and an EU representative.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TGhwpdTbUqQbR5AiiN8Ljw

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Rewrites the served privacy policy and synchronized source text following the 2026 privacy review.

Changes:

  • Expands disclosures covering credentials, recipients, retention, logging, transfers, and user rights.
  • Adds retention tables and unresolved-input callouts.
  • Documents the logging audit supporting policy claims.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 11 comments.

File Description
src/assets/privacy-policy.html Updates the public policy page and styling.
docs/icp-mcp-privacy-policy-draft.md Mirrors policy text and records the logging audit.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/assets/privacy-policy.html Outdated
Comment thread src/assets/privacy-policy.html Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md
Comment thread src/assets/privacy-policy.html Outdated
Comment thread src/assets/privacy-policy.html Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md Outdated
Comment thread src/assets/privacy-policy.html Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md Outdated
… 3 of 4 open items

Copilot's review of the rewrite found three claims that did not survive
contact with the implementation; all verified and corrected in both the
served page and the source text:

- A per-session cache (Session.app_delegations) keeps the application
  domain, account number, per-application key seed, and II's signed
  delegation for the rest of the session, so 'not retained after the
  call completes' was wrong for that material. It is now its own data
  category and retention row.
- Revocation has two windows, not one: II stops honouring the
  connection within five minutes, but cached per-application
  delegations are reused without an II round-trip (delegated_identity)
  and were issued with II's default TTL of up to one hour, so already
  issued authorizations survive revocation until they expire. Sections
  4 and 7 now describe the two steps and the ~1h practical worst case.
- Logs carry the ephemeral session-key principal (session_principal),
  not the stable own-origin identity, which is never logged. Sections
  5 and 6 and the logging audit now say exactly that, which also makes
  the cross-session-linkage story more accurate: log entries from
  different sessions cannot be linked.

Three of the four [NEEDS INPUT] items are also resolved with evidence:

- Hosting: both deployments map to AWS eu-central-1 (Frankfurt) in
  AWS's published ip-ranges.json; Germany is EEA-adequate under the
  Swiss Federal Council's list, so section 3 names the country and
  needs no extra safeguard beyond AWS's processing terms.
- Legal bases: adopted (Art. 6(1)(b) per EDPB Guidelines 2/2019 for the
  service categories; 6(1)(f) with Recital 49 for security logging,
  abuse prevention, and metrics). FADP requires no per-purpose basis of
  private controllers; the listing satisfies Art. 13(1)(c) where GDPR
  applies.
- Metrics: verified computed on demand from memory and never persisted;
  the retention row now says so.

The EU-representative question (GDPR Art. 27) remains the one open
marker: if Art. 3(2) applies, the occasional-processing exemption will
not fit, so legal must either name a representative or record a
reasoned non-applicability position.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TGhwpdTbUqQbR5AiiN8Ljw

aterga commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

All eleven review findings verified against the implementation and addressed in b7fc283, in both the served page and the source text. They reduce to four defects:

  1. The per-session delegation cache was undisclosed (Session.app_delegations, src/identities.rs:312-325, populated at 1048-1092): the application domain, account number, per-application key seed, and II's signed delegation persist for the rest of the session, so "not retained after the call completes" was wrong for that material. It is now a data category of its own ("Per-application connection material") with its own retention row, and the requests/results category carves it out explicitly.

  2. Revocation has two windows, not one: delegated_identity reuses a cached delegation without contacting Internet Identity, and delegations are requested with max_ttl = null, II's default of up to one hour — so an already-issued application authorization survives revocation until it expires. Sections 4 and 7 now describe the two steps consistently (≤5 min for anything new; ≤1 h for already-issued authorizations; practical worst case ~1 h), replacing both the bare five-minute promise and the contradictory "immediate" wording.

  3. The logged principal was misdescribed: logs carry session_principalself_authenticating over the per-connection session key, new every connection — not the stable own-origin identity, which is never logged. Sections 5 and 6 and the logging audit now name the actual value; the corrected version is also stronger for users, since log entries from different sessions cannot be linked through it.

  4. The header's open-items list was out of sync with the markers in the body; it is now a per-item status list.

The same commit resolves three of the four [NEEDS INPUT] items with evidence: hosting (both deployments map to AWS eu-central-1/Frankfurt in AWS's published ip-ranges.json; Germany is EEA-adequate under the Swiss list, so section 3 names it), legal bases (adopted: Art. 6(1)(b) per EDPB Guidelines 2/2019 for the service categories, 6(1)(f)/Recital 49 for security logging and metrics), and metrics retention (verified computed on demand from memory, never persisted). The one remaining marker is the EU representative (Art. 27), which needs a decision from DFINITY legal.

Two engineering follow-ups worth tracking separately rather than in this docs PR, both of which would let the policy make stronger promises: pass a short max_ttl (e.g. 5 minutes) to mcp_prepare_delegation so cached delegations cannot outlive revocation by more than minutes, and drop a session's cached state when an Unauthorized is observed.


Generated by Claude Code

@aterga
aterga marked this pull request as ready for review July 31, 2026 19:14
@aterga
aterga requested review from a team and Copilot July 31, 2026 19:14
…page

Key custody, strengthened per review of the critical finding: the
delegated session signing key (and each per-application key) is
generated inside the server by fresh_ed25519; only the DER public half
is sent to Internet Identity for signing, so no secret key crosses a
network in either direction. The custody paragraph now says so.

The PR being taken ready for review means the page publishes, and a
visible NEEDS-INPUT box does not belong on a public policy. The
published text asserts nothing about an EU representative either way
(the FDPIC/EU-authority complaint sentence is accurate regardless), so
publication does not pre-empt the Art. 27 decision, which stays tracked
in the source doc's header for DFINITY legal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TGhwpdTbUqQbR5AiiN8Ljw

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Suppressed comments (6)

src/assets/privacy-policy.html:190

  • This description is inconsistent with the implementation and with section 7: the session key is used to obtain a separate per-application delegation, while application calls are signed by the per-application key; after revocation, an already-issued delegation can still be used for up to one hour. As written, readers are told that the session key directly signs tool calls and stops all activity on revocation.
time-limited, scope-limited authorization to act as you, and the Service uses
that key to sign the requests your assistant makes. It is a signing
credential, so it is worth being precise about its limits: it is not your
Internet Identity key, it cannot be used to sign in as you anywhere else, and
it stops working when the authorization expires or you revoke it. Separately,

docs/icp-mcp-privacy-policy-draft.md:95

  • This source wording does not match the implementation or section 7: the session key obtains separate per-application delegations, and those per-application keys sign application calls. Already-issued delegations can also remain usable for up to one hour after revocation, so saying the key directly signs requests and simply stops on revocation is misleading.
session signing key**. Internet Identity issues it a time-limited, scope-
limited authorization to act as you, and the Service uses that key to sign
the requests your assistant makes. It is a signing credential, so it is worth
being precise about its limits: it is not your Internet Identity key, it
cannot be used to sign in as you anywhere else, and it stops working when the
authorization expires or you revoke it. Separately, your AI assistant holds an

docs/icp-mcp-privacy-policy-draft.md:266

  • The dashboard does retain operational results in memory: monitoring/mcp-status/server.js stores the latest health report in cache.report, and an expired report is not removed until another report replaces it or the process restarts. “Not persisted” does not justify saying these metrics are “not stored”; document the dashboard’s actual in-memory retention.
| Connection (OAuth) registrations | Stored on disk so an assistant can reconnect across restarts. There is currently **no time limit**: a registration is kept until it is displaced once the store reaches its cap of 10,000, which for a rarely-used deployment can mean indefinitely. |
| Technical logs | Up to three months, then deleted. |
| Aggregated operational metrics | Computed on demand from data already in memory; not stored. |

src/assets/privacy-policy.html:400

  • The deployment does not support these absolute claims. log_request only covers requests reaching Axum; /status/* is routed directly to the Node dashboard, which has no routine request log. Also, disabling Caddy access logs does not prevent reverse-proxy failure diagnostics from including the request URI (and therefore a query string). Scope the routine-log statement to the MCP application and disclose diagnostic URIs.
<li>Every request produces one log line with the HTTP method, the path, the
response status, and how long it took. Query strings and request bodies are
never included, which keeps single-use codes and delegations out of logs.</li>

docs/icp-mcp-privacy-policy-draft.md:281

  • This is broader than the audited behavior. Axum logs only requests that reach the MCP application; /status/* bypasses it and has no routine access log. Caddy can also include the request URI, including its query string, in reverse-proxy failure diagnostics even without an access-log directive. Qualify both assertions so the source matches the deployed logging paths.
- Every request produces one log line with the HTTP method, the path, the
  response status, and how long it took. Query strings and request bodies are
  never included, which keeps single-use codes and delegations out of logs.

src/assets/privacy-policy.html:383

  • The “not stored” retention claim is false for the status dashboard cited by the source audit. monitoring/mcp-status/server.js keeps the most recent health report in cache.report; after its reuse TTL expires it remains in memory until another report replaces it or the process restarts. Disclose that in-memory retention rather than equating “not written to disk” with “not stored.”
<tr><td>Aggregated operational metrics</td><td>Computed on demand from data
already in memory; not stored.</td></tr>

Comment thread src/assets/privacy-policy.html Outdated
Comment thread docs/icp-mcp-privacy-policy-draft.md Outdated
Copilot AI review requested due to automatic review settings July 31, 2026 19:19
…lot round 3)

All verified against the implementation:

- The session key does not sign application calls: it authenticates the
  Service to Internet Identity to obtain per-application delegations,
  and those per-application keys sign the actual requests. The custody
  paragraph now describes the two tiers, and defers revocation to
  section 7's two-step window instead of claiming the key simply stops
  on revocation.
- 'Not stored' was false for the status dashboard: server.js keeps the
  most recent health report in cache.report until replaced or restart.
  The metrics retention row now says held in memory, never on disk.
- 'Every request produces one log line' covered only requests reaching
  the axum application; /status/* is proxied straight to the Node
  dashboard with no routine request log. Scoped, and disclosed that
  reverse-proxy failure diagnostics can include the requested address
  with any query string. Logging audit updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TGhwpdTbUqQbR5AiiN8Ljw

aterga commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

Round-3 findings verified and fixed in 550b985 (both files):

  • Key-signing description: correct — the session key never signs application calls; it authenticates the Service to Internet Identity to obtain per-application delegations, and those per-application keys sign the requests. The custody paragraph now describes both tiers and defers revocation to section 7's two-step window instead of claiming the key "stops working" on revocation.
  • Metrics "not stored": correct — monitoring/mcp-status/server.js keeps the most recent health report in cache.report until replaced or restart. The retention row now says "held in memory only, never written to disk" and names the dashboard's report cache.
  • Log-claim scope: correct on both counts — log_request covers only requests reaching the axum application (/status/* is proxied straight to the Node dashboard, which has no routine request log), and reverse-proxy failure diagnostics can include the requested address with any query string. Both bullets are scoped accordingly, and the logging audit records the /status/* bypass.

The two placeholder comments were fixed in 74d9d11, just before this review landed: the EU-representative [NEEDS INPUT] marker is removed from both the served page and the source. The published text asserts nothing about a representative either way (the FDPIC/EU-authority complaint sentence is accurate regardless), so publication does not pre-empt the Art. 27 determination, which remains tracked in the source doc's header for DFINITY legal.

Resolving all threads addressed by b7fc283, 74d9d11, and 550b985.


Generated by Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (10)

docs/icp-mcp-privacy-policy-draft.md:385

  • This audit treats absence of Caddy's log directive as if it excluded all request metadata, but that only disables routine access logs. Caddy still emits diagnostic http.log.error entries for reverse-proxy failures, including the request URI/query. Record that exception here; otherwise the audit does not support section 5's absolute query-string claim.
- Request logging (`log_request`, `src/main.rs`) records method, path, status,
  and latency, and deliberately omits the query string and the body. It covers

src/assets/privacy-policy.html:394

  • This repeats the immediate-deletion claim, but expired session records remain in the map until the periodic 60-second reaper removes them. Clarify that the chosen duration ends usability immediately while memory deletion follows on cleanup.
written to disk: gauges are computed on demand, and the status dashboard
keeps its most recent health report in memory until the next one replaces it
or the process restarts.</td></tr>
</table>

docs/icp-mcp-privacy-policy-draft.md:280

  • This repeats the immediate-deletion claim, but expired session records remain in the map until the periodic 60-second reaper removes them. Clarify that the chosen duration ends usability immediately while memory deletion follows on cleanup.
| Technical logs | Up to three months, then deleted. |
| Aggregated operational metrics | Held in memory only, never written to disk: gauges are computed on demand, and the status dashboard keeps its most recent health report in memory until the next one replaces it or the process restarts. |

Revoking a connection takes effect in the two steps described in section 7.
Revocation does not by itself erase the session record: the delegated
signing key and the per-application connection material stay in memory until

docs/icp-mcp-privacy-policy-draft.md:104

  • This still describes the wrong signing flow. Identities::derive_app_delegation uses the session key only to obtain a per-application delegation from Internet Identity; a separate per-application key signs the application call. The current wording also sounds as though revocation disables all signing immediately, while section 7 correctly says already-issued application authorizations remain usable for up to an hour. Keep the source text aligned with the actual two-key flow.
travels is only the key's public half, which Internet Identity signs,
issuing a time-limited, scope-limited authorization for that key to act as
you. The Service uses the session key with Internet Identity to obtain, for
each application you interact with, a further short-lived authorization and
per-application key (the connection material described in section 1), and
those per-application keys are what actually sign your requests. All of
these are signing credentials the Service generated itself, so it is worth

src/assets/privacy-policy.html:417

  • The “never included” claim only holds for the Rust application logger. Caddy has no routine access log, but reverse-proxy failures are written to http.log.error with request metadata including the full URI and query string. During an upstream/process failure, this policy therefore promises more than the deployed stack guarantees. Distinguish the application log from Caddy diagnostics and disclose that diagnostic URIs may contain queries.

<h2>5. What Our Logs Contain</h2>

src/assets/privacy-policy.html:196

  • This still describes the wrong signing flow. Identities::derive_app_delegation uses the session key only to obtain a per-application delegation from Internet Identity; a separate per-application key signs the application call. The current wording also sounds as though revocation disables all signing immediately, while section 7 correctly says already-issued application authorizations remain usable for up to an hour. Describe both key layers here so the key-custody correction is accurate.
which Internet Identity signs, issuing a time-limited, scope-limited
authorization for that key to act as you. The Service uses the session key
with Internet Identity to obtain, for each application you interact with, a
further short-lived authorization and per-application key (the connection
material described in section 1), and those per-application keys are what

docs/icp-mcp-privacy-policy-draft.md:299

  • The “never included” claim only holds for the Rust application logger. Caddy has no routine access log, but reverse-proxy failures are written to http.log.error with request metadata including the full URI and query string. During an upstream/process failure, this policy therefore promises more than the deployed stack guarantees. Distinguish the application log from Caddy diagnostics and disclose that diagnostic URIs may contain queries.

This issue also appears on line 384 of the same file.


We would rather be specific than make sweeping promises, so:

src/assets/privacy-policy.html:369

  • Expiration does not discard this record immediately. spawn_session_reaper runs every 60 seconds, and only prune_stale removes the session key and cached application material; expiration merely makes the credentials unusable until that sweep. Because this is explicitly a retention table, distinguish immediate expiry from later deletion.

This issue also appears on line 391 of the same file.

<h2>4. Data Retention</h2>

<table>
<tr><th>Category</th><th>Retained</th></tr>

docs/icp-mcp-privacy-policy-draft.md:267

  • Expiration does not discard this record immediately. spawn_session_reaper runs every 60 seconds, and only prune_stale removes the session key and cached application material; expiration merely makes the credentials unusable until that sweep. Because this is explicitly a retention table, distinguish immediate expiry from later deletion.

This issue also appears on line 275 of the same file.
docs/icp-mcp-privacy-policy-draft.md:15

  • The PR description still says four visible [NEEDS INPUT] markers remain and lists hosting, legal bases, and metrics retention as unresolved, but this source now marks those three resolved and the rendered policy contains no markers. Update the PR description and merge checklist to reflect the current state and explicitly say whether the remaining EU-representative decision blocks publication; otherwise reviewers and release operators have contradictory acceptance criteria.
> **Open-items status (2026-07-31):**
>
> 1. **Hosting locations: resolved.** Both deployments run on AWS EC2 in

Copilot AI review requested due to automatic review settings July 31, 2026 19:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (5)

src/assets/privacy-policy.html:373

  • The signing key is not discarded at the instant the chosen duration elapses. McpServer::spawn_session_reaper runs every 60 seconds (src/lib.rs:345-378), and expired sessions remain in the map until that sweep; the same timing affects the per-application material and revocation statements below. Update all matching retention claims (and the source copy) to disclose the periodic-cleanup delay.
<tr><td>Session and authorization data (signing key, access level,
duration)</td><td>In volatile memory only, never written to disk. Discarded
when the duration you chose elapses (at most 30 days) or when the Service
restarts, whichever comes first.</td></tr>

docs/icp-mcp-privacy-policy-draft.md:270

  • This promises deletion exactly when the selected duration elapses, but expired session records are removed only by the 60-second reaper in src/lib.rs:345-378. The signing key and cached per-application material can therefore remain until the next sweep. Update this row and the matching per-application/revocation statements to describe periodic cleanup, and mirror that wording in the served page.
| Session and authorization data (signing key, access level, duration) | In volatile memory only, never written to disk. Discarded when the duration you chose elapses (at most 30 days) or when the Service restarts, whichever comes first. |

src/assets/privacy-policy.html:338

  • The recipient list does not match the Service's outbound calls. src/discover.rs:1307-1319 uses ic-api.internetcomputer.org, icrc-api.internetcomputer.org, and sns-api.internetcomputer.org, while skills use skills.internetcomputer.org; the application does not call dashboard.internetcomputer.org. This currently omits two metadata API recipients and names the wrong endpoint, undermining the section's purpose. Update the served policy to list the actual services/hosts.

This issue also appears on line 370 of the same file.

<p><strong>Two services DFINITY Foundation operates</strong>: the public
canister-metadata service at <code>dashboard.internetcomputer.org</code> and
the developer-skills service at <code>skills.internetcomputer.org</code>.</p>

docs/icp-mcp-privacy-policy-draft.md:238

  • This source list is inconsistent with the implementation: src/discover.rs:1307-1319 contacts three separate metadata hosts (ic-api, icrc-api, and sns-api), in addition to the skills service, and does not contact dashboard.internetcomputer.org. List the actual recipients so the source remains accurate and synchronized with the served policy.

This issue also appears on line 270 of the same file.

**Two services DFINITY Foundation operates**: the public canister-metadata
service at `dashboard.internetcomputer.org` and the developer-skills service
at `skills.internetcomputer.org`.

docs/icp-mcp-privacy-policy-draft.md:39

  • This leaves a merge prerequisite unresolved while hiding it from the served page. The PR description says the four [NEEDS INPUT] items must remain visible and specifically lists the EU representative as required before merge, but this revision removes every marker and moves the still-open Art. 27 decision "off the page." Either obtain and record the legal decision before merging, or restore a visible unresolved marker/callout so publication cannot silently proceed without it.
> 4. **EU representative: open with DFINITY legal, off the page.** The
>    published text asserts nothing either way (the FDPIC/EU-authority
>    complaint sentence is accurate regardless), so publication does not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants