# infra/relay/src/environments/EnvironmentConnector.ts · screen/t3code-personal

[View on GitCafe](https://git.cafe/screen/t3code-personal/blob/c9a0e8a119271765196dec38ef91395713da4213/infra/relay/src/environments/EnvironmentConnector.ts)

Repository: [screen/t3code-personal](https://git.cafe/screen/t3code-personal)

Visibility: public

Requested revision: c9a0e8a119271765196dec38ef91395713da4213

Requested commit: c9a0e8a119271765196dec38ef91395713da4213

Commit: c9a0e8a119271765196dec38ef91395713da4213

Blob: 9201f814661e68ef043488cd9b34f430804449fb

Size: 24763 bytes

[Immutable source](https://git.cafe/screen/t3code-personal/blob/c9a0e8a119271765196dec38ef91395713da4213/infra/relay/src/environments/EnvironmentConnector.ts?format=markdown)

```
import {
  EnvironmentHttpBadRequestError,
  EnvironmentHttpConflictError,
  EnvironmentHttpForbiddenError,
  EnvironmentHttpInternalServerError,
  EnvironmentHttpUnauthorizedError,
} from "@t3tools/contracts";
import { makeEnvironmentHttpApiClient } from "@t3tools/client-runtime/rpc";
import {
  RelayCloudEnvironmentHealthProofPayload,
  RelayEnvironmentHealthResponse,
  RelayEnvironmentHealthResponseProofPayload,
  RelayEnvironmentMintResponse,
  RelayEnvironmentMintResponseProofPayload,
  RelayCloudMintCredentialProofPayload,
  RelayEnvironmentConnectNotAuthorizedReason,
  type RelayEnvironmentConnectResponse,
  type RelayEnvironmentStatusResponse,
} from "@t3tools/contracts/relay";
import {
  normalizeRelayIssuer,
  RELAY_HEALTH_REQUEST_TYP,
  RELAY_HEALTH_RESPONSE_TYP,
  RELAY_MINT_REQUEST_TYP,
  RELAY_MINT_RESPONSE_TYP,
  signRelayJwt,
  verifyRelayJwt,
} from "@t3tools/shared/relayJwt";
import { stableStringify } from "@t3tools/shared/relaySigning";
import * as Context from "effect/Context";
import * as Crypto from "effect/Crypto";
import * as DateTime from "effect/DateTime";
import * as Duration from "effect/Duration";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Redacted from "effect/Redacted";
import * as Schema from "effect/Schema";
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
import * as HttpClient from "effect/unstable/http/HttpClient";
import * as HttpClientError from "effect/unstable/http/HttpClientError";

import * as EnvironmentLinks from "./EnvironmentLinks.ts";
import * as ManagedEndpointAllocations from "./ManagedEndpointAllocations.ts";
import * as RelayConfiguration from "../Config.ts";
import { isManagedEndpointHostname } from "../deploymentConfig.ts";

function environmentConnectNotAuthorizedReasonMessage(
  reason: RelayEnvironmentConnectNotAuthorizedReason,
): string {
  switch (reason) {
    case "client_proof_key_thumbprint_missing":
      return "the client proof key thumbprint is missing";
    case "environment_link_not_found":
      return "no active environment link was found";
    case "endpoint_provider_not_managed":
      return "the linked endpoint is not relay-managed";
    case "managed_endpoint_allocation_not_found":
      return "no managed endpoint allocation was found";
    case "managed_endpoint_base_domain_not_configured":
      return "the managed endpoint base domain is not configured";
    case "managed_endpoint_allocation_not_ready":
      return "the managed endpoint allocation is incomplete";
    case "managed_endpoint_hostname_invalid":
      return "the managed endpoint hostname is invalid";
    case "managed_endpoint_mismatch":
      return "the linked endpoint does not match its managed allocation";
  }
}

export class EnvironmentConnectNotAuthorized extends Schema.TaggedError<EnvironmentConnectNotAuthorized>()(
  "EnvironmentConnectNotAuthorized",
  {
    environmentId: Schema.String,
    operation: Schema.Literals(["connect", "status"]),
    reason: RelayEnvironmentConnectNotAuthorizedReason,
  },
) {
  override get message(): string {
    return `Environment '${this.environmentId}' is not authorized for ${this.operation}: ${environmentConnectNotAuthorizedReasonMessage(this.reason)}`;
  }
}

export class EnvironmentMintRequestFailed extends Schema.TaggedError<EnvironmentMintRequestFailed>()(
  "EnvironmentMintRequestFailed",
  {
    environmentId: Schema.String,
    operation: Schema.Literals(["connect", "status"]),
    cause: Schema.Defect(),
  },
) {
  override get message(): string {
    return `Environment '${this.environmentId}' ${this.operation} request failed`;
  }
}

export class EnvironmentMintRequestTimedOut extends Schema.TaggedError<EnvironmentMintRequestTimedOut>()(
  "EnvironmentMintRequestTimedOut",
  {
    environmentId: Schema.String,
    timeoutMs: Schema.Number,
  },
) {
  override get message(): string {
    return `Environment '${this.environmentId}' mint request timed out after ${this.timeoutMs}ms`;
  }
}

export class EnvironmentMintResponseInvalid extends Schema.TaggedError<EnvironmentMintResponseInvalid>()(
  "EnvironmentMintResponseInvalid",
  {
    environmentId: Schema.String,
    operation: Schema.Literals(["connect", "status"]),
  },
) {
  override get message(): string {
    return `Environment '${this.environmentId}' returned an invalid ${this.operation} response`;
  }
}

export type EnvironmentConnectorError =
  | EnvironmentConnectNotAuthorized
  | EnvironmentMintRequestFailed
  | EnvironmentMintRequestTimedOut
  | EnvironmentMintResponseInvalid
  | EnvironmentLinks.EnvironmentLinkLookupPersistenceError
  | ManagedEndpointAllocations.ManagedEndpointAllocationPersistenceError;

export const ENVIRONMENT_MINT_REQUEST_TIMEOUT_MS = 10_000;
const ENVIRONMENT_HEALTH_CLOCK_SKEW_MILLIS = 60 * 1_000;

export class EnvironmentConnector extends Context.Service<
  EnvironmentConnector,
  {
    readonly connect: (input: {
      readonly userId: string;
      readonly environmentId: string;
      readonly clientProofKeyThumbprint: string;
      readonly deviceId?: string;
    }) => Effect.Effect<RelayEnvironmentConnectResponse, EnvironmentConnectorError>;
    readonly status: (input: {
      readonly userId: string;
      readonly environmentId: string;
    }) => Effect.Effect<RelayEnvironmentStatusResponse, EnvironmentConnectorError>;
  }
>()("t3code-relay/environments/EnvironmentConnector") {}

const decodeMintResponseProof = Schema.decodeUnknownEffect(
  RelayEnvironmentMintResponseProofPayload,
);
const decodeHealthResponseProof = Schema.decodeUnknownEffect(
  RelayEnvironmentHealthResponseProofPayload,
);
const isEnvironmentHealthError = Schema.is(
  Schema.Union([
    EnvironmentHttpBadRequestError,
    EnvironmentHttpUnauthorizedError,
    EnvironmentHttpForbiddenError,
    EnvironmentHttpConflictError,
    EnvironmentHttpInternalServerError,
  ]),
);

function environmentHealthRequestFailureMessage(cause: unknown): string {
  return isEnvironmentHealthError(cause)
    ? `Managed endpoint health request failed: ${cause.message}`
    : "Managed endpoint health request failed.";
}

function environmentHealthRequestFailureReason(cause: unknown): string {
  if (isEnvironmentHealthError(cause)) {
    return cause._tag;
  }
  if (HttpClientError.isHttpClientError(cause)) {
    return cause.reason._tag;
  }
  if (Schema.isSchemaError(cause)) {
    return "SchemaError";
  }
  return cause instanceof Error && cause.name ? cause.name : "Unknown";
}

const currentTraceId = Effect.currentSpan.pipe(
  Effect.map((span) => span.traceId),
  Effect.orElseSucceed(() => "unavailable"),
);

const withoutRedirects = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
  effect.pipe(Effect.provideService(FetchHttpClient.RequestInit, { redirect: "manual" }));

const verifyWithEnvironmentKeys = Effect.fnUntraced(function* <A, E>(input: {
  readonly token: string;
  readonly typ: string;
  readonly issuer: string;
  readonly audience: string;
  readonly nowEpochSeconds: number;
  readonly environmentPublicKeys: ReadonlyArray<string>;
  readonly decodePayload: (input: unknown) => Effect.Effect<A, E>;
}) {
  const { decodePayload, ...rest } = input;
  for (const publicKey of input.environmentPublicKeys) {
    const proof = yield* verifyRelayJwt({ ...rest, publicKey }).pipe(
      Effect.flatMap(decodePayload),
      Effect.option,
    );
    if (Option.isSome(proof)) {
      return proof.value;
    }
    // A linked environment can have rotated keys; try the remaining active keys.
  }
  return null;
});

function verifyEnvironmentResponse(input: {
  readonly response: RelayEnvironmentMintResponse;
  readonly environmentId: string;
  readonly requestNonce: string;
  readonly clientProofKeyThumbprint: string;
  readonly environmentPublicKeys: ReadonlyArray<string>;
  readonly relayIssuer: string;
  readonly nowEpochSeconds: number;
}) {
  return verifyWithEnvironmentKeys({
    token: input.response.proof,
    typ: RELAY_MINT_RESPONSE_TYP,
    issuer: `t3-env:${input.environmentId}`,
    audience: normalizeRelayIssuer(input.relayIssuer),
    nowEpochSeconds: input.nowEpochSeconds,
    environmentPublicKeys: input.environmentPublicKeys,
    decodePayload: decodeMintResponseProof,
  }).pipe(
    Effect.map(
      (proof) =>
        proof !== null &&
        proof.environmentId === input.environmentId &&
        proof.requestNonce === input.requestNonce &&
        proof.clientProofKeyThumbprint === input.clientProofKeyThumbprint &&
        proof.credential === input.response.credential &&
        Option.match(DateTime.make(input.response.expiresAt), {
          onNone: () => false,
          onSome: (expiresAt) => Math.floor(expiresAt.epochMilliseconds / 1_000) === proof.exp,
        }),
    ),
  );
}

function verifyEnvironmentHealthResponse(input: {
  readonly response: RelayEnvironmentHealthResponse;
  readonly environmentId: string;
  readonly requestNonce: string;
  readonly requestIssuedAt: DateTime.DateTime;
  readonly environmentPublicKeys: ReadonlyArray<string>;
  readonly relayIssuer: string;
  readonly now: DateTime.DateTime;
}) {
  return verifyWithEnvironmentKeys({
    token: input.response.proof,
    typ: RELAY_HEALTH_RESPONSE_TYP,
    issuer: `t3-env:${input.environmentId}`,
    audience: normalizeRelayIssuer(input.relayIssuer),
    nowEpochSeconds: Math.floor(input.now.epochMilliseconds / 1_000),
    environmentPublicKeys: input.environmentPublicKeys,
    decodePayload: decodeHealthResponseProof,
  }).pipe(
    Effect.map((proof) => {
      if (
        proof === null ||
        input.response.environmentId !== input.environmentId ||
        proof.environmentId !== input.environmentId ||
        proof.requestNonce !== input.requestNonce ||
        proof.status !== input.response.status ||
        proof.checkedAt !== input.response.checkedAt ||
        stableStringify(proof.descriptor) !== stableStringify(input.response.descriptor)
      ) {
        return false;
      }
      const checkedAt = DateTime.make(input.response.checkedAt);
      if (Option.isNone(checkedAt)) {
        return false;
      }
      return (
        checkedAt.value.epochMilliseconds >=
          input.requestIssuedAt.epochMilliseconds - ENVIRONMENT_HEALTH_CLOCK_SKEW_MILLIS &&
        checkedAt.value.epochMilliseconds <=
          input.now.epochMilliseconds + ENVIRONMENT_HEALTH_CLOCK_SKEW_MILLIS
      );
    }),
  );
}

const make = Effect.gen(function* () {
  const links = yield* EnvironmentLinks.EnvironmentLinks;
  const allocations = yield* ManagedEndpointAllocations.ManagedEndpointAllocations;
  const settings = yield* RelayConfiguration.RelayConfiguration;
  const httpClient = yield* HttpClient.HttpClient;
  const crypto = yield* Crypto.Crypto;
  const relayIssuer = normalizeRelayIssuer(settings.relayIssuer);
  const makeEnvironmentClient = (httpBaseUrl: string) =>
    makeEnvironmentHttpApiClient(httpBaseUrl).pipe(
      Effect.provideService(HttpClient.HttpClient, httpClient),
    );
  const resolveManagedEndpoint = Effect.fn("relay.environment_connector.resolve_managed_endpoint")(
    function* (input: {
      readonly operation: "connect" | "status";
      readonly link: EnvironmentLinks.RelayLinkedEnvironmentRecord;
      readonly allocation: ManagedEndpointAllocations.ManagedEndpointAllocation | null;
    }) {
      if (input.link.endpoint.providerKind !== "cloudflare_tunnel") {
        yield* Effect.annotateCurrentSpan({
          "relay.authorization.endpoint_provider_kind": input.link.endpoint.providerKind,
        });
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "endpoint_provider_not_managed",
        });
      }
      if (!input.allocation) {
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "managed_endpoint_allocation_not_found",
        });
      }
      const allocationAttributes = {
        "relay.authorization.allocation_hostname": input.allocation.hostname,
        "relay.authorization.allocation_has_ready_at": input.allocation.readyAt !== null,
        "relay.authorization.allocation_has_tunnel_id": input.allocation.tunnelId !== null,
        "relay.authorization.allocation_has_dns_record_id": input.allocation.dnsRecordId !== null,
      } as const;
      if (!settings.managedEndpointBaseDomain) {
        yield* Effect.annotateCurrentSpan(allocationAttributes);
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "managed_endpoint_base_domain_not_configured",
        });
      }
      if (
        input.allocation.readyAt === null ||
        input.allocation.tunnelId === null ||
        input.allocation.dnsRecordId === null
      ) {
        yield* Effect.annotateCurrentSpan(allocationAttributes);
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "managed_endpoint_allocation_not_ready",
        });
      }
      if (
        !isManagedEndpointHostname(input.allocation.hostname, settings.managedEndpointBaseDomain)
      ) {
        yield* Effect.annotateCurrentSpan({
          ...allocationAttributes,
          "relay.authorization.managed_endpoint_base_domain": settings.managedEndpointBaseDomain,
        });
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "managed_endpoint_hostname_invalid",
        });
      }
      const endpoint = ManagedEndpointAllocations.resolveReadyManagedEndpoint({
        allocation: input.allocation,
        baseDomain: settings.managedEndpointBaseDomain,
      });
      if (
        endpoint === null ||
        endpoint.httpBaseUrl !== input.link.endpoint.httpBaseUrl ||
        endpoint.wsBaseUrl !== input.link.endpoint.wsBaseUrl
      ) {
        yield* Effect.annotateCurrentSpan({
          ...allocationAttributes,
          "relay.authorization.linked_http_base_url": input.link.endpoint.httpBaseUrl,
          "relay.authorization.linked_ws_base_url": input.link.endpoint.wsBaseUrl,
          ...(endpoint
            ? {
                "relay.authorization.resolved_http_base_url": endpoint.httpBaseUrl,
                "relay.authorization.resolved_ws_base_url": endpoint.wsBaseUrl,
              }
            : {}),
        });
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.link.environmentId,
          operation: input.operation,
          reason: "managed_endpoint_mismatch",
        });
      }
      return endpoint;
    },
  );

  return EnvironmentConnector.of({
    status: Effect.fn("relay.environment_connector.status")(function* (input) {
      yield* Effect.annotateCurrentSpan({
        "relay.environment_id": input.environmentId,
        "relay.operation": "status",
      });
      const { link, allocation } = yield* Effect.all(
        {
          link: links.getForUser(input),
          allocation: allocations.get(input),
        },
        { concurrency: 2 },
      );
      if (!link) {
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.environmentId,
          operation: "status",
          reason: "environment_link_not_found",
        });
      }
      const endpoint = yield* resolveManagedEndpoint({
        operation: "status",
        link,
        allocation,
      });
      const now = yield* DateTime.now;
      const expiresAt = DateTime.add(now, { minutes: 2 });
      const nonce = yield* crypto.randomUUIDv4.pipe(
        Effect.mapError(
          (cause) =>
            new EnvironmentMintRequestFailed({
              environmentId: input.environmentId,
              operation: "status",
              cause,
            }),
        ),
      );
      const payload = {
        iss: relayIssuer,
        aud: `t3-env:${link.environmentId}`,
        sub: input.userId,
        jti: yield* crypto.randomUUIDv4.pipe(
          Effect.mapError(
            (cause) =>
              new EnvironmentMintRequestFailed({
                environmentId: input.environmentId,
                operation: "status",
                cause,
              }),
          ),
        ),
        iat: Math.floor(now.epochMilliseconds / 1_000),
        exp: Math.floor(expiresAt.epochMilliseconds / 1_000),
        environmentId: link.environmentId,
        nonce,
        scope: ["environment:status"],
      } satisfies RelayCloudEnvironmentHealthProofPayload;
      const proof = yield* signRelayJwt({
        privateKey: Redacted.value(settings.cloudMintPrivateKey),
        typ: RELAY_HEALTH_REQUEST_TYP,
        payload,
      }).pipe(
        Effect.mapError(
          (cause) =>
            new EnvironmentMintRequestFailed({
              environmentId: input.environmentId,
              operation: "status",
              cause,
            }),
        ),
      );
      const checkedAt = DateTime.formatIso(now);
      const traceId = yield* currentTraceId;
      const environmentClient = yield* makeEnvironmentClient(endpoint.httpBaseUrl);
      const responseOption = yield* environmentClient.connect.health({ payload: { proof } }).pipe(
        withoutRedirects,
        Effect.match({
          onFailure: (cause) => ({ _tag: "Failure" as const, cause }),
          onSuccess: (response) => ({ _tag: "Success" as const, response }),
        }),
        Effect.timeoutOption(Duration.millis(ENVIRONMENT_MINT_REQUEST_TIMEOUT_MS)),
      );
      if (Option.isNone(responseOption)) {
        yield* Effect.annotateCurrentSpan({
          "relay.environment_health.outcome": "timeout",
          "relay.environment_health.trace_id": traceId,
        });
        yield* Effect.logWarning("Managed endpoint health request timed out", {
          environmentId: link.environmentId,
          endpoint: endpoint.httpBaseUrl,
          traceId,
        });
        return {
          environmentId: link.environmentId,
          endpoint,
          status: "offline" as const,
          checkedAt,
          error: "Managed endpoint health request timed out.",
          traceId,
        };
      }
      if (responseOption.value._tag === "Failure") {
        const failureReason = environmentHealthRequestFailureReason(responseOption.value.cause);
        yield* Effect.annotateCurrentSpan({
          "relay.environment_health.outcome": "failure",
          "relay.environment_health.failure_reason": failureReason,
          "relay.environment_health.trace_id": traceId,
        });
        yield* Effect.logWarning("Managed endpoint health request failed", {
          environmentId: link.environmentId,
          endpoint: endpoint.httpBaseUrl,
          failureReason,
          traceId,
        });
        return {
          environmentId: link.environmentId,
          endpoint,
          status: "offline" as const,
          checkedAt,
          error: environmentHealthRequestFailureMessage(responseOption.value.cause),
          traceId,
        };
      }
      const decoded = responseOption.value.response;
      const verified = yield* verifyEnvironmentHealthResponse({
        response: decoded,
        environmentId: input.environmentId,
        requestNonce: nonce,
        requestIssuedAt: now,
        environmentPublicKeys: [link.environmentPublicKey],
        relayIssuer,
        now: yield* DateTime.now,
      });
      if (!verified) {
        return yield* new EnvironmentMintResponseInvalid({
          environmentId: input.environmentId,
          operation: "status",
        });
      }
      return {
        environmentId: link.environmentId,
        endpoint,
        status: "online" as const,
        checkedAt: decoded.checkedAt,
        descriptor: decoded.descriptor,
      };
    }),
    connect: Effect.fn("relay.environment_connector.connect")(function* (input) {
      yield* Effect.annotateCurrentSpan({
        "relay.environment_id": input.environmentId,
        "relay.operation": "connect",
        "relay.connect.has_device_id": input.deviceId !== undefined,
        ...(input.deviceId ? { "relay.mobile.device_id": input.deviceId } : {}),
      });
      if (input.clientProofKeyThumbprint.trim().length === 0) {
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.environmentId,
          operation: "connect",
          reason: "client_proof_key_thumbprint_missing",
        });
      }
      const { link, allocation } = yield* Effect.all(
        {
          link: links.getForUser(input),
          allocation: allocations.get(input),
        },
        { concurrency: 2 },
      );
      if (!link) {
        return yield* new EnvironmentConnectNotAuthorized({
          environmentId: input.environmentId,
          operation: "connect",
          reason: "environment_link_not_found",
        });
      }
      const endpoint = yield* resolveManagedEndpoint({
        operation: "connect",
        link,
        allocation,
      });
      const now = yield* DateTime.now;
      const expiresAt = DateTime.add(now, { minutes: 2 });
      const nonce = yield* crypto.randomUUIDv4.pipe(
        Effect.mapError(
          (cause) =>
            new EnvironmentMintRequestFailed({
              environmentId: input.environmentId,
              operation: "connect",
              cause,
            }),
        ),
      );
      const payload = {
        iss: relayIssuer,
        aud: `t3-env:${link.environmentId}`,
        sub: input.userId,
        jti: yield* crypto.randomUUIDv4.pipe(
          Effect.mapError(
            (cause) =>
              new EnvironmentMintRequestFailed({
                environmentId: input.environmentId,
                operation: "connect",
                cause,
              }),
          ),
        ),
        iat: Math.floor(now.epochMilliseconds / 1_000),
        exp: Math.floor(expiresAt.epochMilliseconds / 1_000),
        environmentId: link.environmentId,
        clientProofKeyThumbprint: input.clientProofKeyThumbprint,
        cnf: { jkt: input.clientProofKeyThumbprint },
        ...(input.deviceId ? { deviceId: input.deviceId } : {}),
        nonce,
        scope: ["environment:connect"],
      } satisfies RelayCloudMintCredentialProofPayload;
      const proof = yield* signRelayJwt({
        privateKey: Redacted.value(settings.cloudMintPrivateKey),
        typ: RELAY_MINT_REQUEST_TYP,
        payload,
      }).pipe(
        Effect.mapError(
          (cause) =>
            new EnvironmentMintRequestFailed({
              environmentId: input.environmentId,
              operation: "connect",
              cause,
            }),
        ),
      );
      const environmentClient = yield* makeEnvironmentClient(endpoint.httpBaseUrl);
      const decoded = yield* environmentClient.connect
        .t3MintCredential({ payload: { proof } })
        .pipe(
          withoutRedirects,
          Effect.mapError(
            (cause) =>
              new EnvironmentMintRequestFailed({
                environmentId: input.environmentId,
                operation: "connect",
                cause,
              }),
          ),
          Effect.timeoutOption(Duration.millis(ENVIRONMENT_MINT_REQUEST_TIMEOUT_MS)),
          Effect.flatMap(
            Option.match({
              onNone: () =>
                Effect.fail(
                  new EnvironmentMintRequestTimedOut({
                    environmentId: input.environmentId,
                    timeoutMs: ENVIRONMENT_MINT_REQUEST_TIMEOUT_MS,
                  }),
                ),
              onSome: Effect.succeed,
            }),
          ),
        );
      const verified = yield* verifyEnvironmentResponse({
        response: decoded,
        environmentId: input.environmentId,
        requestNonce: nonce,
        clientProofKeyThumbprint: input.clientProofKeyThumbprint,
        environmentPublicKeys: [link.environmentPublicKey],
        relayIssuer,
        nowEpochSeconds: Math.floor(now.epochMilliseconds / 1_000),
      });
      if (!verified) {
        return yield* new EnvironmentMintResponseInvalid({
          environmentId: input.environmentId,
          operation: "connect",
        });
      }
      return {
        environmentId: link.environmentId,
        endpoint,
        credential: decoded.credential,
        expiresAt: decoded.expiresAt,
      };
    }),
  });
});

export const layer = Layer.effect(EnvironmentConnector, make);

```
