Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7e46fb8
lint: add optional openssl usage linter
jasonhernandez Apr 1, 2026
50cfe2b
doc: add openssl-to-rustls migration plan and linter output
jasonhernandez Apr 1, 2026
b1f30c5
doc: update migration plan for FIPS 140-3 compliance mode
jasonhernandez Apr 1, 2026
c6f2ccf
deny: ban non-FIPS crypto crates to prevent compliance gaps
jasonhernandez Apr 1, 2026
c5ce52f
lint: add container FIPS compliance auditor
jasonhernandez Apr 2, 2026
73001a8
doc: add comprehensive FIPS 140-3 compliance report
jasonhernandez Apr 2, 2026
accfc2e
lint: fix copyright header and python formatting
jasonhernandez Apr 2, 2026
8d20957
crypto: unblock rustls and add FIPS feature flag via mz-ore
jasonhernandez Apr 2, 2026
1fa0f67
chore: regenerate Cargo.lock after rebase
jasonhernandez Apr 2, 2026
2f50dcd
deny: add duplicate skip entries for Cargo.lock version bumps
jasonhernandez Apr 2, 2026
f14e817
ci: install Go in CI builder for aws-lc-fips-sys
jasonhernandez Apr 2, 2026
ee2d552
chore: pin uuid to 1.19.0 to match main
jasonhernandez Apr 2, 2026
f50159b
fix: pin os_info, chrono-tz, serde_path_to_error to avoid CI regressions
jasonhernandez Apr 2, 2026
ebeb12b
crypto: swap openssl TLS features to rustls in 3 crates
jasonhernandez Apr 2, 2026
03b3e42
deny: add wrappers and skips for rustls ecosystem deps
jasonhernandez Apr 2, 2026
5ded6ae
environmentd: explicitly enable hyper-openssl client-legacy feature
jasonhernandez Apr 2, 2026
daa4555
deny: add CDLA-Permissive-2.0 to about.toml for webpki-roots
jasonhernandez Apr 2, 2026
dc0ab22
crypto: swap reqwest/hyper-tls to rustls in 3 crates
jasonhernandez Apr 2, 2026
523bc53
doc: update aws-util docs to reflect rustls policy change
jasonhernandez Apr 2, 2026
a67e759
environmentd: explicitly enable hyper-openssl client-legacy feature
jasonhernandez Apr 2, 2026
a172e9c
fix: enable default-https-client for aws-config and pin os_info
jasonhernandez Apr 2, 2026
e2a8aca
adapter: WIP compile-time gating of LD and segment behind telemetry f…
jasonhernandez Apr 2, 2026
e239160
adapter,environmentd,balancerd,ore: compile-time gate telemetry SDKs …
jasonhernandez Apr 2, 2026
9f11afd
doc: document telemetry SDK compile-time exclusion for FIPS
jasonhernandez Apr 2, 2026
b13547d
auth: migrate mz-auth SCRAM-SHA256 crypto from openssl to aws-lc-rs
jasonhernandez Apr 2, 2026
3849278
Console OIDC generate token (#35609)
leedqin Apr 2, 2026
3022e10
Add username to postgresql instructions (#35841)
SangJunBak Apr 2, 2026
71feb0b
crypto: migrate sha2/hmac/subtle usage to aws-lc-rs across 11 crates
jasonhernandez Apr 2, 2026
e09ad35
crypto: migrate Tier 3-4 leaf crates from openssl/native-tls to aws-l…
jasonhernandez Apr 2, 2026
f13c220
environmentd: migrate test TLS infrastructure from openssl to rcgen+r…
jasonhernandez Apr 2, 2026
59bf89a
tests: migrate TLS test call sites from openssl to rustls
jasonhernandez Apr 2, 2026
4eec3e8
tests: restore cert reloading assertions and fix TLS test helpers
jasonhernandez Apr 2, 2026
5c1142c
tls-util: migrate mz-tls-util from openssl to rustls
jasonhernandez Apr 3, 2026
0fa1b3a
ore,server-core,pgwire,balancerd,environmentd: migrate TLS from opens…
jasonhernandez Apr 3, 2026
8891cd4
fix: address CI lint failures
jasonhernandez Apr 3, 2026
7b52804
tests: fix JWT key format — use RSA keypair instead of CA's ECDSA key
jasonhernandez Apr 3, 2026
b109bd0
tests: fix JWT key usage — use public key for decoding, add missing j…
jasonhernandez Apr 3, 2026
0197fe6
tests: fix remaining auth test failures
jasonhernandez Apr 3, 2026
43a402f
tests: fix last UnknownIssuer assertion and update outdated comments
jasonhernandez Apr 3, 2026
ce31f72
ci: trigger fresh build on upstream branch
jasonhernandez Apr 3, 2026
4b076bd
crypto: install aws-lc-rs as the process-wide default CryptoProvider
jasonhernandez Apr 3, 2026
409f191
Revert "crypto: install aws-lc-rs as the process-wide default CryptoP…
jasonhernandez Apr 3, 2026
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
2,899 changes: 1,629 additions & 1,270 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions about.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ accepted = [
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"CC0-1.0",
"CDLA-Permissive-2.0",
"0BSD",
"BSD-2-Clause",
"BSD-3-Clause",
Expand Down
14 changes: 14 additions & 0 deletions bin/lint-fips-containers
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.
#
# lint-fips-containers -- audit container definitions for FIPS compliance gaps

exec "$(dirname "$0")"/pyactivate -m materialize.cli.lint_fips_containers "$@"
14 changes: 14 additions & 0 deletions bin/lint-openssl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.
#
# lint-openssl -- detect OpenSSL usage across the codebase

exec "$(dirname "$0")"/pyactivate -m materialize.cli.lint_openssl "$@"
6 changes: 6 additions & 0 deletions ci/builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ RUN gpg --dearmor < nodesource.asc > /etc/apt/keyrings/nodesource.gpg \
&& npm install -g corepack \
&& corepack enable

# Install Go, required by aws-lc-fips-sys to build the FIPS-validated
# BoringSSL module. Activated when cargo builds with --all-features (which
# enables the mz-ore `fips` feature). Go 1.18+ is required.
RUN curl -fsSL https://go.dev/dl/go1.24.2.linux-$ARCH_GO.tar.gz | tar -C /usr/local -xzf -
ENV PATH="/usr/local/go/bin:${PATH}"

RUN curl -fsSL https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.linux.$ARCH_GCC.tar.xz > shellcheck.tar.xz \
&& tar -xJf shellcheck.tar.xz -C /usr/local/bin --strip-components 1 shellcheck-v0.11.0/shellcheck \
&& rm shellcheck.tar.xz \
Expand Down
32 changes: 25 additions & 7 deletions console/src/components/ConnectInstructions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,35 @@ import TerminalIcon from "~/svg/Terminal";

import { CopyableBox, TabbedCodeBlock } from "./copyableComponents";

export interface ConnectInstructionsProps extends BoxProps {
/** The user string to display. Falls back to user.email if not provided. */
userStr?: string;
/** Frontegg user object. Required for cloud mode. */
user?: User;
/** Override the environmentd address (host:port). */
environmentdAddress?: string;
/** Override the query params in the psql connection string. */
psqlQueryParams?: string;
}

const ConnectInstructions = ({
user,
...props
}: BoxProps & { userStr: string | undefined; user: User }): JSX.Element => {
}: ConnectInstructionsProps): JSX.Element => {
const [currentEnvironment] = useAtom(currentEnvironmentState);
const { clusterName } = useParams<ClusterDetailParams>();

if (!currentEnvironment || currentEnvironment.state !== "enabled") {
const envAddress =
props.environmentdAddress ??
(currentEnvironment?.state === "enabled"
? currentEnvironment.sqlAddress
: undefined);

if (!envAddress) {
return <Spinner />;
}

const userStr = props.userStr || user.email;

const environmentdAddress = currentEnvironment.sqlAddress;
const userStr = props.userStr || user?.email || "";

const defaultClusterOptionString = clusterName
? `&options=--cluster%3D${clusterName}`
Expand All @@ -43,11 +58,14 @@ const ConnectInstructions = ({
// attacks, but that mode requires specifying `sslrootcert=/path/to/cabundle`,
// and that path varies by platform. So instead we use `require`, which is
// at least better than the default of `prefer`.
const queryParams =
props.psqlQueryParams ?? `sslmode=require${defaultClusterOptionString}`;

const psqlCopyString = `psql "postgres://${encodeURIComponent(
userStr,
)}@${environmentdAddress}/materialize?sslmode=require${defaultClusterOptionString}"`;
)}@${envAddress}/materialize?${queryParams}"`;

const [host, port] = environmentdAddress.split(":");
const [host, port] = envAddress.split(":");
return (
<TabbedCodeBlock
data-testid="connection-options"
Expand Down
96 changes: 96 additions & 0 deletions console/src/components/OidcConnectModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

import {
ModalBody,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
Text,
useTheme,
VStack,
} from "@chakra-ui/react";
import React from "react";

import ConnectInstructions from "~/components/ConnectInstructions";
import { SecretCopyableBox } from "~/components/copyableComponents";
import { Modal } from "~/components/Modal";
import { useAuth } from "~/external-library-wrappers/oidc";
import { MaterializeTheme } from "~/theme";
import { obfuscateSecret } from "~/utils/format";

const OIDC_USERNAME_PLACEHOLDER = "<your_oidc_username>";

const OidcConnectModal = ({
onClose,
isOpen,
}: {
onClose: () => void;
isOpen: boolean;
}) => {
const { colors } = useTheme<MaterializeTheme>();
const auth = useAuth();
const idToken = auth.user?.id_token;

const obfuscated = idToken ? obfuscateSecret(idToken) : "";

// Default to the console's hostname, but customers may need to adjust
// if Materialize is exposed on a different host behind a load balancer.
const defaultSqlAddress = `${window.location.hostname}:6875`;

return (
<Modal size="3xl" isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader fontWeight="500">Connect To Materialize</ModalHeader>
<ModalCloseButton />
<ModalBody pt="2" pb="6" alignItems="stretch">
<Text
fontSize="sm"
whiteSpace="normal"
color={colors.foreground.secondary}
>
Use the details below to connect to Materialize. The host and port
shown are defaults and may need to be adjusted for your deployment.
When prompted for a password, paste the ID token.
</Text>
{idToken ? (
<VStack alignItems="stretch" spacing={6} mt="4">
<ConnectInstructions
userStr={OIDC_USERNAME_PLACEHOLDER}
environmentdAddress={defaultSqlAddress}
psqlQueryParams="options=--oidc_auth_enabled%3Dtrue"
/>
<VStack alignItems="stretch" spacing={2}>
<Text textStyle="heading-xs">ID Token</Text>
<SecretCopyableBox
label="idToken"
contents={idToken}
obfuscatedContent={obfuscated}
overflow="hidden"
minWidth={0}
/>
<Text fontSize="sm" color={colors.foreground.secondary}>
When prompted for a password, paste this ID token.
</Text>
</VStack>
</VStack>
) : (
<Text fontSize="sm" mt="4">
No ID token available. Please sign in again.
</Text>
)}
</ModalBody>
</ModalContent>
</Modal>
);
};

export default OidcConnectModal;
16 changes: 16 additions & 0 deletions console/src/layouts/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import useResizeObserver from "use-resize-observer";
import ConnectModal from "~/components/ConnectModal";
import FreeTrialNotice from "~/components/FreeTrialNotice";
import { MaterializeLogo } from "~/components/MaterializeLogo";
import OidcConnectModal from "~/components/OidcConnectModal";
import { AppConfigSwitch } from "~/config/AppConfigSwitch";
import EnvironmentSelectField from "~/layouts/EnvironmentSelect";
import ProfileDropdown from "~/layouts/ProfileDropdown";
Expand Down Expand Up @@ -277,6 +278,21 @@ export const NavBar = ({ isCollapsed }: NavBarProps) => {
</HideIfEnvironmentDisabled>
)
}
selfManagedConfigElement={({ appConfig }) =>
appConfig.authMode === "Oidc" ? (
<HideIfEnvironmentDisabled>
<ConnectMenuItem
isCollapsed={isCollapsed}
width="100%"
onClick={onOpenConnectModal}
/>
<OidcConnectModal
onClose={onCloseConnectModal}
isOpen={isConnectModalOpen}
/>
</HideIfEnvironmentDisabled>
) : null
}
/>
)}
<ProfileDropdown
Expand Down
16 changes: 16 additions & 0 deletions console/src/layouts/NavBar/NavMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Location, useLocation } from "react-router-dom";
import { useCanViewUsage } from "~/api/auth";
import ConnectModal from "~/components/ConnectModal";
import FreeTrialNotice from "~/components/FreeTrialNotice";
import OidcConnectModal from "~/components/OidcConnectModal";
import { AppConfigSwitch, CloudRuntimeConfig } from "~/config/AppConfigSwitch";
import { useFlags } from "~/hooks/useFlags";
import { useIsSuperUser } from "~/hooks/useIsSuperUser";
Expand Down Expand Up @@ -305,6 +306,21 @@ const NavMenuMobile = (props: {
</HideIfEnvironmentDisabled>
)
}
selfManagedConfigElement={({ appConfig }) =>
appConfig.authMode === "Oidc" ? (
<HideIfEnvironmentDisabled>
<ConnectMenuItem
width="100%"
onClick={onOpenConnectModal}
mb={{ base: 0, lg: 6 }}
/>
<OidcConnectModal
onClose={onCloseConnectModal}
isOpen={isConnectModalOpen}
/>
</HideIfEnvironmentDisabled>
) : null
}
/>
</VStack>
</VStack>
Expand Down
3 changes: 2 additions & 1 deletion console/src/queries/frontegg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
UserApiToken,
} from "~/api/frontegg/types";
import { User } from "~/external-library-wrappers/frontegg";
import { obfuscateSecret } from "~/utils/format";

export const fronteggQueryKeys = {
all: () => buildGlobalQueryKey("frontegg"),
Expand Down Expand Up @@ -92,7 +93,7 @@ function formatAppPassword({ clientId, secret }: NewApiToken) {
const formattedClientId = clientId.replaceAll("-", "");
const formattedSecret = secret.replaceAll("-", "");
const password = `mzp_${formattedClientId}${formattedSecret}`;
const obfuscatedPassword = `${new Array(password.length).fill("*").join("")}`;
const obfuscatedPassword = obfuscateSecret(password);
return { password, obfuscatedPassword };
}

Expand Down
5 changes: 5 additions & 0 deletions console/src/utils/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { IPostgresInterval } from "postgres-interval";

import { pluralize } from "~/util";

/** Creates an obfuscated string of asterisks matching the length of the input. */
export function obfuscateSecret(secret: string): string {
return "*".repeat(secret.length);
}

const kilobyte = 1024n;
const megabyte = 1024n * 1024n;
const gigabyte = 1024n * 1024n * 1024n;
Expand Down
Loading
Loading