Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions docs/extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,22 @@ It exports **only local** settings, even if an old `.env` contains Azure setting
into the URI input. That field is **not masked**. Never paste a password-bearing
URI there. The generated URI points to `127.0.0.1`, selects your database, and
specifies TLS, `SCRAM-SHA-256`, `authSource=admin` and `directConnection=true`.
4. For this loopback connection only, choose **Allow invalid certificates** when
the TLS picker appears. TLS encryption stays **on**; this accepts the existing
local development server's self-signed certificate. It is not “disable TLS,”
not a global setting, and never applies to Azure or another remote service.
4. **In the local TLS prompt, select “Allow invalid certificates” for BOTH
Workshop — Site A and Workshop — Site B. Do not leave “Enable TLS (default)”
selected for these workshop connections.** The default validates certificates
and rejects the development server's self-signed certificate with the error
**“self-signed certificate.”** Keep `tls=true` in the generated URI: encryption
stays **on**; only certificate validation is relaxed for these specific
`127.0.0.1` development connections. Never apply this exception to Azure or
another remote service.

> **DocumentDB for VS Code 1.0.0 label caveat:** after this choice, the tree or
> dashboard may display **“⚠ TLS/SSL Disabled.”** That wording is misleading
> for this exact workshop configuration: the supplied URI still has `tls=true`,
> and the extension applies `tlsAllowInvalidCertificates=true` rather than
> disabling encryption. Both local connections were exercised successfully
> with this choice in the attendee test. This is not an instruction to set
> `tls=false`, disable TLS globally, or change your database password.
5. If asked for an authentication method, choose **Username and Password**
(native authentication). Enter the section's username and paste its password only
into the **masked password prompt**. Do not select Microsoft Entra/Azure login.
Expand Down
8 changes: 8 additions & 0 deletions docs/lab.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ Neither means managed Azure. Both sites have separate credentials and volumes.
Run `npm run extension:connections` and follow the
[private setup steps](extension.md#connect-the-two-existing-sites-privately). Save
**Workshop — Site A** and **Workshop — Site B** in DocumentDB **Connections**.

> **Local TLS prompt: choose “Allow invalid certificates” for both sites.**
> The default certificate-validation choice rejects their self-signed development
> certificates. Keep `tls=true`: encryption stays on. Extension 1.0.0 may label
> this **“TLS/SSL Disabled”** even though only certificate validation is relaxed
> for these loopback connections; see the [TLS explanation](extension.md#connect-the-two-existing-sites-privately).
> Do not use this exception for Azure or change global TLS settings.

Expand each to its actual workshop database. This is required lab tooling, not an
Azure demo: no sign-in, no **Set Up Local** third database, no forwarded database
ports. Keep the credential file out of screen sharing. If the editor is blocked,
Expand Down
4 changes: 3 additions & 1 deletion scripts/extension-connections.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ export async function writeExtensionConnections(directory = process.cwd(), log =
const content = [marker, "SECRET: open privately; never share, commit, screenshot, or paste into a terminal.",
"Use DocumentDB: New Connection... > Connection String. No Azure sign-in or local setup wizard.",
"Paste only the credential-free URI into the unmasked URI box; username/password go in separate native-auth prompts.",
"Select Allow invalid certificates for these loopback connections only: TLS stays enabled with the local self-signed certificate.", "",
"LOCAL TLS PROMPT (BOTH SITES): choose Allow invalid certificates, not Enable TLS (default). The default rejects the local self-signed certificate.",
"Keep tls=true: encryption stays on. In extension 1.0.0, the warning TLS/SSL Disabled is misleading for this configuration; only certificate validation is relaxed.",
"This exception is only for these 127.0.0.1 development connections. Never apply it to Azure, set tls=false, change global TLS settings, or rotate passwords to fix a certificate error.", "",
...connections.flatMap(({ label, port, database, uri, username, password }) => [label, `Loopback port: ${port}; database: ${database}`, `Connection string (no credentials): ${uri}`, `Username: ${username}`, `Password (paste only in masked prompt): ${password}`, ""]),
].join("\n");
const temporary = join(privateDirectory, `.connections-${randomUUID()}.tmp`);
Expand Down
16 changes: 16 additions & 0 deletions test/extension.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ test("private handoff is owner-only, atomically repeatable, excludes cloud and p
assert.equal((await stat(output)).mode & 0o777, 0o600);
const content = await readFile(output, "utf8");
assert.match(content, /Password \(paste only in masked prompt\): site A: p@ss\/#\$literal/);
assert.match(content, /LOCAL TLS PROMPT \(BOTH SITES\): choose Allow invalid certificates, not Enable TLS \(default\)/);
assert.match(content, /Keep tls=true: encryption stays on/);
assert.match(content, /TLS\/SSL Disabled is misleading/);
assert.match(content, /Never apply it to Azure/);
assert.doesNotMatch(content, /never-export|cloud\.invalid/);
assert.doesNotMatch(logs.join("\n"), /mongodb:|p@ss|independent-secret|never-export/);
assert.equal(await writeExtensionConnections(directory, () => {}), output);
Expand Down Expand Up @@ -207,3 +211,15 @@ test("read-only playground templates use the selected database/catalog, bounded
assert.equal(calls[0].projection.catalogVersion, 1);
assert.equal(calls[0].limit, 5);
});


test("attendee guides call out the local TLS choice and misleading v1.0 warning", async () => {
for (const name of ["../docs/extension.md", "../docs/lab.md"]) {
const text = await readFile(new URL(name, import.meta.url), "utf8");
assert.match(text, /Allow invalid certificates/);
assert.match(text, /self-signed/);
assert.match(text, /tls=true/);
assert.match(text, /TLS\/SSL Disabled/);
assert.match(text, /Azure/);
}
});
Loading