Skip to content

Require publicUrl to be an origin URL and detect Slack OIDC by hostname - #156

Open
salluexez wants to merge 1 commit into
yc-software:mainfrom
salluexez:fix-public-url-origin-validation
Open

Require publicUrl to be an origin URL and detect Slack OIDC by hostname#156
salluexez wants to merge 1 commit into
yc-software:mainfrom
salluexez:fix-public-url-origin-validation

Conversation

@salluexez

@salluexez salluexez commented Aug 3, 2026

Copy link
Copy Markdown

Summary

  • Enforce publicUrl to be an HTTP(S) origin URL (without credentials, subpaths, queries, fragments, or trailing dots) across all target environments during CLI configuration validation.
  • Update Slack OIDC issuer validation to detect Slack by hostname (slack.com or *.slack.com) rather than an exact literal string comparison.
  • Added unit test coverage in cli/test/config.test.ts.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Copilot AI review requested due to automatic review settings August 3, 2026 15:35

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

This PR tightens configuration validation to prevent misconfigured base URLs and to treat Slack OIDC issuers more robustly by identifying Slack issuers via hostname rather than a single literal issuer string.

Changes:

  • Enforce publicUrl as an HTTP(S) origin-only URL during CLI config validation (no credentials, paths, query/fragment, or trailing hostname dot).
  • Detect Slack OIDC issuers by hostname (slack.com / *.slack.com) instead of exact string comparison when deciding whether JWKS configuration is required.
  • Add unit tests covering the new publicUrl origin validation.

Reviewed changes

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

File Description
plugins/portal/src/index.ts Updates runtime boot checks to treat Slack issuers by hostname via a new isSlackIssuer helper.
cli/src/config.ts Tightens publicUrl validation and updates portal trust validation to use hostname-based Slack issuer detection.
cli/test/config.test.ts Adds tests ensuring publicUrl is validated as an HTTP(S) origin and normalized consistently.
Suppressed comments (1)

cli/src/config.ts:509

  • publicUrl origin validation doesn’t reject URLs with an empty hostname (e.g. https:///). new URL("https:///") parses with protocol https: and pathname /, so this currently passes validation and then normalizes to https://, which is not a usable public origin. Add an explicit non-empty hostname check (and consider keeping apiUrl validation in sync, since it uses the same pattern).
    const parsed = new URL(publicUrl);
    if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error("protocol");
    if (parsed.pathname !== "/" || parsed.search || parsed.hash || parsed.username || parsed.password)
      throw new Error("origin");
    if (parsed.hostname.endsWith(".")) throw new Error("trailing dot");

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

Comment thread cli/src/config.ts
Comment on lines +804 to +811
function isSlackIssuer(issuer: string): boolean {
try {
const host = new URL(issuer).hostname;
return host === "slack.com" || host.endsWith(".slack.com");
} catch {
return false;
}
}
Comment thread cli/test/config.test.ts
Comment on lines +91 to +99
for (const publicUrl of [
"",
"not a url",
"ftp://acme.example",
"https://acme.example/subpath",
"https://acme.example?x=1",
"https://user:pw@acme.example",
"https://acme.example.",
]) {
Comment thread cli/src/config.ts
Comment on lines 500 to 504
const publicUrl = o["publicUrl"];
if (typeof publicUrl !== "string" || !publicUrl.trim()) {
throw new CliError(`${path}: "publicUrl" must be a non-empty http(s) URL`);
throw new CliError(`${path}: "publicUrl" must be a non-empty http(s) origin URL`);
}
try {
Comment on lines +121 to +128
function isSlackIssuer(issuer: string): boolean {
try {
const host = new URL(issuer).hostname;
return host === "slack.com" || host.endsWith(".slack.com");
} catch {
return false;
}
}
@16francej 16francej added code-pr Code submitted instead of an ADR bug Something isn't working security Security-sensitive change labels Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working code-pr Code submitted instead of an ADR security Security-sensitive change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants