diff --git a/.env.dev.example b/.env.dev.example new file mode 100644 index 0000000000..f67488c23e --- /dev/null +++ b/.env.dev.example @@ -0,0 +1,150 @@ +# Keys +# Required key for platform encryption/decryption ops +# THIS IS A SAMPLE ENCRYPTION KEY AND SHOULD NEVER BE USED FOR PRODUCTION +ENCRYPTION_KEY=VVHnGZ0w98WLgISK4XSJcagezuG6EWRFTk48KE4Y5Mw= + +# JWT +# Required secrets to sign JWT tokens +# THIS IS A SAMPLE AUTH_SECRET KEY AND SHOULD NEVER BE USED FOR PRODUCTION +AUTH_SECRET=5lrMXKKWCVocS/uerPsl7V+TX/aaUaI7iDkgl3tSmLE= + +# Postgres creds +POSTGRES_PASSWORD=infisical +POSTGRES_USER=infisical +POSTGRES_DB=infisical + +# Required +DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} + +# Redis +REDIS_URL=redis://redis:6379 + +# Website URL +# Required +SITE_URL=http://localhost:8080 + +# Mail/SMTP +SMTP_HOST= +SMTP_PORT= +SMTP_FROM_ADDRESS= +SMTP_FROM_NAME= +SMTP_USERNAME= +SMTP_PASSWORD= + +# Integration +# Optional only if integration is used +CLIENT_ID_HEROKU= +CLIENT_ID_VERCEL= +CLIENT_ID_NETLIFY= +CLIENT_ID_GITHUB= +CLIENT_ID_GITHUB_APP= +CLIENT_SLUG_GITHUB_APP= +CLIENT_ID_GITLAB= +CLIENT_ID_BITBUCKET= +CLIENT_SECRET_HEROKU= +CLIENT_SECRET_VERCEL= +CLIENT_SECRET_NETLIFY= +CLIENT_SECRET_GITHUB= +CLIENT_SECRET_GITHUB_APP= +CLIENT_SECRET_GITLAB= +CLIENT_SECRET_BITBUCKET= +CLIENT_SLUG_VERCEL= + +CLIENT_PRIVATE_KEY_GITHUB_APP= +CLIENT_APP_ID_GITHUB_APP= + +# Sentry (optional) for monitoring errors +SENTRY_DSN= + +# Infisical Cloud-specific configs +# Ignore - Not applicable for self-hosted version +POSTHOG_HOST= +POSTHOG_PROJECT_API_KEY= + +# SSO-specific variables +CLIENT_ID_GOOGLE_LOGIN= +CLIENT_SECRET_GOOGLE_LOGIN= + +CLIENT_ID_GITHUB_LOGIN= +CLIENT_SECRET_GITHUB_LOGIN= + +CLIENT_ID_GITLAB_LOGIN= +CLIENT_SECRET_GITLAB_LOGIN= + +CAPTCHA_SECRET= + +NEXT_PUBLIC_CAPTCHA_SITE_KEY= + +OTEL_TELEMETRY_COLLECTION_ENABLED=false +OTEL_EXPORT_TYPE=prometheus +OTEL_EXPORT_OTLP_ENDPOINT= +OTEL_OTLP_PUSH_INTERVAL= + +OTEL_COLLECTOR_BASIC_AUTH_USERNAME= +OTEL_COLLECTOR_BASIC_AUTH_PASSWORD= + +PLAIN_API_KEY= +PLAIN_WISH_LABEL_IDS= + +SSL_CLIENT_CERTIFICATE_HEADER_KEY= + +ENABLE_MSSQL_SECRET_ROTATION_ENCRYPT=true + +# App Connections + +# aws assume-role connection +INF_APP_CONNECTION_AWS_ACCESS_KEY_ID= +INF_APP_CONNECTION_AWS_SECRET_ACCESS_KEY= + +# github oauth connection +INF_APP_CONNECTION_GITHUB_OAUTH_CLIENT_ID= +INF_APP_CONNECTION_GITHUB_OAUTH_CLIENT_SECRET= + +#github app connection +INF_APP_CONNECTION_GITHUB_APP_CLIENT_ID= +INF_APP_CONNECTION_GITHUB_APP_CLIENT_SECRET= +INF_APP_CONNECTION_GITHUB_APP_PRIVATE_KEY= +INF_APP_CONNECTION_GITHUB_APP_SLUG= +INF_APP_CONNECTION_GITHUB_APP_ID= + +#gitlab app connection +INF_APP_CONNECTION_GITLAB_OAUTH_CLIENT_ID= +INF_APP_CONNECTION_GITLAB_OAUTH_CLIENT_SECRET= + +#github radar app connection +INF_APP_CONNECTION_GITHUB_RADAR_APP_CLIENT_ID= +INF_APP_CONNECTION_GITHUB_RADAR_APP_CLIENT_SECRET= +INF_APP_CONNECTION_GITHUB_RADAR_APP_PRIVATE_KEY= +INF_APP_CONNECTION_GITHUB_RADAR_APP_SLUG= +INF_APP_CONNECTION_GITHUB_RADAR_APP_ID= +INF_APP_CONNECTION_GITHUB_RADAR_APP_WEBHOOK_SECRET= + +#gcp app connection +INF_APP_CONNECTION_GCP_SERVICE_ACCOUNT_CREDENTIAL= + +# azure app connections +INF_APP_CONNECTION_AZURE_APP_CONFIGURATION_CLIENT_ID= +INF_APP_CONNECTION_AZURE_APP_CONFIGURATION_CLIENT_SECRET= + +INF_APP_CONNECTION_AZURE_KEY_VAULT_CLIENT_ID= +INF_APP_CONNECTION_AZURE_KEY_VAULT_CLIENT_SECRET= + +INF_APP_CONNECTION_AZURE_CLIENT_SECRETS_CLIENT_ID= +INF_APP_CONNECTION_AZURE_CLIENT_SECRETS_CLIENT_SECRET= + +INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_ID= +INF_APP_CONNECTION_AZURE_DEVOPS_CLIENT_SECRET= + +# heroku app connection +INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_ID= +INF_APP_CONNECTION_HEROKU_OAUTH_CLIENT_SECRET= + +# datadog +SHOULD_USE_DATADOG_TRACER= +DATADOG_PROFILING_ENABLED= +DATADOG_ENV= +DATADOG_SERVICE= +DATADOG_HOSTNAME= + +# kubernetes +KUBERNETES_AUTO_FETCH_SERVICE_ACCOUNT_TOKEN=false diff --git a/.env.example b/.env.example index 9da28e5282..489aa292cb 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ # Keys # Required key for platform encryption/decryption ops # THIS IS A SAMPLE ENCRYPTION KEY AND SHOULD NEVER BE USED FOR PRODUCTION -ENCRYPTION_KEY=VVHnGZ0w98WLgISK4XSJcagezuG6EWRFTk48KE4Y5Mw= +ENCRYPTION_KEY=f13dbc92aaaf86fa7cb0ed8ac3265f47 # JWT # Required secrets to sign JWT tokens @@ -21,7 +21,7 @@ REDIS_URL=redis://redis:6379 # Website URL # Required -SITE_URL=http://localhost:8080 +SITE_URL=http://localhost:80 # Mail/SMTP SMTP_HOST= diff --git a/.github/workflows/release-k8-operator-helm.yml b/.github/workflows/release-k8-operator-helm.yml deleted file mode 100644 index 7a9d867dd7..0000000000 --- a/.github/workflows/release-k8-operator-helm.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Release K8 Operator Helm Chart -on: - workflow_dispatch: - -jobs: - test-helm: - name: Test Helm Chart - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Set up Helm - uses: azure/setup-helm@v4.2.0 - with: - version: v3.17.0 - - - uses: actions/setup-python@v5.3.0 - with: - python-version: "3.x" - check-latest: true - - - name: Set up chart-testing - uses: helm/chart-testing-action@v2.7.0 - - - name: Run chart-testing (lint) - run: ct lint --config ct.yaml --charts helm-charts/secrets-operator - - - name: Create kind cluster - uses: helm/kind-action@v1.12.0 - - - name: Run chart-testing (install) - run: ct install --config ct.yaml --charts helm-charts/secrets-operator - - release-helm: - name: Release Helm Chart - needs: test-helm - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install Helm - uses: azure/setup-helm@v3 - with: - version: v3.10.0 - - - name: Install python - uses: actions/setup-python@v4 - - - name: Install Cloudsmith CLI - run: pip install --upgrade cloudsmith-cli - - - name: Build and push helm package to CloudSmith - run: cd helm-charts && sh upload-k8s-operator-cloudsmith.sh - env: - CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }} diff --git a/.github/workflows/release_docker_k8_operator.yaml b/.github/workflows/release_docker_k8_operator.yaml deleted file mode 100644 index 81472bf88f..0000000000 --- a/.github/workflows/release_docker_k8_operator.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: Release K8 Operator Docker Image -on: - push: - tags: - - "infisical-k8-operator/v*.*.*" - -permissions: - contents: write - pull-requests: write - -jobs: - release-image: - name: Generate Helm Chart PR - runs-on: ubuntu-latest - outputs: - pr_number: ${{ steps.create-pr.outputs.pull-request-number }} - steps: - - name: Extract version from tag - id: extract_version - run: echo "::set-output name=version::${GITHUB_REF_NAME#infisical-k8-operator/}" - - - name: Checkout code - uses: actions/checkout@v2 - - # Dependency for helm generation - - name: Install Helm - uses: azure/setup-helm@v3 - with: - version: v3.10.0 - - # Dependency for helm generation - - name: Install Go - uses: actions/setup-go@v4 - with: - go-version: 1.21 - - # Install binaries for helm generation - - name: Install dependencies - working-directory: k8-operator - run: | - make helmify - make kustomize - make controller-gen - - - name: Generate Helm Chart - working-directory: k8-operator - run: make helm VERSION=${{ steps.extract_version.outputs.version }} - - - name: Debug - Check file changes - run: | - echo "Current git status:" - git status - echo "" - echo "Modified files:" - git diff --name-only - - # If there is no diff, exit with error. Version should always be changed, so if there is no diff, something is wrong and we should exit. - if [ -z "$(git diff --name-only)" ]; then - echo "No helm changes or version changes. Invalid release detected, Exiting." - exit 1 - fi - - - name: Create Helm Chart PR - id: create-pr - uses: peter-evans/create-pull-request@v5 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: "Update Helm chart to version ${{ steps.extract_version.outputs.version }}" - committer: GitHub - author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> - branch: helm-update-${{ steps.extract_version.outputs.version }} - delete-branch: true - title: "Update Helm chart to version ${{ steps.extract_version.outputs.version }}" - body: | - This PR updates the Helm chart to version `${{ steps.extract_version.outputs.version }}`. - Additionally the helm chart has been updated to match the latest operator code changes. - - Associated Release Workflow: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - - Once you have approved this PR, you can trigger the helm release workflow manually. - base: main - - - name: 🔧 Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: 🔧 Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: 🐋 Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - id: docker_build - uses: docker/build-push-action@v2 - with: - context: k8-operator - push: true - platforms: linux/amd64,linux/arm64 - tags: | - infisical/kubernetes-operator:latest - infisical/kubernetes-operator:${{ steps.extract_version.outputs.version }} diff --git a/.github/workflows/run-backend-bdd-tests.yml b/.github/workflows/run-backend-bdd-tests.yml index 7b54aa44e8..df09632978 100644 --- a/.github/workflows/run-backend-bdd-tests.yml +++ b/.github/workflows/run-backend-bdd-tests.yml @@ -47,10 +47,13 @@ jobs: - name: Output .env file and enable feature flags for BDD tests run: | - cp .env.example .env + cp .env.dev.example .env echo "ACME_DEVELOPMENT_MODE=true" >> .env echo "ACME_DEVELOPMENT_HTTP01_CHALLENGE_HOST_OVERRIDES={\"localhost\": \"host.docker.internal:8087\", \"infisical.com\": \"host.docker.internal:8087\", \"example.com\": \"host.docker.internal:8087\"}" >> .env echo "BDD_NOCK_API_ENABLED=true" >> .env + # use Technitium DNS server for BDD tests + echo "ACME_DNS_RESOLVE_RESOLVER_SERVERS_HOST_ENABLED=true" >> .env + echo "ACME_DNS_RESOLVER_SERVERS=technitium" >> .env # Skip upstream validation, otherwise the ACME client for the upstream will try to # validate the DNS records, which will fail because the DNS records are not actually created. echo "ACME_SKIP_UPSTREAM_VALIDATION=true" >> .env diff --git a/.github/workflows/run-helm-chart-tests-secret-operator.yml b/.github/workflows/run-helm-chart-tests-secret-operator.yml deleted file mode 100644 index 15bb38956c..0000000000 --- a/.github/workflows/run-helm-chart-tests-secret-operator.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Run Helm Chart Tests for Secret Operator -on: - pull_request: - paths: - - "helm-charts/secrets-operator/**" - - ".github/workflows/run-helm-chart-tests-secret-operator.yml" - -jobs: - test-helm: - name: Test Helm Chart - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Set up Helm - uses: azure/setup-helm@v4.2.0 - with: - version: v3.17.0 - - - uses: actions/setup-python@v5.3.0 - with: - python-version: "3.x" - check-latest: true - - - name: Set up chart-testing - uses: helm/chart-testing-action@v2.7.0 - - - name: Run chart-testing (lint) - run: ct lint --config ct.yaml --charts helm-charts/secrets-operator - - - name: Create kind cluster - uses: helm/kind-action@v1.12.0 - - - name: Run chart-testing (install) - run: ct install --config ct.yaml --charts helm-charts/secrets-operator diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index 1e590139c4..20ba0b3155 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.yml @@ -16,7 +16,7 @@ jobs: const title = context.payload.pull_request.title; // Valid PR types based on pull_request_template.md - const validTypes = ['fix', 'feature', 'improvement', 'breaking', 'docs', 'chore']; + const validTypes = ['fix', 'feature', 'improvement', 'breaking', 'docs', 'chore', 'feat']; // Regex pattern: type(optional-scope): short description // - Type must be one of the valid types diff --git a/.infisicalignore b/.infisicalignore index 441031b338..46e38aa23f 100644 --- a/.infisicalignore +++ b/.infisicalignore @@ -58,4 +58,5 @@ docs/documentation/platform/pki/enrollment-methods/api.mdx:private-key:139 docs/documentation/platform/pki/certificate-syncs/aws-secrets-manager.mdx:private-key:62 docs/documentation/platform/pki/certificate-syncs/chef.mdx:private-key:61 backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:246 -backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:248 \ No newline at end of file +backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:248 +docs/documentation/platform/pki/enrollment-methods/api.mdx:private-key:142 \ No newline at end of file diff --git a/Makefile b/Makefile index 2352e51348..a5a87dfbc7 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ up-dev-metrics: docker compose -f docker-compose.dev.yml --profile metrics up --build up-prod: - docker-compose -f docker-compose.prod.yml up --build + docker compose -f docker-compose.prod.yml up --build down: docker compose -f docker-compose.dev.yml down diff --git a/README.md b/README.md index 1a44117a49..6a46a1f5b7 100644 --- a/README.md +++ b/README.md @@ -100,13 +100,13 @@ To set up and run Infisical locally, make sure you have Git and Docker installed Linux/macOS: ```console -git clone https://github.com/Infisical/infisical && cd "$(basename $_ .git)" && cp .env.example .env && docker compose -f docker-compose.prod.yml up +git clone https://github.com/Infisical/infisical && cd "$(basename $_ .git)" && cp .env.dev.example .env && docker compose -f docker-compose.prod.yml up ``` Windows Command Prompt: ```console -git clone https://github.com/Infisical/infisical && cd infisical && copy .env.example .env && docker compose -f docker-compose.prod.yml up +git clone https://github.com/Infisical/infisical && cd infisical && copy .env.dev.example .env && docker compose -f docker-compose.prod.yml up ``` Create an account at `http://localhost:80` diff --git a/backend/bdd/features/environment.py b/backend/bdd/features/environment.py index 52fda3ecab..8ed1410e01 100644 --- a/backend/bdd/features/environment.py +++ b/backend/bdd/features/environment.py @@ -23,6 +23,9 @@ CERT_CA_ID = os.environ.get("CERT_CA_ID") CERT_TEMPLATE_ID = os.environ.get("CERT_TEMPLATE_ID") AUTH_TOKEN = os.environ.get("INFISICAL_TOKEN") BOOTSTRAP_INFISICAL = int(os.environ.get("BOOTSTRAP_INFISICAL", 0)) +TECHNITIUM_URL = os.environ.get("TECHNITIUM_URL", "http://localhost:5380") +TECHNITIUM_USER = os.environ.get("TECHNITIUM_USER", "admin") +TECHNITIUM_PASSWORD = os.environ.get("TECHNITIUM_PASSWORD", "infisical") # Called mostly from a CI to setup the new Infisical instance to get it ready for BDD tests @@ -188,6 +191,9 @@ def before_all(context: Context): base_vars = { "BASE_URL": BASE_URL, "PEBBLE_URL": PEBBLE_URL, + "TECHNITIUM_URL": TECHNITIUM_URL, + "TECHNITIUM_USER": TECHNITIUM_USER, + "TECHNITIUM_PASSWORD": TECHNITIUM_PASSWORD, } if BOOTSTRAP_INFISICAL: details = bootstrap_infisical(context) @@ -206,6 +212,7 @@ def before_all(context: Context): } context._initial_vars = vars context.http_client = httpx.Client(base_url=BASE_URL) + context.technitium_http_client = httpx.Client(base_url=TECHNITIUM_URL) def before_scenario(context: Context, scenario: typing.Any): diff --git a/backend/bdd/features/pki/acme/auth.feature b/backend/bdd/features/pki/acme/auth.feature index 757a182c87..ef087ee074 100644 --- a/backend/bdd/features/pki/acme/auth.feature +++ b/backend/bdd/features/pki/acme/auth.feature @@ -19,13 +19,17 @@ Feature: Authorization And the value order.authorizations[0].body with jq ".challenges | map(pick(.type, .status)) | sort_by(.type)" should be equal to json """ [ + { + "type": "dns-01", + "status": "pending" + }, { "type": "http-01", "status": "pending" } ] """ - And the value order.authorizations[0].body with jq ".challenges | map(.status) | sort" should be equal to ["pending"] + And the value order.authorizations[0].body with jq ".challenges | map(.status) | sort" should be equal to ["pending", "pending"] And the value order.authorizations[0].body with jq ".identifier" should be equal to json """ { diff --git a/backend/bdd/features/pki/acme/challenge.feature b/backend/bdd/features/pki/acme/challenge.feature index 80f6fed6cb..0d673c567c 100644 --- a/backend/bdd/features/pki/acme/challenge.feature +++ b/backend/bdd/features/pki/acme/challenge.feature @@ -1,6 +1,6 @@ Feature: Challenge - Scenario: Validate challenge + Scenario: Validate challenge with HTTP-01 Given I have an ACME cert profile as "acme_profile" When I have an ACME client connecting to "{BASE_URL}/api/v1/cert-manager/acme/profiles/{acme_profile.id}/directory" Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account @@ -22,6 +22,28 @@ Feature: Challenge And I parse the full-chain certificate from order finalized_order as cert And the value cert with jq ".subject.common_name" should be equal to "localhost" + Scenario: Validate challenge with DNS-01 + Given I have an ACME cert profile as "acme_profile" + When I have an ACME client connecting to "{BASE_URL}/api/v1/cert-manager/acme/profiles/{acme_profile.id}/directory" + Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account + When I create certificate signing request as csr + Then I add names to certificate signing request csr + """ + { + "COMMON_NAME": "example.com" + } + """ + And I create a RSA private key pair as cert_key + And I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format + And I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order + And I select challenge with type dns-01 for domain example.com from order in order as challenge + Then I add domain example.com challenge response DNS records for challenge + And I tell ACME server that challenge is ready to be verified + And I poll and finalize the ACME order order as finalized_order + And the value finalized_order.body with jq ".status" should be equal to "valid" + And I parse the full-chain certificate from order finalized_order as cert + And the value cert with jq ".subject.common_name" should be equal to "example.com" + Scenario: Validate challenge with retry Given I have an ACME cert profile as "acme_profile" When I have an ACME client connecting to "{BASE_URL}/api/v1/cert-manager/acme/profiles/{acme_profile.id}/directory" @@ -192,3 +214,28 @@ Feature: Challenge And the value response with jq ".status" should be equal to 400 And the value response with jq ".type" should be equal to "urn:ietf:params:acme:error:badCSR" And the value response with jq ".detail" should be equal to "Invalid CSR: Common name + SANs mismatch with order identifiers" + + Scenario: Get certificate without passing challenge when skip DNS ownership verification is enabled + Given I create an ACME profile with config as "acme_profile" + """ + { + "skipDnsOwnershipVerification": true + } + """ + When I have an ACME client connecting to "{BASE_URL}/api/v1/cert-manager/acme/profiles/{acme_profile.id}/directory" + Then I register a new ACME account with email fangpen@infisical.com and EAB key id "{acme_profile.eab_kid}" with secret "{acme_profile.eab_secret}" as acme_account + When I create certificate signing request as csr + Then I add names to certificate signing request csr + """ + { + "COMMON_NAME": "localhost" + } + """ + And I create a RSA private key pair as cert_key + And I sign the certificate signing request csr with private key cert_key and output it as csr_pem in PEM format + And I submit the certificate signing request PEM csr_pem certificate order to the ACME server as order + And the value order.body with jq ".status" should be equal to "ready" + And I poll and finalize the ACME order order as finalized_order + And the value finalized_order.body with jq ".status" should be equal to "valid" + And I parse the full-chain certificate from order finalized_order as cert + And the value cert with jq ".subject.common_name" should be equal to "localhost" diff --git a/backend/bdd/features/steps/pki_acme.py b/backend/bdd/features/steps/pki_acme.py index c0b2fee8f0..a847cbadba 100644 --- a/backend/bdd/features/steps/pki_acme.py +++ b/backend/bdd/features/steps/pki_acme.py @@ -266,6 +266,44 @@ def step_impl(context: Context, ca_id: str, template_id: str, profile_var: str): ) +@given('I create an ACME profile with config as "{profile_var}"') +def step_impl(context: Context, profile_var: str): + profile_slug = faker.slug() + jwt_token = context.vars["AUTH_TOKEN"] + acme_config = replace_vars(json.loads(context.text), context.vars) + response = context.http_client.post( + "/api/v1/cert-manager/certificate-profiles", + headers=dict(authorization="Bearer {}".format(jwt_token)), + json={ + "projectId": context.vars["PROJECT_ID"], + "slug": profile_slug, + "description": "ACME Profile created by BDD test", + "enrollmentType": "acme", + "caId": context.vars["CERT_CA_ID"], + "certificateTemplateId": context.vars["CERT_TEMPLATE_ID"], + "acmeConfig": acme_config, + }, + ) + response.raise_for_status() + resp_json = response.json() + profile_id = resp_json["certificateProfile"]["id"] + kid = profile_id + + response = context.http_client.get( + f"/api/v1/cert-manager/certificate-profiles/{profile_id}/acme/eab-secret/reveal", + headers=dict(authorization="Bearer {}".format(jwt_token)), + ) + response.raise_for_status() + resp_json = response.json() + secret = resp_json["eabSecret"] + + context.vars[profile_var] = AcmeProfile( + profile_id, + eab_kid=kid, + eab_secret=secret, + ) + + @given('I have an ACME cert profile with external ACME CA as "{profile_var}"') def step_impl(context: Context, profile_var: str): profile_id = context.vars.get("PROFILE_ID") @@ -990,6 +1028,58 @@ def step_impl(context: Context, var_path: str, hostname: str): serve_challenges(context=context, challenges=[challenge]) +@then("I add domain {domain} challenge response DNS records for {var_path}") +def step_impl(context: Context, domain: str, var_path: str): + client = context.technitium_http_client + challenge = eval_var(context, var_path, as_json=False) + + zone = domain + domain = f"{challenge.chall.LABEL}.{domain}" + value = challenge.chall.validation(context.acme_client.net.key) + + resp = client.post( + "/api/user/login", + data={ + "user": context.vars["TECHNITIUM_USER"], + "pass": context.vars["TECHNITIUM_PASSWORD"], + }, + ) + resp.raise_for_status() + + token = resp.json()["token"] + resp = client.post( + "/api/zones/create", + params=dict( + token=token, + zone=zone, + type="Primary", + ), + ) + resp.raise_for_status() + error_msg = resp.json().get("errorMessage") + if error_msg is not None and not error_msg.startswith("Zone already exists:"): + raise RuntimeError(f"Unexpected error while creating zone {zone}: {error_msg}") + + resp = client.post( + "/api/zones/records/add", + params=dict( + token=token, + zone=zone, + domain=domain, + type="TXT", + text=value, + ), + ) + resp.raise_for_status() + error_msg = resp.json().get("errorMessage") + if error_msg is not None and not error_msg.startswith( + "Cannot add record: record already exists" + ): + raise RuntimeError( + f"Unexpected error while creating TXT record {domain} for zone {zone}: {error_msg}" + ) + + @then("I tell ACME server that {var_path} is ready to be verified") def step_impl(context: Context, var_path: str): challenge = eval_var(context, var_path, as_json=False) diff --git a/backend/scripts/generate-schema-types.ts b/backend/scripts/generate-schema-types.ts index 358a61b31b..0fb692c6ee 100644 --- a/backend/scripts/generate-schema-types.ts +++ b/backend/scripts/generate-schema-types.ts @@ -98,9 +98,11 @@ const main = async () => { (el) => !el.tableName.includes("_migrations") && !el.tableName.includes("audit_logs_") && + !el.tableName.includes("certificate_requests_") && !el.tableName.includes("user_notifications_") && !el.tableName.includes("active_locks") && - el.tableName !== "intermediate_audit_logs" + el.tableName !== "intermediate_audit_logs" && + el.tableName !== "intermediate_certificate_requests" ); for (let i = 0; i < tables.length; i += 1) { diff --git a/backend/src/@types/knex.d.ts b/backend/src/@types/knex.d.ts index 1301000d58..67c8adfa93 100644 --- a/backend/src/@types/knex.d.ts +++ b/backend/src/@types/knex.d.ts @@ -170,6 +170,9 @@ import { TIdentityGcpAuths, TIdentityGcpAuthsInsert, TIdentityGcpAuthsUpdate, + TIdentityGroupMembership, + TIdentityGroupMembershipInsert, + TIdentityGroupMembershipUpdate, TIdentityJwtAuths, TIdentityJwtAuthsInsert, TIdentityJwtAuthsUpdate, @@ -857,6 +860,11 @@ declare module "knex/types/tables" { TUserGroupMembershipInsert, TUserGroupMembershipUpdate >; + [TableName.IdentityGroupMembership]: KnexOriginal.CompositeTableType< + TIdentityGroupMembership, + TIdentityGroupMembershipInsert, + TIdentityGroupMembershipUpdate + >; [TableName.GroupProjectMembership]: KnexOriginal.CompositeTableType< TGroupProjectMemberships, TGroupProjectMembershipsInsert, diff --git a/backend/src/db/migrations/20251202162715_add-identity-group-membership.ts b/backend/src/db/migrations/20251202162715_add-identity-group-membership.ts new file mode 100644 index 0000000000..ff67f9a9f1 --- /dev/null +++ b/backend/src/db/migrations/20251202162715_add-identity-group-membership.ts @@ -0,0 +1,28 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils"; + +export async function up(knex: Knex): Promise { + if (!(await knex.schema.hasTable(TableName.IdentityGroupMembership))) { + await knex.schema.createTable(TableName.IdentityGroupMembership, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.uuid("identityId").notNullable(); + t.foreign("identityId").references("id").inTable(TableName.Identity).onDelete("CASCADE"); + t.uuid("groupId").notNullable(); + t.foreign("groupId").references("id").inTable(TableName.Groups).onDelete("CASCADE"); + t.timestamps(true, true, true); + + t.unique(["identityId", "groupId"]); + }); + } + + await createOnUpdateTrigger(knex, TableName.IdentityGroupMembership); +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.IdentityGroupMembership)) { + await knex.schema.dropTable(TableName.IdentityGroupMembership); + await dropOnUpdateTrigger(knex, TableName.IdentityGroupMembership); + } +} diff --git a/backend/src/db/migrations/20251209191101_add-acme-order-id-for-cert-requests.ts b/backend/src/db/migrations/20251209191101_add-acme-order-id-for-cert-requests.ts new file mode 100644 index 0000000000..3a87e75a40 --- /dev/null +++ b/backend/src/db/migrations/20251209191101_add-acme-order-id-for-cert-requests.ts @@ -0,0 +1,38 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { dropConstraintIfExists } from "./utils/dropConstraintIfExists"; + +const FOREIGN_KEY_CONSTRAINT_NAME = "certificate_requests_acme_order_id_fkey"; +const INDEX_NAME = "certificate_requests_acme_order_id_idx"; + +export async function up(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.CertificateRequests)) { + const hasAcmeOrderId = await knex.schema.hasColumn(TableName.CertificateRequests, "acmeOrderId"); + + if (!hasAcmeOrderId) { + await knex.schema.alterTable(TableName.CertificateRequests, (t) => { + t.uuid("acmeOrderId").nullable(); + t.foreign("acmeOrderId", FOREIGN_KEY_CONSTRAINT_NAME) + .references("id") + .inTable(TableName.PkiAcmeOrder) + .onDelete("SET NULL"); + t.index("acmeOrderId", INDEX_NAME); + }); + } + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.CertificateRequests)) { + const hasAcmeOrderId = await knex.schema.hasColumn(TableName.CertificateRequests, "acmeOrderId"); + + if (hasAcmeOrderId) { + await dropConstraintIfExists(TableName.CertificateRequests, FOREIGN_KEY_CONSTRAINT_NAME, knex); + await knex.schema.alterTable(TableName.CertificateRequests, (t) => { + t.dropIndex("acmeOrderId", INDEX_NAME); + t.dropColumn("acmeOrderId"); + }); + } + } +} diff --git a/backend/src/db/migrations/20251210113242_add-skip-dns-ownership-verification-to-acme-config.ts b/backend/src/db/migrations/20251210113242_add-skip-dns-ownership-verification-to-acme-config.ts new file mode 100644 index 0000000000..6ae5b40397 --- /dev/null +++ b/backend/src/db/migrations/20251210113242_add-skip-dns-ownership-verification-to-acme-config.ts @@ -0,0 +1,23 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.PkiAcmeEnrollmentConfig)) { + if (!(await knex.schema.hasColumn(TableName.PkiAcmeEnrollmentConfig, "skipDnsOwnershipVerification"))) { + await knex.schema.alterTable(TableName.PkiAcmeEnrollmentConfig, (t) => { + t.boolean("skipDnsOwnershipVerification").defaultTo(false).notNullable(); + }); + } + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.PkiAcmeEnrollmentConfig)) { + if (await knex.schema.hasColumn(TableName.PkiAcmeEnrollmentConfig, "skipDnsOwnershipVerification")) { + await knex.schema.alterTable(TableName.PkiAcmeEnrollmentConfig, (t) => { + t.dropColumn("skipDnsOwnershipVerification"); + }); + } + } +} diff --git a/backend/src/db/migrations/20251212150000_add-certificate-requests-partitioning.ts b/backend/src/db/migrations/20251212150000_add-certificate-requests-partitioning.ts new file mode 100644 index 0000000000..c7084b5659 --- /dev/null +++ b/backend/src/db/migrations/20251212150000_add-certificate-requests-partitioning.ts @@ -0,0 +1,171 @@ +/* eslint-disable no-console */ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; +import { createOnUpdateTrigger } from "../utils"; + +const INTERMEDIATE_CERTIFICATE_REQUESTS_TABLE = "intermediate_certificate_requests"; + +const formatPartitionDate = (date: Date) => { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + + return `${year}-${month}-${day}`; +}; + +const createCertificateRequestPartition = async (knex: Knex, startDate: Date, endDate: Date) => { + const startDateStr = formatPartitionDate(startDate); + const endDateStr = formatPartitionDate(endDate); + + const partitionName = `${TableName.CertificateRequests}_${startDateStr.replace(/-/g, "")}_${endDateStr.replace(/-/g, "")}`; + + await knex.schema.raw( + `CREATE TABLE ${partitionName} PARTITION OF ${TableName.CertificateRequests} FOR VALUES FROM ('${startDateStr}') TO ('${endDateStr}')` + ); +}; + +export async function up(knex: Knex): Promise { + // Check if table is already partitioned by looking for partition information + const partitionInfo: { rows: { schemaname: string; tablename: string }[] } = await knex.raw( + ` + SELECT schemaname, tablename + FROM pg_tables + WHERE tablename LIKE '${TableName.CertificateRequests}_%' + AND schemaname = 'public' + ` + ); + + if (partitionInfo.rows.length > 0) { + console.info("Certificate requests table is already partitioned, skipping migration..."); + return; + } + + if (await knex.schema.hasTable(TableName.CertificateRequests)) { + console.info("Converting existing certificate_requests table to partitioned table..."); + + // Drop primary key constraint + console.info("Dropping primary key of certificate_requests table..."); + await knex.schema.alterTable(TableName.CertificateRequests, (t) => { + t.dropPrimary(); + }); + + // Get all indices of the certificate_requests table and drop them + const indexNames: { rows: { indexname: string }[] } = await knex.raw( + ` + SELECT indexname + FROM pg_indexes + WHERE tablename = '${TableName.CertificateRequests}' + ` + ); + + console.log( + "Deleting existing certificate_requests indices:", + indexNames.rows.map((e) => e.indexname) + ); + + for await (const row of indexNames.rows) { + await knex.raw(`DROP INDEX IF EXISTS ??`, [row.indexname]); + } + + // Rename existing table to intermediate name + console.log("Renaming certificate_requests table to intermediate name"); + await knex.schema.renameTable(TableName.CertificateRequests, INTERMEDIATE_CERTIFICATE_REQUESTS_TABLE); + + // Create new partitioned table with same schema - MUST MATCH EXACTLY the original table + const createTableSql = knex.schema + .createTable(TableName.CertificateRequests, (t) => { + t.uuid("id").defaultTo(knex.fn.uuid()); + t.timestamps(true, true, true); + t.string("status").notNullable(); + t.string("projectId").notNullable(); + t.uuid("profileId").nullable(); + t.uuid("caId").nullable(); + t.uuid("certificateId").nullable(); + t.text("csr").nullable(); + t.string("commonName").nullable(); + t.text("altNames").nullable(); + t.specificType("keyUsages", "text[]").nullable(); + t.specificType("extendedKeyUsages", "text[]").nullable(); + t.datetime("notBefore").nullable(); + t.datetime("notAfter").nullable(); + t.string("keyAlgorithm").nullable(); + t.string("signatureAlgorithm").nullable(); + t.text("errorMessage").nullable(); + t.text("metadata").nullable(); + t.uuid("acmeOrderId").nullable(); + + t.primary(["id", "createdAt"]); + }) + .toString(); + + console.info("Creating partitioned certificate_requests table..."); + await knex.schema.raw(`${createTableSql} PARTITION BY RANGE ("createdAt")`); + + console.log("Adding indices..."); + await knex.schema.alterTable(TableName.CertificateRequests, (t) => { + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + t.foreign("profileId").references("id").inTable(TableName.PkiCertificateProfile).onDelete("SET NULL"); + t.foreign("caId").references("id").inTable(TableName.CertificateAuthority).onDelete("SET NULL"); + t.foreign("certificateId").references("id").inTable(TableName.Certificate).onDelete("SET NULL"); + + t.index("status"); + t.index(["projectId", "status"]); + t.index(["projectId", "createdAt"]); + t.index("acmeOrderId", "certificate_requests_acme_order_id_idx"); + }); + + // Create default partition + console.log("Creating default partition..."); + await knex.schema.raw( + `CREATE TABLE ${TableName.CertificateRequests}_default PARTITION OF ${TableName.CertificateRequests} DEFAULT` + ); + + const nextDate = new Date(); + nextDate.setDate(nextDate.getDate() + 1); + const nextDateStr = formatPartitionDate(nextDate); + + console.log("Attaching existing certificate_requests table as a partition..."); + await knex.schema.raw( + ` + ALTER TABLE ${INTERMEDIATE_CERTIFICATE_REQUESTS_TABLE} ADD CONSTRAINT certificate_requests_old + CHECK ( "createdAt" < DATE '${nextDateStr}' ); + + ALTER TABLE ${TableName.CertificateRequests} ATTACH PARTITION ${INTERMEDIATE_CERTIFICATE_REQUESTS_TABLE} + FOR VALUES FROM (MINVALUE) TO ('${nextDateStr}' ); + ` + ); + + // Create partition from next day until end of month + console.log("Creating certificate_requests partitions ahead of time... next date:", nextDateStr); + await createCertificateRequestPartition( + knex, + nextDate, + new Date(nextDate.getFullYear(), nextDate.getMonth() + 1, 1) + ); + + // Create partitions 20 years ahead for certificate requests + const partitionMonths = 20 * 12; + const partitionPromises: Promise[] = []; + for (let x = 1; x <= partitionMonths; x += 1) { + partitionPromises.push( + createCertificateRequestPartition( + knex, + new Date(nextDate.getFullYear(), nextDate.getMonth() + x, 1), + new Date(nextDate.getFullYear(), nextDate.getMonth() + (x + 1), 1) + ) + ); + } + + await Promise.all(partitionPromises); + + await createOnUpdateTrigger(knex, TableName.CertificateRequests); + console.log("Certificate requests partition migration complete"); + } else { + console.log("Certificate requests table does not exist, skipping partitioning migration"); + } +} + +export async function down(): Promise { + // skip +} diff --git a/backend/src/db/schemas/certificate-requests.ts b/backend/src/db/schemas/certificate-requests.ts index e01e08bbd1..4013ea5bbc 100644 --- a/backend/src/db/schemas/certificate-requests.ts +++ b/backend/src/db/schemas/certificate-requests.ts @@ -26,7 +26,8 @@ export const CertificateRequestsSchema = z.object({ keyAlgorithm: z.string().nullable().optional(), signatureAlgorithm: z.string().nullable().optional(), errorMessage: z.string().nullable().optional(), - metadata: z.string().nullable().optional() + metadata: z.string().nullable().optional(), + acmeOrderId: z.string().uuid().nullable().optional() }); export type TCertificateRequests = z.infer; diff --git a/backend/src/db/schemas/identity-group-membership.ts b/backend/src/db/schemas/identity-group-membership.ts new file mode 100644 index 0000000000..7dcd65c545 --- /dev/null +++ b/backend/src/db/schemas/identity-group-membership.ts @@ -0,0 +1,22 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const IdentityGroupMembershipSchema = z.object({ + id: z.string().uuid(), + identityId: z.string().uuid(), + groupId: z.string().uuid(), + createdAt: z.date(), + updatedAt: z.date() +}); + +export type TIdentityGroupMembership = z.infer; +export type TIdentityGroupMembershipInsert = Omit, TImmutableDBKeys>; +export type TIdentityGroupMembershipUpdate = Partial< + Omit, TImmutableDBKeys> +>; diff --git a/backend/src/db/schemas/index.ts b/backend/src/db/schemas/index.ts index 528582c592..3517bd6cd0 100644 --- a/backend/src/db/schemas/index.ts +++ b/backend/src/db/schemas/index.ts @@ -55,6 +55,7 @@ export * from "./identity-alicloud-auths"; export * from "./identity-aws-auths"; export * from "./identity-azure-auths"; export * from "./identity-gcp-auths"; +export * from "./identity-group-membership"; export * from "./identity-jwt-auths"; export * from "./identity-kubernetes-auths"; export * from "./identity-metadata"; diff --git a/backend/src/db/schemas/models.ts b/backend/src/db/schemas/models.ts index fe38a9c9ba..b18d21163c 100644 --- a/backend/src/db/schemas/models.ts +++ b/backend/src/db/schemas/models.ts @@ -42,6 +42,7 @@ export enum TableName { GroupProjectMembershipRole = "group_project_membership_roles", ExternalGroupOrgRoleMapping = "external_group_org_role_mappings", UserGroupMembership = "user_group_membership", + IdentityGroupMembership = "identity_group_membership", UserAliases = "user_aliases", UserEncryptionKey = "user_encryption_keys", AuthTokens = "auth_tokens", diff --git a/backend/src/db/schemas/pki-acme-enrollment-configs.ts b/backend/src/db/schemas/pki-acme-enrollment-configs.ts index f0592319bf..4f4460986f 100644 --- a/backend/src/db/schemas/pki-acme-enrollment-configs.ts +++ b/backend/src/db/schemas/pki-acme-enrollment-configs.ts @@ -13,7 +13,8 @@ export const PkiAcmeEnrollmentConfigsSchema = z.object({ id: z.string().uuid(), encryptedEabSecret: zodBuffer, createdAt: z.date(), - updatedAt: z.date() + updatedAt: z.date(), + skipDnsOwnershipVerification: z.boolean().default(false) }); export type TPkiAcmeEnrollmentConfigs = z.infer; diff --git a/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts b/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts index 62911d5239..d6475d5351 100644 --- a/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts +++ b/backend/src/ee/routes/v1/dynamic-secret-lease-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { DynamicSecretLeasesSchema } from "@app/db/schemas"; +import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { ApiDocsTags, DYNAMIC_SECRET_LEASES } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; import { ms } from "@app/lib/ms"; @@ -48,14 +49,35 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const { data, lease, dynamicSecret } = await server.services.dynamicSecretLease.create({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - name: req.body.dynamicSecretName, - ...req.body + const { data, lease, dynamicSecret, projectId, environment, secretPath } = + await server.services.dynamicSecretLease.create({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + name: req.body.dynamicSecretName, + ...req.body + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.CREATE_DYNAMIC_SECRET_LEASE, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretType: dynamicSecret.type, + dynamicSecretId: dynamicSecret.id, + projectId, + environment, + secretPath, + leaseId: lease.id, + leaseExternalEntityId: lease.externalEntityId, + leaseExpireAt: lease.expireAt + } + } }); + return { lease, data, dynamicSecret }; } }); @@ -92,14 +114,36 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const lease = await server.services.dynamicSecretLease.revokeLease({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - leaseId: req.params.leaseId, - ...req.body + const { lease, dynamicSecret, projectId, environment, secretPath } = + await server.services.dynamicSecretLease.revokeLease({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + leaseId: req.params.leaseId, + ...req.body + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.DELETE_DYNAMIC_SECRET_LEASE, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretType: dynamicSecret.type, + dynamicSecretId: dynamicSecret.id, + leaseId: lease.id, + leaseExternalEntityId: lease.externalEntityId, + leaseStatus: lease.status, + environment, + secretPath, + projectId, + isForced: req.body.isForced + } + } }); + return { lease }; } }); @@ -147,14 +191,35 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const lease = await server.services.dynamicSecretLease.renewLease({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - leaseId: req.params.leaseId, - ...req.body + const { lease, dynamicSecret, projectId, environment, secretPath } = + await server.services.dynamicSecretLease.renewLease({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + leaseId: req.params.leaseId, + ...req.body + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.RENEW_DYNAMIC_SECRET_LEASE, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretType: dynamicSecret.type, + dynamicSecretId: dynamicSecret.id, + leaseId: lease.id, + leaseExternalEntityId: lease.externalEntityId, + newLeaseExpireAt: lease.expireAt, + environment, + secretPath, + projectId + } + } }); + return { lease }; } }); @@ -191,15 +256,41 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const lease = await server.services.dynamicSecretLease.getLeaseDetails({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - leaseId: req.params.leaseId, - ...req.query + const { lease, dynamicSecret, projectId, environment, secretPath } = + await server.services.dynamicSecretLease.getLeaseDetails({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + leaseId: req.params.leaseId, + ...req.query + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.GET_DYNAMIC_SECRET_LEASE, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretId: dynamicSecret.id, + dynamicSecretType: dynamicSecret.type, + leaseId: lease.id, + leaseExternalEntityId: lease.externalEntityId, + leaseExpireAt: lease.expireAt, + environment, + secretPath, + projectId + } + } }); - return { lease }; + + return { + lease: { + ...lease, + dynamicSecret + } + }; } }); }; diff --git a/backend/src/ee/routes/v1/dynamic-secret-router.ts b/backend/src/ee/routes/v1/dynamic-secret-router.ts index 0e48206dc8..f0ce32270c 100644 --- a/backend/src/ee/routes/v1/dynamic-secret-router.ts +++ b/backend/src/ee/routes/v1/dynamic-secret-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { DynamicSecretLeasesSchema } from "@app/db/schemas"; +import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { DynamicSecretProviderSchema } from "@app/ee/services/dynamic-secret/providers/models"; import { ApiDocsTags, DYNAMIC_SECRETS } from "@app/lib/api-docs"; import { removeTrailingSlash } from "@app/lib/fn"; @@ -98,6 +99,27 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => actorOrgId: req.permission.orgId, ...req.body }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: dynamicSecretCfg.projectId, + event: { + type: EventType.CREATE_DYNAMIC_SECRET, + metadata: { + dynamicSecretName: dynamicSecretCfg.name, + dynamicSecretType: dynamicSecretCfg.type, + dynamicSecretId: dynamicSecretCfg.id, + defaultTTL: dynamicSecretCfg.defaultTTL, + maxTTL: dynamicSecretCfg.maxTTL, + gatewayV2Id: dynamicSecretCfg.gatewayV2Id, + usernameTemplate: dynamicSecretCfg.usernameTemplate, + environment: dynamicSecretCfg.environment, + secretPath: dynamicSecretCfg.secretPath, + projectId: dynamicSecretCfg.projectId + } + } + }); + return { dynamicSecret: dynamicSecretCfg }; } }); @@ -160,18 +182,36 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const dynamicSecretCfg = await server.services.dynamicSecret.updateByName({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - name: req.params.name, - path: req.body.path, - projectSlug: req.body.projectSlug, - environmentSlug: req.body.environmentSlug, - ...req.body.data + const { dynamicSecret, updatedFields, projectId, environment, secretPath } = + await server.services.dynamicSecret.updateByName({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + name: req.params.name, + path: req.body.path, + projectSlug: req.body.projectSlug, + environmentSlug: req.body.environmentSlug, + ...req.body.data + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.UPDATE_DYNAMIC_SECRET, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretType: dynamicSecret.type, + dynamicSecretId: dynamicSecret.id, + environment, + secretPath, + projectId, + updatedFields + } + } }); - return { dynamicSecret: dynamicSecretCfg }; + return { dynamicSecret }; } }); @@ -209,6 +249,23 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => name: req.params.name, ...req.body }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: dynamicSecretCfg.projectId, + event: { + type: EventType.DELETE_DYNAMIC_SECRET, + metadata: { + dynamicSecretName: dynamicSecretCfg.name, + dynamicSecretType: dynamicSecretCfg.type, + dynamicSecretId: dynamicSecretCfg.id, + environment: dynamicSecretCfg.environment, + secretPath: dynamicSecretCfg.secretPath, + projectId: dynamicSecretCfg.projectId + } + } + }); + return { dynamicSecret: dynamicSecretCfg }; } }); @@ -249,6 +306,22 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => ...req.query }); + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: dynamicSecretCfg.projectId, + event: { + type: EventType.GET_DYNAMIC_SECRET, + metadata: { + dynamicSecretName: dynamicSecretCfg.name, + dynamicSecretType: dynamicSecretCfg.type, + dynamicSecretId: dynamicSecretCfg.id, + environment: dynamicSecretCfg.environment, + secretPath: dynamicSecretCfg.secretPath, + projectId: dynamicSecretCfg.projectId + } + } + }); + return { dynamicSecret: dynamicSecretCfg }; } }); @@ -275,14 +348,29 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const dynamicSecretCfgs = await server.services.dynamicSecret.listDynamicSecretsByEnv({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - ...req.query + const { dynamicSecrets, environment, secretPath, projectId } = + await server.services.dynamicSecret.listDynamicSecretsByEnv({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.query + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.LIST_DYNAMIC_SECRETS, + metadata: { + environment, + secretPath, + projectId + } + } }); - return { dynamicSecrets: dynamicSecretCfgs }; + + return { dynamicSecrets }; } }); @@ -316,14 +404,33 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) => }, onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { - const leases = await server.services.dynamicSecretLease.listLeases({ - actor: req.permission.type, - actorId: req.permission.id, - actorAuthMethod: req.permission.authMethod, - actorOrgId: req.permission.orgId, - name: req.params.name, - ...req.query + const { leases, dynamicSecret, projectId, environment, secretPath } = + await server.services.dynamicSecretLease.listLeases({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + name: req.params.name, + ...req.query + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.LIST_DYNAMIC_SECRET_LEASES, + metadata: { + dynamicSecretName: dynamicSecret.name, + dynamicSecretType: dynamicSecret.type, + dynamicSecretId: dynamicSecret.id, + environment, + secretPath, + projectId, + leaseCount: leases.length + } + } }); + return { leases }; } }); diff --git a/backend/src/ee/routes/v1/external-kms-routers/external-kms-endpoints.ts b/backend/src/ee/routes/v1/external-kms-routers/external-kms-endpoints.ts index 47b4947f2b..2ae94155b9 100644 --- a/backend/src/ee/routes/v1/external-kms-routers/external-kms-endpoints.ts +++ b/backend/src/ee/routes/v1/external-kms-routers/external-kms-endpoints.ts @@ -11,6 +11,7 @@ import { } from "@app/ee/services/external-kms/providers/model"; import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError } from "@app/lib/errors"; +import { deterministicStringify } from "@app/lib/fn/object"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -88,9 +89,11 @@ export const registerExternalKmsEndpoints = < ...rest } = externalKms; + const credentialsToHash = deterministicStringify(configuration.credential); + const credentialsHash = crypto.nativeCrypto .createHash("sha256") - .update(externalKmsData.encryptedProviderInputs) + .update(Buffer.from(credentialsToHash)) .digest("hex"); return { ...rest, externalKms: { ...externalKmsData, configuration, credentialsHash } }; } @@ -153,9 +156,12 @@ export const registerExternalKmsEndpoints = < external: { providerInput: externalKmsConfiguration, ...externalKmsData }, ...rest } = externalKms; + + const credentialsToHash = deterministicStringify(externalKmsConfiguration.credential); + const credentialsHash = crypto.nativeCrypto .createHash("sha256") - .update(externalKmsData.encryptedProviderInputs) + .update(Buffer.from(credentialsToHash)) .digest("hex"); return { ...rest, externalKms: { ...externalKmsData, configuration: externalKmsConfiguration, credentialsHash } }; } @@ -222,9 +228,12 @@ export const registerExternalKmsEndpoints = < external: { providerInput: externalKmsConfiguration, ...externalKmsData }, ...rest } = externalKms; + + const credentialsToHash = deterministicStringify(externalKmsConfiguration.credential); + const credentialsHash = crypto.nativeCrypto .createHash("sha256") - .update(externalKmsData.encryptedProviderInputs) + .update(Buffer.from(credentialsToHash)) .digest("hex"); return { ...rest, externalKms: { ...externalKmsData, configuration: externalKmsConfiguration, credentialsHash } }; } @@ -277,9 +286,12 @@ export const registerExternalKmsEndpoints = < external: { providerInput: configuration, ...externalKmsData }, ...rest } = externalKms; + + const credentialsToHash = deterministicStringify(configuration.credential); + const credentialsHash = crypto.nativeCrypto .createHash("sha256") - .update(externalKmsData.encryptedProviderInputs) + .update(Buffer.from(credentialsToHash)) .digest("hex"); return { ...rest, externalKms: { ...externalKmsData, configuration, credentialsHash } }; diff --git a/backend/src/ee/routes/v1/group-router.ts b/backend/src/ee/routes/v1/group-router.ts index 4696bef26d..d5d2455a7b 100644 --- a/backend/src/ee/routes/v1/group-router.ts +++ b/backend/src/ee/routes/v1/group-router.ts @@ -1,18 +1,27 @@ import { z } from "zod"; -import { GroupsSchema, OrgMembershipRole, ProjectsSchema, UsersSchema } from "@app/db/schemas"; +import { GroupsSchema, IdentitiesSchema, OrgMembershipRole, ProjectsSchema, UsersSchema } from "@app/db/schemas"; import { - EFilterReturnedProjects, - EFilterReturnedUsers, - EGroupProjectsOrderBy + FilterMemberType, + FilterReturnedMachineIdentities, + FilterReturnedProjects, + FilterReturnedUsers, + GroupMembersOrderBy, + GroupProjectsOrderBy } from "@app/ee/services/group/group-types"; import { ApiDocsTags, GROUPS } from "@app/lib/api-docs"; import { OrderByDirection } from "@app/lib/types"; +import { CharacterType, characterValidator } from "@app/lib/validator/validate-string"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; +const GroupIdentityResponseSchema = IdentitiesSchema.pick({ + id: true, + name: true +}); + export const registerGroupRouter = async (server: FastifyZodProvider) => { server.route({ url: "/", @@ -190,8 +199,15 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { offset: z.coerce.number().min(0).default(0).describe(GROUPS.LIST_USERS.offset), limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_USERS.limit), username: z.string().trim().optional().describe(GROUPS.LIST_USERS.username), - search: z.string().trim().optional().describe(GROUPS.LIST_USERS.search), - filter: z.nativeEnum(EFilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) + search: z + .string() + .trim() + .refine((val) => characterValidator([CharacterType.AlphaNumeric, CharacterType.Hyphen])(val), { + message: "Invalid pattern: only alphanumeric characters, - are allowed." + }) + .optional() + .describe(GROUPS.LIST_USERS.search), + filter: z.nativeEnum(FilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) }), response: { 200: z.object({ @@ -202,12 +218,10 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { lastName: true, id: true }) - .merge( - z.object({ - isPartOfGroup: z.boolean(), - joinedGroupAt: z.date().nullable() - }) - ) + .extend({ + isPartOfGroup: z.boolean(), + joinedGroupAt: z.date().nullable() + }) .array(), totalCount: z.number() }) @@ -227,6 +241,134 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { } }); + server.route({ + method: "GET", + url: "/:id/machine-identities", + config: { + rateLimit: readLimit + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + schema: { + hide: false, + tags: [ApiDocsTags.Groups], + params: z.object({ + id: z.string().trim().describe(GROUPS.LIST_MACHINE_IDENTITIES.id) + }), + querystring: z.object({ + offset: z.coerce.number().min(0).default(0).describe(GROUPS.LIST_MACHINE_IDENTITIES.offset), + limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_MACHINE_IDENTITIES.limit), + search: z + .string() + .trim() + .refine((val) => characterValidator([CharacterType.AlphaNumeric, CharacterType.Hyphen])(val), { + message: "Invalid pattern: only alphanumeric characters, - are allowed." + }) + .optional() + .describe(GROUPS.LIST_MACHINE_IDENTITIES.search), + filter: z + .nativeEnum(FilterReturnedMachineIdentities) + .optional() + .describe(GROUPS.LIST_MACHINE_IDENTITIES.filterMachineIdentities) + }), + response: { + 200: z.object({ + machineIdentities: GroupIdentityResponseSchema.extend({ + isPartOfGroup: z.boolean(), + joinedGroupAt: z.date().nullable() + }).array(), + totalCount: z.number() + }) + } + }, + handler: async (req) => { + const { machineIdentities, totalCount } = await server.services.group.listGroupMachineIdentities({ + id: req.params.id, + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.query + }); + + return { machineIdentities, totalCount }; + } + }); + + server.route({ + method: "GET", + url: "/:id/members", + config: { + rateLimit: readLimit + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + schema: { + hide: false, + tags: [ApiDocsTags.Groups], + params: z.object({ + id: z.string().trim().describe(GROUPS.LIST_MEMBERS.id) + }), + querystring: z.object({ + offset: z.coerce.number().min(0).default(0).describe(GROUPS.LIST_MEMBERS.offset), + limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_MEMBERS.limit), + search: z + .string() + .trim() + .refine((val) => characterValidator([CharacterType.AlphaNumeric, CharacterType.Hyphen])(val), { + message: "Invalid pattern: only alphanumeric characters, - are allowed." + }) + .optional() + .describe(GROUPS.LIST_MEMBERS.search), + orderBy: z + .nativeEnum(GroupMembersOrderBy) + .default(GroupMembersOrderBy.Name) + .optional() + .describe(GROUPS.LIST_MEMBERS.orderBy), + orderDirection: z.nativeEnum(OrderByDirection).optional().describe(GROUPS.LIST_MEMBERS.orderDirection), + memberTypeFilter: z + .union([z.nativeEnum(FilterMemberType), z.array(z.nativeEnum(FilterMemberType))]) + .optional() + .describe(GROUPS.LIST_MEMBERS.memberTypeFilter) + .transform((val) => { + if (!val) return undefined; + return Array.isArray(val) ? val : [val]; + }) + }), + response: { + 200: z.object({ + members: z + .discriminatedUnion("type", [ + z.object({ + id: z.string(), + joinedGroupAt: z.date().nullable(), + type: z.literal("user"), + user: UsersSchema.pick({ id: true, firstName: true, lastName: true, email: true, username: true }) + }), + z.object({ + id: z.string(), + joinedGroupAt: z.date().nullable(), + type: z.literal("machineIdentity"), + machineIdentity: GroupIdentityResponseSchema + }) + ]) + .array(), + totalCount: z.number() + }) + } + }, + handler: async (req) => { + const { members, totalCount } = await server.services.group.listGroupMembers({ + id: req.params.id, + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.query + }); + + return { members, totalCount }; + } + }); + server.route({ method: "GET", url: "/:id/projects", @@ -243,11 +385,18 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { querystring: z.object({ offset: z.coerce.number().min(0).default(0).describe(GROUPS.LIST_PROJECTS.offset), limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_PROJECTS.limit), - search: z.string().trim().optional().describe(GROUPS.LIST_PROJECTS.search), - filter: z.nativeEnum(EFilterReturnedProjects).optional().describe(GROUPS.LIST_PROJECTS.filterProjects), + search: z + .string() + .trim() + .refine((val) => characterValidator([CharacterType.AlphaNumeric, CharacterType.Hyphen])(val), { + message: "Invalid pattern: only alphanumeric characters, - are allowed." + }) + .optional() + .describe(GROUPS.LIST_PROJECTS.search), + filter: z.nativeEnum(FilterReturnedProjects).optional().describe(GROUPS.LIST_PROJECTS.filterProjects), orderBy: z - .nativeEnum(EGroupProjectsOrderBy) - .default(EGroupProjectsOrderBy.Name) + .nativeEnum(GroupProjectsOrderBy) + .default(GroupProjectsOrderBy.Name) .describe(GROUPS.LIST_PROJECTS.orderBy), orderDirection: z .nativeEnum(OrderByDirection) @@ -263,11 +412,9 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { description: true, type: true }) - .merge( - z.object({ - joinedGroupAt: z.date().nullable() - }) - ) + .extend({ + joinedGroupAt: z.date().nullable() + }) .array(), totalCount: z.number() }) @@ -325,6 +472,40 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { } }); + server.route({ + method: "POST", + url: "/:id/machine-identities/:machineIdentityId", + config: { + rateLimit: writeLimit + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + schema: { + hide: false, + tags: [ApiDocsTags.Groups], + params: z.object({ + id: z.string().trim().describe(GROUPS.ADD_MACHINE_IDENTITY.id), + machineIdentityId: z.string().trim().describe(GROUPS.ADD_MACHINE_IDENTITY.machineIdentityId) + }), + response: { + 200: z.object({ + id: z.string() + }) + } + }, + handler: async (req) => { + const machineIdentity = await server.services.group.addMachineIdentityToGroup({ + id: req.params.id, + identityId: req.params.machineIdentityId, + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId + }); + + return machineIdentity; + } + }); + server.route({ method: "DELETE", url: "/:id/users/:username", @@ -362,4 +543,38 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => { return user; } }); + + server.route({ + method: "DELETE", + url: "/:id/machine-identities/:machineIdentityId", + config: { + rateLimit: writeLimit + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + schema: { + hide: false, + tags: [ApiDocsTags.Groups], + params: z.object({ + id: z.string().trim().describe(GROUPS.DELETE_MACHINE_IDENTITY.id), + machineIdentityId: z.string().trim().describe(GROUPS.DELETE_MACHINE_IDENTITY.machineIdentityId) + }), + response: { + 200: z.object({ + id: z.string() + }) + } + }, + handler: async (req) => { + const machineIdentity = await server.services.group.removeMachineIdentityFromGroup({ + id: req.params.id, + identityId: req.params.machineIdentityId, + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId + }); + + return machineIdentity; + } + }); }; diff --git a/backend/src/ee/routes/v1/user-additional-privilege-router.ts b/backend/src/ee/routes/v1/user-additional-privilege-router.ts index 926b222319..debaa12cfe 100644 --- a/backend/src/ee/routes/v1/user-additional-privilege-router.ts +++ b/backend/src/ee/routes/v1/user-additional-privilege-router.ts @@ -142,6 +142,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr data: { ...req.body, ...req.body.type, + name: req.body.slug, permissions: req.body.permissions ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-error this is valid ts diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts index 6d97e3b9eb..7882eaab7d 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts @@ -56,7 +56,7 @@ type TSecretApprovalRequestServiceFactoryDep = { TAccessApprovalRequestReviewerDALFactory, "create" | "find" | "findOne" | "transaction" | "delete" >; - groupDAL: Pick; + groupDAL: Pick; smtpService: Pick; userDAL: Pick< TUserDALFactory, @@ -182,7 +182,7 @@ export const accessApprovalRequestServiceFactory = ({ await Promise.all( approverGroupIds.map((groupApproverId) => groupDAL - .findAllGroupPossibleMembers({ + .findAllGroupPossibleUsers({ orgId: actorOrgId, groupId: groupApproverId }) diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index b89137ec6e..57b736c401 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -49,6 +49,7 @@ import { TWebhookPayloads } from "@app/services/webhook/webhook-types"; import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types"; import { KmipPermission } from "../kmip/kmip-enum"; +import { AcmeChallengeType, AcmeIdentifierType } from "../pki-acme/pki-acme-schemas"; import { ApprovalStatus } from "../secret-approval-request/secret-approval-request-types"; export type TListProjectAuditLogDTO = { @@ -78,7 +79,9 @@ export type TCreateAuditLogDTO = { | ScimClientActor | PlatformActor | UnknownUserActor - | KmipClientActor; + | KmipClientActor + | AcmeProfileActor + | AcmeAccountActor; orgId?: string; projectId?: string; } & BaseAuthData; @@ -392,6 +395,7 @@ export enum EventType { CREATE_CERTIFICATE_REQUEST = "create-certificate-request", GET_CERTIFICATE_REQUEST = "get-certificate-request", GET_CERTIFICATE_FROM_REQUEST = "get-certificate-from-request", + LIST_CERTIFICATE_REQUESTS = "list-certificate-requests", ATTEMPT_CREATE_SLACK_INTEGRATION = "attempt-create-slack-integration", ATTEMPT_REINSTALL_SLACK_INTEGRATION = "attempt-reinstall-slack-integration", GET_PROJECT_SLACK_CONFIG = "get-project-slack-config", @@ -574,7 +578,32 @@ export enum EventType { APPROVAL_REQUEST_CANCEL = "approval-request-cancel", APPROVAL_REQUEST_GRANT_LIST = "approval-request-grant-list", APPROVAL_REQUEST_GRANT_GET = "approval-request-grant-get", - APPROVAL_REQUEST_GRANT_REVOKE = "approval-request-grant-revoke" + APPROVAL_REQUEST_GRANT_REVOKE = "approval-request-grant-revoke", + + // PKI ACME + CREATE_ACME_ACCOUNT = "create-acme-account", + RETRIEVE_ACME_ACCOUNT = "retrieve-acme-account", + CREATE_ACME_ORDER = "create-acme-order", + FINALIZE_ACME_ORDER = "finalize-acme-order", + DOWNLOAD_ACME_CERTIFICATE = "download-acme-certificate", + RESPOND_TO_ACME_CHALLENGE = "respond-to-acme-challenge", + PASS_ACME_CHALLENGE = "pass-acme-challenge", + ATTEMPT_ACME_CHALLENGE = "attempt-acme-challenge", + FAIL_ACME_CHALLENGE = "fail-acme-challenge", + + // Dynamic Secrets + CREATE_DYNAMIC_SECRET = "create-dynamic-secret", + UPDATE_DYNAMIC_SECRET = "update-dynamic-secret", + DELETE_DYNAMIC_SECRET = "delete-dynamic-secret", + GET_DYNAMIC_SECRET = "get-dynamic-secret", + LIST_DYNAMIC_SECRETS = "list-dynamic-secrets", + + // Dynamic Secret Leases + CREATE_DYNAMIC_SECRET_LEASE = "create-dynamic-secret-lease", + DELETE_DYNAMIC_SECRET_LEASE = "delete-dynamic-secret-lease", + RENEW_DYNAMIC_SECRET_LEASE = "renew-dynamic-secret-lease", + LIST_DYNAMIC_SECRET_LEASES = "list-dynamic-secret-leases", + GET_DYNAMIC_SECRET_LEASE = "get-dynamic-secret-lease" } export const filterableSecretEvents: EventType[] = [ @@ -615,6 +644,15 @@ interface KmipClientActorMetadata { name: string; } +interface AcmeProfileActorMetadata { + profileId: string; +} + +interface AcmeAccountActorMetadata { + profileId: string; + accountId: string; +} + interface UnknownUserActorMetadata {} export interface UserActor { @@ -652,7 +690,25 @@ export interface ScimClientActor { metadata: ScimClientActorMetadata; } -export type Actor = UserActor | ServiceActor | IdentityActor | ScimClientActor | PlatformActor | KmipClientActor; +export interface AcmeProfileActor { + type: ActorType.ACME_PROFILE; + metadata: AcmeProfileActorMetadata; +} + +export interface AcmeAccountActor { + type: ActorType.ACME_ACCOUNT; + metadata: AcmeAccountActorMetadata; +} + +export type Actor = + | UserActor + | ServiceActor + | IdentityActor + | ScimClientActor + | PlatformActor + | KmipClientActor + | AcmeProfileActor + | AcmeAccountActor; interface GetSecretsEvent { type: EventType.GET_SECRETS; @@ -4248,6 +4304,18 @@ interface GetCertificateFromRequestEvent { }; } +interface ListCertificateRequestsEvent { + type: EventType.LIST_CERTIFICATE_REQUESTS; + metadata: { + offset: number; + limit: number; + search?: string; + status?: string; + count: number; + certificateRequestIds: string[]; + }; +} + interface ApprovalPolicyCreateEvent { type: EventType.APPROVAL_POLICY_CREATE; metadata: { @@ -4368,6 +4436,235 @@ interface ApprovalRequestGrantRevokeEvent { }; } +interface CreateAcmeAccountEvent { + type: EventType.CREATE_ACME_ACCOUNT; + metadata: { + accountId: string; + publicKeyThumbprint: string; + emails?: string[]; + }; +} + +interface RetrieveAcmeAccountEvent { + type: EventType.RETRIEVE_ACME_ACCOUNT; + metadata: { + accountId: string; + publicKeyThumbprint: string; + }; +} + +interface CreateAcmeOrderEvent { + type: EventType.CREATE_ACME_ORDER; + metadata: { + orderId: string; + identifiers: Array<{ + type: AcmeIdentifierType; + value: string; + }>; + }; +} + +interface FinalizeAcmeOrderEvent { + type: EventType.FINALIZE_ACME_ORDER; + metadata: { + orderId: string; + csr: string; + }; +} + +interface DownloadAcmeCertificateEvent { + type: EventType.DOWNLOAD_ACME_CERTIFICATE; + metadata: { + orderId: string; + }; +} + +interface RespondToAcmeChallengeEvent { + type: EventType.RESPOND_TO_ACME_CHALLENGE; + metadata: { + challengeId: string; + type: AcmeChallengeType; + }; +} +interface PassedAcmeChallengeEvent { + type: EventType.PASS_ACME_CHALLENGE; + metadata: { + challengeId: string; + type: AcmeChallengeType; + }; +} + +interface AttemptAcmeChallengeEvent { + type: EventType.ATTEMPT_ACME_CHALLENGE; + metadata: { + challengeId: string; + type: AcmeChallengeType; + retryCount: number; + errorMessage: string; + }; +} + +interface FailAcmeChallengeEvent { + type: EventType.FAIL_ACME_CHALLENGE; + metadata: { + challengeId: string; + type: AcmeChallengeType; + retryCount: number; + errorMessage: string; + }; +} + +interface GetDynamicSecretLeaseEvent { + type: EventType.GET_DYNAMIC_SECRET_LEASE; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + leaseId: string; + leaseExternalEntityId: string; + leaseExpireAt: Date; + + projectId: string; + environment: string; + secretPath: string; + }; +} + +interface RenewDynamicSecretLeaseEvent { + type: EventType.RENEW_DYNAMIC_SECRET_LEASE; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + leaseId: string; + leaseExternalEntityId: string; + newLeaseExpireAt: Date; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface CreateDynamicSecretLeaseEvent { + type: EventType.CREATE_DYNAMIC_SECRET_LEASE; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + leaseId: string; + leaseExternalEntityId: string; + leaseExpireAt: Date; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface DeleteDynamicSecretLeaseEvent { + type: EventType.DELETE_DYNAMIC_SECRET_LEASE; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + leaseId: string; + leaseExternalEntityId: string; + leaseStatus?: string | null; + + environment: string; + secretPath: string; + projectId: string; + + isForced: boolean; + }; +} + +interface CreateDynamicSecretEvent { + type: EventType.CREATE_DYNAMIC_SECRET; + metadata: { + dynamicSecretName: string; + dynamicSecretType: string; + dynamicSecretId: string; + defaultTTL: string; + maxTTL?: string | null; + gatewayV2Id?: string | null; + usernameTemplate?: string | null; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface UpdateDynamicSecretEvent { + type: EventType.UPDATE_DYNAMIC_SECRET; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + updatedFields: string[]; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface DeleteDynamicSecretEvent { + type: EventType.DELETE_DYNAMIC_SECRET; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface GetDynamicSecretEvent { + type: EventType.GET_DYNAMIC_SECRET; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface ListDynamicSecretsEvent { + type: EventType.LIST_DYNAMIC_SECRETS; + metadata: { + environment: string; + secretPath: string; + projectId: string; + }; +} + +interface ListDynamicSecretLeasesEvent { + type: EventType.LIST_DYNAMIC_SECRET_LEASES; + metadata: { + dynamicSecretName: string; + dynamicSecretId: string; + dynamicSecretType: string; + + environment: string; + secretPath: string; + projectId: string; + + leaseCount: number; + }; +} + export type Event = | CreateSubOrganizationEvent | UpdateSubOrganizationEvent @@ -4750,6 +5047,7 @@ export type Event = | CreateCertificateRequestEvent | GetCertificateRequestEvent | GetCertificateFromRequestEvent + | ListCertificateRequestsEvent | AutomatedRenewCertificate | AutomatedRenewCertificateFailed | UserLoginEvent @@ -4768,4 +5066,23 @@ export type Event = | ApprovalRequestCancelEvent | ApprovalRequestGrantListEvent | ApprovalRequestGrantGetEvent - | ApprovalRequestGrantRevokeEvent; + | ApprovalRequestGrantRevokeEvent + | CreateAcmeAccountEvent + | RetrieveAcmeAccountEvent + | CreateAcmeOrderEvent + | FinalizeAcmeOrderEvent + | DownloadAcmeCertificateEvent + | RespondToAcmeChallengeEvent + | PassedAcmeChallengeEvent + | AttemptAcmeChallengeEvent + | FailAcmeChallengeEvent + | CreateDynamicSecretEvent + | UpdateDynamicSecretEvent + | DeleteDynamicSecretEvent + | GetDynamicSecretEvent + | ListDynamicSecretsEvent + | ListDynamicSecretLeasesEvent + | CreateDynamicSecretLeaseEvent + | DeleteDynamicSecretLeaseEvent + | RenewDynamicSecretLeaseEvent + | GetDynamicSecretLeaseEvent; diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index ea5efd5024..13c24ce46c 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -179,7 +179,14 @@ export const dynamicSecretLeaseServiceFactory = ({ }); await dynamicSecretQueueService.setLeaseRevocation(dynamicSecretLease.id, dynamicSecretCfg.id, expireAt); - return { lease: dynamicSecretLease, dynamicSecret: dynamicSecretCfg, data }; + return { + lease: dynamicSecretLease, + dynamicSecret: dynamicSecretCfg, + data, + projectId, + environment: environmentSlug, + secretPath: path + }; }; const renewLease: TDynamicSecretLeaseServiceFactory["renewLease"] = async ({ @@ -277,7 +284,13 @@ export const dynamicSecretLeaseServiceFactory = ({ expireAt, externalEntityId: entityId }); - return updatedDynamicSecretLease; + return { + lease: updatedDynamicSecretLease, + dynamicSecret: dynamicSecretCfg, + projectId, + environment: environmentSlug, + secretPath: path + }; }; const revokeLease: TDynamicSecretLeaseServiceFactory["revokeLease"] = async ({ @@ -364,12 +377,24 @@ export const dynamicSecretLeaseServiceFactory = ({ }); // queue a job to retry the revocation at a later time await dynamicSecretQueueService.queueFailedRevocation(dynamicSecretLease.id, dynamicSecretCfg.id); - return updatedDynamicSecretLease; + return { + lease: updatedDynamicSecretLease, + dynamicSecret: dynamicSecretCfg, + projectId, + environment: environmentSlug, + secretPath: path + }; } await dynamicSecretQueueService.unsetLeaseRevocation(dynamicSecretLease.id); const deletedDynamicSecretLease = await dynamicSecretLeaseDAL.deleteById(dynamicSecretLease.id); - return deletedDynamicSecretLease; + return { + lease: deletedDynamicSecretLease, + dynamicSecret: dynamicSecretCfg, + projectId, + environment: environmentSlug, + secretPath: path + }; }; const listLeases: TDynamicSecretLeaseServiceFactory["listLeases"] = async ({ @@ -417,7 +442,13 @@ export const dynamicSecretLeaseServiceFactory = ({ ); const dynamicSecretLeases = await dynamicSecretLeaseDAL.find({ dynamicSecretId: dynamicSecretCfg.id }); - return dynamicSecretLeases; + return { + leases: dynamicSecretLeases, + dynamicSecret: dynamicSecretCfg, + projectId, + environment: environmentSlug, + secretPath: path + }; }; const getLeaseDetails: TDynamicSecretLeaseServiceFactory["getLeaseDetails"] = async ({ @@ -469,7 +500,13 @@ export const dynamicSecretLeaseServiceFactory = ({ }) ); - return dynamicSecretLease; + return { + lease: dynamicSecretLease, + dynamicSecret: dynamicSecretCfg, + projectId, + environment: environmentSlug, + secretPath: path + }; }; return { diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-types.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-types.ts index c6dfe7b165..02b16679be 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-types.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-types.ts @@ -55,34 +55,36 @@ export type TDynamicSecretLeaseServiceFactory = { lease: TDynamicSecretLeases; dynamicSecret: TDynamicSecretWithMetadata; data: unknown; + projectId: string; + environment: string; + secretPath: string; + }>; + listLeases: (arg: TListDynamicSecretLeasesDTO) => Promise<{ + leases: TDynamicSecretLeases[]; + dynamicSecret: TDynamicSecretWithMetadata; + projectId: string; + environment: string; + secretPath: string; + }>; + revokeLease: (arg: TDeleteDynamicSecretLeaseDTO) => Promise<{ + lease: TDynamicSecretLeases; + dynamicSecret: TDynamicSecretWithMetadata; + projectId: string; + environment: string; + secretPath: string; + }>; + renewLease: (arg: TRenewDynamicSecretLeaseDTO) => Promise<{ + lease: TDynamicSecretLeases; + dynamicSecret: TDynamicSecretWithMetadata; + projectId: string; + environment: string; + secretPath: string; }>; - listLeases: (arg: TListDynamicSecretLeasesDTO) => Promise; - revokeLease: (arg: TDeleteDynamicSecretLeaseDTO) => Promise; - renewLease: (arg: TRenewDynamicSecretLeaseDTO) => Promise; getLeaseDetails: (arg: TDetailsDynamicSecretLeaseDTO) => Promise<{ - dynamicSecret: { - id: string; - name: string; - version: number; - type: string; - defaultTTL: string; - maxTTL: string | null | undefined; - encryptedInput: Buffer; - folderId: string; - status: string | null | undefined; - statusDetails: string | null | undefined; - createdAt: Date; - updatedAt: Date; - }; - version: number; - id: string; - createdAt: Date; - updatedAt: Date; - externalEntityId: string; - expireAt: Date; - dynamicSecretId: string; - status?: string | null | undefined; - config?: unknown; - statusDetails?: string | null | undefined; + dynamicSecret: TDynamicSecretWithMetadata; + lease: TDynamicSecretLeases; + projectId: string; + environment: string; + secretPath: string; }>; }; diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-fns.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-fns.ts index e9fc2b6e5e..a1234f9421 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-fns.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-fns.ts @@ -6,6 +6,8 @@ import { BadRequestError } from "@app/lib/errors"; import { isPrivateIp } from "@app/lib/ip/ipRange"; import { getDbConnectionHost } from "@app/lib/knex"; +const ERROR_MESSAGE = "Invalid host"; + export const verifyHostInputValidity = async (host: string, isGateway = false) => { const appCfg = getConfig(); @@ -40,13 +42,13 @@ export const verifyHostInputValidity = async (host: string, isGateway = false) = } } - const normalizedHost = host.split(":")[0]; + const normalizedHost = host.split(":")[0].toLowerCase(); const inputHostIps: string[] = []; if (net.isIPv4(host)) { inputHostIps.push(host); } else { if (normalizedHost === "localhost" || normalizedHost === "host.docker.internal") { - throw new BadRequestError({ message: "Invalid db host" }); + throw new BadRequestError({ message: ERROR_MESSAGE }); } try { const resolvedIps = await dns.resolve4(host); @@ -62,10 +64,10 @@ export const verifyHostInputValidity = async (host: string, isGateway = false) = if (!(appCfg.DYNAMIC_SECRET_ALLOW_INTERNAL_IP || appCfg.ALLOW_INTERNAL_IP_CONNECTIONS)) { const isInternalIp = inputHostIps.some((el) => isPrivateIp(el)); - if (isInternalIp) throw new BadRequestError({ message: "Invalid db host" }); + if (isInternalIp) throw new BadRequestError({ message: ERROR_MESSAGE }); } const isAppUsedIps = inputHostIps.some((el) => exclusiveIps.includes(el)); - if (isAppUsedIps) throw new BadRequestError({ message: "Invalid db host" }); + if (isAppUsedIps) throw new BadRequestError({ message: ERROR_MESSAGE }); return inputHostIps; }; diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index 1372076595..4da278c090 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -9,6 +9,7 @@ import { } from "@app/ee/services/permission/project-permission"; import { crypto } from "@app/lib/crypto"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; +import { extractObjectFieldPaths } from "@app/lib/fn"; import { OrderByDirection } from "@app/lib/types"; import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { KmsDataKey } from "@app/services/kms/kms-types"; @@ -44,6 +45,34 @@ type TDynamicSecretServiceFactoryDep = { resourceMetadataDAL: Pick; }; +const getUpdatedFieldPaths = ( + oldData: Record | null | undefined, + newData: Record | null | undefined +): string[] => { + const updatedPaths = new Set(); + + if (!newData || typeof newData !== "object") { + return []; + } + + if (!oldData || typeof oldData !== "object") { + return []; + } + + Object.keys(newData).forEach((key) => { + const oldValue = oldData?.[key]; + const newValue = newData[key]; + + if (JSON.stringify(oldValue) !== JSON.stringify(newValue)) { + // Extract paths from the new value + const paths = extractObjectFieldPaths(newValue, key); + paths.forEach((path) => updatedPaths.add(path)); + } + }); + + return Array.from(updatedPaths).sort(); +}; + export const dynamicSecretServiceFactory = ({ dynamicSecretDAL, dynamicSecretLeaseDAL, @@ -191,7 +220,13 @@ export const dynamicSecretServiceFactory = ({ return cfg; }); - return { ...dynamicSecretCfg, inputs }; + return { + ...dynamicSecretCfg, + inputs, + projectId: project.id, + environment: environmentSlug, + secretPath: path + }; }; const updateByName: TDynamicSecretServiceFactory["updateByName"] = async ({ @@ -278,8 +313,26 @@ export const dynamicSecretServiceFactory = ({ secretManagerDecryptor({ cipherTextBlob: dynamicSecretCfg.encryptedInput }).toString() ) as object; const newInput = { ...decryptedStoredInput, ...(inputs || {}) }; + const oldInput = await selectedProvider.validateProviderInputs(decryptedStoredInput, { projectId }); const updatedInput = await selectedProvider.validateProviderInputs(newInput, { projectId }); + const updatedFields = getUpdatedFieldPaths( + { + ...(oldInput as object), + maxTTL: dynamicSecretCfg.maxTTL, + defaultTTL: dynamicSecretCfg.defaultTTL, + name: dynamicSecretCfg.name, + usernameTemplate + }, + { + ...(updatedInput as object), + maxTTL, + defaultTTL, + name: newName ?? name, + usernameTemplate + } + ); + let selectedGatewayId: string | null = null; let isGatewayV1 = true; if (updatedInput && typeof updatedInput === "object" && "gatewayId" in updatedInput && updatedInput?.gatewayId) { @@ -357,7 +410,13 @@ export const dynamicSecretServiceFactory = ({ return cfg; }); - return { ...updatedDynamicCfg, inputs: updatedInput }; + return { + dynamicSecret: updatedDynamicCfg, + updatedFields, + projectId: project.id, + environment: environmentSlug, + secretPath: path + }; }; const deleteByName: TDynamicSecretServiceFactory["deleteByName"] = async ({ @@ -412,7 +471,12 @@ export const dynamicSecretServiceFactory = ({ await Promise.all(leases.map(({ id: leaseId }) => dynamicSecretQueueService.unsetLeaseRevocation(leaseId))); const deletedDynamicSecretCfg = await dynamicSecretDAL.deleteById(dynamicSecretCfg.id); - return deletedDynamicSecretCfg; + return { + ...deletedDynamicSecretCfg, + environment: environmentSlug, + secretPath: path, + projectId: project.id + }; } // if leases exist we should flag it as deleting and then remove leases in background // then delete the main one @@ -421,11 +485,21 @@ export const dynamicSecretServiceFactory = ({ status: DynamicSecretStatus.Deleting }); await dynamicSecretQueueService.pruneDynamicSecret(updatedDynamicSecretCfg.id); - return updatedDynamicSecretCfg; + return { + ...updatedDynamicSecretCfg, + environment: environmentSlug, + secretPath: path, + projectId: project.id + }; } // if no leases just delete the config const deletedDynamicSecretCfg = await dynamicSecretDAL.deleteById(dynamicSecretCfg.id); - return deletedDynamicSecretCfg; + return { + ...deletedDynamicSecretCfg, + projectId: project.id, + environment: environmentSlug, + secretPath: path + }; }; const getDetails: TDynamicSecretServiceFactory["getDetails"] = async ({ @@ -491,7 +565,13 @@ export const dynamicSecretServiceFactory = ({ projectId })) as object; - return { ...dynamicSecretCfg, inputs: providerInputs }; + return { + ...dynamicSecretCfg, + inputs: providerInputs, + projectId: project.id, + environment: environmentSlug, + secretPath: path + }; }; // get unique dynamic secret count across multiple envs @@ -622,16 +702,21 @@ export const dynamicSecretServiceFactory = ({ } ); - return dynamicSecretCfg.filter((dynamicSecret) => { - return permission.can( - ProjectPermissionDynamicSecretActions.ReadRootCredential, - subject(ProjectPermissionSub.DynamicSecrets, { - environment: environmentSlug, - secretPath: path, - metadata: dynamicSecret.metadata - }) - ); - }); + return { + dynamicSecrets: dynamicSecretCfg.filter((dynamicSecret) => { + return permission.can( + ProjectPermissionDynamicSecretActions.ReadRootCredential, + subject(ProjectPermissionSub.DynamicSecrets, { + environment: environmentSlug, + secretPath: path, + metadata: dynamicSecret.metadata + }) + ); + }), + environment: environmentSlug, + secretPath: path, + projectId + }; }; const listDynamicSecretsByFolderIds: TDynamicSecretServiceFactory["listDynamicSecretsByFolderIds"] = async ( diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-types.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-types.ts index 0e135caef6..d5fa291b5a 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-types.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-types.ts @@ -86,11 +86,28 @@ export type TGetDynamicSecretsCountDTO = Omit Promise; - updateByName: (arg: TUpdateDynamicSecretDTO) => Promise; - deleteByName: (arg: TDeleteDynamicSecretDTO) => Promise; - getDetails: (arg: TDetailsDynamicSecretDTO) => Promise; - listDynamicSecretsByEnv: (arg: TListDynamicSecretsDTO) => Promise; + create: ( + arg: TCreateDynamicSecretDTO + ) => Promise; + updateByName: (arg: TUpdateDynamicSecretDTO) => Promise<{ + dynamicSecret: TDynamicSecrets; + updatedFields: string[]; + projectId: string; + environment: string; + secretPath: string; + }>; + deleteByName: ( + arg: TDeleteDynamicSecretDTO + ) => Promise; + getDetails: ( + arg: TDetailsDynamicSecretDTO + ) => Promise; + listDynamicSecretsByEnv: (arg: TListDynamicSecretsDTO) => Promise<{ + dynamicSecrets: Array; + environment: string; + secretPath: string; + projectId: string; + }>; listDynamicSecretsByEnvs: ( arg: TListDynamicSecretsMultiEnvDTO ) => Promise>; diff --git a/backend/src/ee/services/external-kms/external-kms-service.ts b/backend/src/ee/services/external-kms/external-kms-service.ts index eb595ee020..af246eacdc 100644 --- a/backend/src/ee/services/external-kms/external-kms-service.ts +++ b/backend/src/ee/services/external-kms/external-kms-service.ts @@ -380,6 +380,7 @@ export const externalKmsServiceFactory = ({ const findById = async ({ actor, actorId, actorOrgId, actorAuthMethod, id: kmsId }: TGetExternalKmsByIdDTO) => { const kmsDoc = await kmsDAL.findById(kmsId); + if (!kmsDoc) throw new NotFoundError({ message: `Could not find KMS with ID '${kmsId}'` }); const { permission } = await permissionService.getOrgPermission({ scope: OrganizationActionScope.Any, actor, diff --git a/backend/src/ee/services/group/group-dal.ts b/backend/src/ee/services/group/group-dal.ts index ced8410b76..eccad82a66 100644 --- a/backend/src/ee/services/group/group-dal.ts +++ b/backend/src/ee/services/group/group-dal.ts @@ -6,7 +6,14 @@ import { DatabaseError } from "@app/lib/errors"; import { buildFindFilter, ormify, selectAllTableCols, TFindFilter, TFindOpt } from "@app/lib/knex"; import { OrderByDirection } from "@app/lib/types"; -import { EFilterReturnedProjects, EFilterReturnedUsers, EGroupProjectsOrderBy } from "./group-types"; +import { + FilterMemberType, + FilterReturnedMachineIdentities, + FilterReturnedProjects, + FilterReturnedUsers, + GroupMembersOrderBy, + GroupProjectsOrderBy +} from "./group-types"; export type TGroupDALFactory = ReturnType; @@ -70,7 +77,7 @@ export const groupDALFactory = (db: TDbClient) => { }; // special query - const findAllGroupPossibleMembers = async ({ + const findAllGroupPossibleUsers = async ({ orgId, groupId, offset = 0, @@ -85,7 +92,7 @@ export const groupDALFactory = (db: TDbClient) => { limit?: number; username?: string; search?: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedUsers; }) => { try { const query = db @@ -127,11 +134,11 @@ export const groupDALFactory = (db: TDbClient) => { } switch (filter) { - case EFilterReturnedUsers.EXISTING_MEMBERS: - void query.andWhere(`${TableName.UserGroupMembership}.createdAt`, "is not", null); + case FilterReturnedUsers.EXISTING_MEMBERS: + void query.whereNotNull(`${TableName.UserGroupMembership}.createdAt`); break; - case EFilterReturnedUsers.NON_MEMBERS: - void query.andWhere(`${TableName.UserGroupMembership}.createdAt`, "is", null); + case FilterReturnedUsers.NON_MEMBERS: + void query.whereNull(`${TableName.UserGroupMembership}.createdAt`); break; default: break; @@ -155,7 +162,7 @@ export const groupDALFactory = (db: TDbClient) => { username: memberUsername, firstName, lastName, - isPartOfGroup: !!memberGroupId, + isPartOfGroup: Boolean(memberGroupId), joinedGroupAt }) ), @@ -167,6 +174,256 @@ export const groupDALFactory = (db: TDbClient) => { } }; + const findAllGroupPossibleMachineIdentities = async ({ + orgId, + groupId, + offset = 0, + limit, + search, + filter + }: { + orgId: string; + groupId: string; + offset?: number; + limit?: number; + search?: string; + filter?: FilterReturnedMachineIdentities; + }) => { + try { + const query = db + .replicaNode()(TableName.Membership) + .where(`${TableName.Membership}.scopeOrgId`, orgId) + .where(`${TableName.Membership}.scope`, AccessScope.Organization) + .whereNotNull(`${TableName.Membership}.actorIdentityId`) + .whereNull(`${TableName.Identity}.projectId`) + .join(TableName.Identity, `${TableName.Membership}.actorIdentityId`, `${TableName.Identity}.id`) + .leftJoin(TableName.IdentityGroupMembership, (bd) => { + bd.on(`${TableName.IdentityGroupMembership}.identityId`, "=", `${TableName.Identity}.id`).andOn( + `${TableName.IdentityGroupMembership}.groupId`, + "=", + db.raw("?", [groupId]) + ); + }) + .select( + db.ref("id").withSchema(TableName.Membership), + db.ref("groupId").withSchema(TableName.IdentityGroupMembership), + db.ref("createdAt").withSchema(TableName.IdentityGroupMembership).as("joinedGroupAt"), + db.ref("name").withSchema(TableName.Identity), + db.ref("id").withSchema(TableName.Identity).as("identityId"), + db.raw(`count(*) OVER() as total_count`) + ) + .offset(offset) + .orderBy("name", "asc"); + + if (limit) { + void query.limit(limit); + } + + if (search) { + void query.andWhereRaw(`LOWER("${TableName.Identity}"."name") ilike ?`, `%${search}%`); + } + + switch (filter) { + case FilterReturnedMachineIdentities.ASSIGNED_MACHINE_IDENTITIES: + void query.whereNotNull(`${TableName.IdentityGroupMembership}.createdAt`); + break; + case FilterReturnedMachineIdentities.NON_ASSIGNED_MACHINE_IDENTITIES: + void query.whereNull(`${TableName.IdentityGroupMembership}.createdAt`); + break; + default: + break; + } + + const machineIdentities = await query; + + return { + machineIdentities: machineIdentities.map(({ name, identityId, joinedGroupAt, groupId: identityGroupId }) => ({ + id: identityId, + name, + isPartOfGroup: Boolean(identityGroupId), + joinedGroupAt + })), + // @ts-expect-error col select is raw and not strongly typed + totalCount: Number(machineIdentities?.[0]?.total_count ?? 0) + }; + } catch (error) { + throw new DatabaseError({ error, name: "Find all group identities" }); + } + }; + + const findAllGroupPossibleMembers = async ({ + orgId, + groupId, + offset = 0, + limit, + search, + orderBy = GroupMembersOrderBy.Name, + orderDirection = OrderByDirection.ASC, + memberTypeFilter + }: { + orgId: string; + groupId: string; + offset?: number; + limit?: number; + search?: string; + orderBy?: GroupMembersOrderBy; + orderDirection?: OrderByDirection; + memberTypeFilter?: FilterMemberType[]; + }) => { + try { + const includeUsers = + !memberTypeFilter || memberTypeFilter.length === 0 || memberTypeFilter.includes(FilterMemberType.USERS); + const includeMachineIdentities = + !memberTypeFilter || + memberTypeFilter.length === 0 || + memberTypeFilter.includes(FilterMemberType.MACHINE_IDENTITIES); + + const query = db + .replicaNode()(TableName.Membership) + .where(`${TableName.Membership}.scopeOrgId`, orgId) + .where(`${TableName.Membership}.scope`, AccessScope.Organization) + .leftJoin(TableName.Users, `${TableName.Membership}.actorUserId`, `${TableName.Users}.id`) + .leftJoin(TableName.Identity, `${TableName.Membership}.actorIdentityId`, `${TableName.Identity}.id`) + .leftJoin(TableName.UserGroupMembership, (bd) => { + bd.on(`${TableName.UserGroupMembership}.userId`, "=", `${TableName.Users}.id`).andOn( + `${TableName.UserGroupMembership}.groupId`, + "=", + db.raw("?", [groupId]) + ); + }) + .leftJoin(TableName.IdentityGroupMembership, (bd) => { + bd.on(`${TableName.IdentityGroupMembership}.identityId`, "=", `${TableName.Identity}.id`).andOn( + `${TableName.IdentityGroupMembership}.groupId`, + "=", + db.raw("?", [groupId]) + ); + }) + .where((qb) => { + void qb + .where((innerQb) => { + void innerQb + .whereNotNull(`${TableName.Membership}.actorUserId`) + .whereNotNull(`${TableName.UserGroupMembership}.createdAt`) + .where(`${TableName.Users}.isGhost`, false); + }) + .orWhere((innerQb) => { + void innerQb + .whereNotNull(`${TableName.Membership}.actorIdentityId`) + .whereNotNull(`${TableName.IdentityGroupMembership}.createdAt`) + .whereNull(`${TableName.Identity}.projectId`); + }); + }) + .select( + db.raw( + `CASE WHEN "${TableName.Membership}"."actorUserId" IS NOT NULL THEN "${TableName.UserGroupMembership}"."createdAt" ELSE "${TableName.IdentityGroupMembership}"."createdAt" END as "joinedGroupAt"` + ), + db.ref("email").withSchema(TableName.Users), + db.ref("username").withSchema(TableName.Users), + db.ref("firstName").withSchema(TableName.Users), + db.ref("lastName").withSchema(TableName.Users), + db.raw(`"${TableName.Users}"."id"::text as "userId"`), + db.raw(`"${TableName.Identity}"."id"::text as "identityId"`), + db.ref("name").withSchema(TableName.Identity).as("identityName"), + db.raw( + `CASE WHEN "${TableName.Membership}"."actorUserId" IS NOT NULL THEN 'user' ELSE 'machineIdentity' END as "member_type"` + ), + db.raw(`count(*) OVER() as total_count`) + ); + + void query.andWhere((qb) => { + if (includeUsers) { + void qb.whereNotNull(`${TableName.Membership}.actorUserId`); + } + + if (includeMachineIdentities) { + void qb[includeUsers ? "orWhere" : "where"]((innerQb) => { + void innerQb.whereNotNull(`${TableName.Membership}.actorIdentityId`); + }); + } + + if (!includeUsers && !includeMachineIdentities) { + void qb.whereRaw("FALSE"); + } + }); + + if (search) { + void query.andWhere((qb) => { + void qb + .whereRaw( + `CONCAT_WS(' ', "${TableName.Users}"."firstName", "${TableName.Users}"."lastName", lower("${TableName.Users}"."username")) ilike ?`, + [`%${search}%`] + ) + .orWhereRaw(`LOWER("${TableName.Identity}"."name") ilike ?`, [`%${search}%`]); + }); + } + + if (orderBy === GroupMembersOrderBy.Name) { + const orderDirectionClause = orderDirection === OrderByDirection.ASC ? "ASC" : "DESC"; + + // This order by clause is used to sort the members by name. + // It first checks if the full name (first name and last name) is not empty, then the username, then the email, then the identity name. If all of these are empty, it returns null. + void query.orderByRaw( + `LOWER(COALESCE(NULLIF(TRIM(CONCAT_WS(' ', "${TableName.Users}"."firstName", "${TableName.Users}"."lastName")), ''), "${TableName.Users}"."username", "${TableName.Users}"."email", "${TableName.Identity}"."name")) ${orderDirectionClause}` + ); + } + + if (offset) { + void query.offset(offset); + } + if (limit) { + void query.limit(limit); + } + + const results = (await query) as unknown as { + email: string; + username: string; + firstName: string; + lastName: string; + userId: string; + identityId: string; + identityName: string; + member_type: "user" | "machineIdentity"; + joinedGroupAt: Date; + total_count: string; + }[]; + + const members = results.map( + ({ email, username, firstName, lastName, userId, identityId, identityName, member_type, joinedGroupAt }) => { + if (member_type === "user") { + return { + id: userId, + joinedGroupAt, + type: "user" as const, + user: { + id: userId, + email, + username, + firstName, + lastName + } + }; + } + return { + id: identityId, + joinedGroupAt, + type: "machineIdentity" as const, + machineIdentity: { + id: identityId, + name: identityName + } + }; + } + ); + + return { + members, + totalCount: Number(results?.[0]?.total_count ?? 0) + }; + } catch (error) { + throw new DatabaseError({ error, name: "Find all group possible members" }); + } + }; + const findAllGroupProjects = async ({ orgId, groupId, @@ -182,8 +439,8 @@ export const groupDALFactory = (db: TDbClient) => { offset?: number; limit?: number; search?: string; - filter?: EFilterReturnedProjects; - orderBy?: EGroupProjectsOrderBy; + filter?: FilterReturnedProjects; + orderBy?: GroupProjectsOrderBy; orderDirection?: OrderByDirection; }) => { try { @@ -225,10 +482,10 @@ export const groupDALFactory = (db: TDbClient) => { } switch (filter) { - case EFilterReturnedProjects.ASSIGNED_PROJECTS: + case FilterReturnedProjects.ASSIGNED_PROJECTS: void query.whereNotNull(`${TableName.Membership}.id`); break; - case EFilterReturnedProjects.UNASSIGNED_PROJECTS: + case FilterReturnedProjects.UNASSIGNED_PROJECTS: void query.whereNull(`${TableName.Membership}.id`); break; default: @@ -313,6 +570,8 @@ export const groupDALFactory = (db: TDbClient) => { ...groupOrm, findGroups, findByOrgId, + findAllGroupPossibleUsers, + findAllGroupPossibleMachineIdentities, findAllGroupPossibleMembers, findAllGroupProjects, findGroupsByProjectId, diff --git a/backend/src/ee/services/group/group-fns.ts b/backend/src/ee/services/group/group-fns.ts index c4384cc4e2..e42a86261e 100644 --- a/backend/src/ee/services/group/group-fns.ts +++ b/backend/src/ee/services/group/group-fns.ts @@ -5,9 +5,11 @@ import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError, ForbiddenRequestError, NotFoundError, ScimRequestError } from "@app/lib/errors"; import { + TAddIdentitiesToGroup, TAddUsersToGroup, TAddUsersToGroupByUserIds, TConvertPendingGroupAdditionsToGroupMemberships, + TRemoveIdentitiesFromGroup, TRemoveUsersFromGroupByUserIds } from "./group-types"; @@ -285,6 +287,70 @@ export const addUsersToGroupByUserIds = async ({ }); }; +/** + * Add identities with identity ids [identityIds] to group [group]. + * @param {group} group - group to add identity(s) to + * @param {string[]} identityIds - id(s) of organization scoped identity(s) to add to group + * @returns {Promise<{ id: string }[]>} - id(s) of added identity(s) + */ +export const addIdentitiesToGroup = async ({ + group, + identityIds, + identityDAL, + identityGroupMembershipDAL, + membershipDAL +}: TAddIdentitiesToGroup) => { + const identityIdsSet = new Set(identityIds); + const identityIdsArray = Array.from(identityIdsSet); + + // ensure all identities exist and belong to the org via org scoped membership + const foundIdentitiesMemberships = await membershipDAL.find({ + scope: AccessScope.Organization, + scopeOrgId: group.orgId, + $in: { + actorIdentityId: identityIdsArray + } + }); + + const existingIdentityOrgMembershipsIdentityIdsSet = new Set( + foundIdentitiesMemberships.map((u) => u.actorIdentityId as string) + ); + + identityIdsArray.forEach((identityId) => { + if (!existingIdentityOrgMembershipsIdentityIdsSet.has(identityId)) { + throw new ForbiddenRequestError({ + message: `Identity with id ${identityId} is not part of the organization` + }); + } + }); + + // check if identity group membership already exists + const existingIdentityGroupMemberships = await identityGroupMembershipDAL.find({ + groupId: group.id, + $in: { + identityId: identityIdsArray + } + }); + + if (existingIdentityGroupMemberships.length) { + throw new BadRequestError({ + message: `${identityIdsArray.length > 1 ? `Identities are` : `Identity is`} already part of the group ${group.slug}` + }); + } + + return identityDAL.transaction(async (tx) => { + await identityGroupMembershipDAL.insertMany( + foundIdentitiesMemberships.map((membership) => ({ + identityId: membership.actorIdentityId as string, + groupId: group.id + })), + tx + ); + + return identityIdsArray.map((identityId) => ({ id: identityId })); + }); +}; + /** * Remove users with user ids [userIds] from group [group]. * - Users may be part of the group (non-pending + pending); @@ -421,6 +487,75 @@ export const removeUsersFromGroupByUserIds = async ({ }); }; +/** + * Remove identities with identity ids [identityIds] from group [group]. + * @param {group} group - group to remove identity(s) from + * @param {string[]} identityIds - id(s) of identity(s) to remove from group + * @returns {Promise<{ id: string }[]>} - id(s) of removed identity(s) + */ +export const removeIdentitiesFromGroup = async ({ + group, + identityIds, + identityDAL, + membershipDAL, + identityGroupMembershipDAL +}: TRemoveIdentitiesFromGroup) => { + const identityIdsSet = new Set(identityIds); + const identityIdsArray = Array.from(identityIdsSet); + + // ensure all identities exist and belong to the org via org scoped membership + const foundIdentitiesMemberships = await membershipDAL.find({ + scope: AccessScope.Organization, + scopeOrgId: group.orgId, + $in: { + actorIdentityId: identityIdsArray + } + }); + + const foundIdentitiesMembershipsIdentityIdsSet = new Set( + foundIdentitiesMemberships.map((u) => u.actorIdentityId as string) + ); + + if (foundIdentitiesMembershipsIdentityIdsSet.size !== identityIdsArray.length) { + throw new NotFoundError({ + message: `Machine identities not found` + }); + } + + // check if identity group membership already exists + const existingIdentityGroupMemberships = await identityGroupMembershipDAL.find({ + groupId: group.id, + $in: { + identityId: identityIdsArray + } + }); + + const existingIdentityGroupMembershipsIdentityIdsSet = new Set( + existingIdentityGroupMemberships.map((u) => u.identityId) + ); + + identityIdsArray.forEach((identityId) => { + if (!existingIdentityGroupMembershipsIdentityIdsSet.has(identityId)) { + throw new ForbiddenRequestError({ + message: `Machine identities are not part of the group ${group.slug}` + }); + } + }); + return identityDAL.transaction(async (tx) => { + await identityGroupMembershipDAL.delete( + { + groupId: group.id, + $in: { + identityId: identityIdsArray + } + }, + tx + ); + + return identityIdsArray.map((identityId) => ({ id: identityId })); + }); +}; + /** * Convert pending group additions for users with ids [userIds] to group memberships. * @param {string[]} userIds - id(s) of user(s) to try to convert pending group additions to group memberships diff --git a/backend/src/ee/services/group/group-service.ts b/backend/src/ee/services/group/group-service.ts index 1a6a046a6b..30d047a776 100644 --- a/backend/src/ee/services/group/group-service.ts +++ b/backend/src/ee/services/group/group-service.ts @@ -5,6 +5,8 @@ import { AccessScope, OrganizationActionScope, OrgMembershipRole, TRoles } from import { TOidcConfigDALFactory } from "@app/ee/services/oidc/oidc-config-dal"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { alphaNumericNanoId } from "@app/lib/nanoid"; +import { TIdentityDALFactory } from "@app/services/identity/identity-dal"; +import { TMembershipDALFactory } from "@app/services/membership/membership-dal"; import { TMembershipRoleDALFactory } from "@app/services/membership/membership-role-dal"; import { TMembershipGroupDALFactory } from "@app/services/membership-group/membership-group-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal"; @@ -18,33 +20,48 @@ import { OrgPermissionGroupActions, OrgPermissionSubjects } from "../permission/ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TGroupDALFactory } from "./group-dal"; -import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "./group-fns"; import { + addIdentitiesToGroup, + addUsersToGroupByUserIds, + removeIdentitiesFromGroup, + removeUsersFromGroupByUserIds +} from "./group-fns"; +import { + TAddMachineIdentityToGroupDTO, TAddUserToGroupDTO, TCreateGroupDTO, TDeleteGroupDTO, TGetGroupByIdDTO, + TListGroupMachineIdentitiesDTO, + TListGroupMembersDTO, TListGroupProjectsDTO, TListGroupUsersDTO, + TRemoveMachineIdentityFromGroupDTO, TRemoveUserFromGroupDTO, TUpdateGroupDTO } from "./group-types"; +import { TIdentityGroupMembershipDALFactory } from "./identity-group-membership-dal"; import { TUserGroupMembershipDALFactory } from "./user-group-membership-dal"; type TGroupServiceFactoryDep = { userDAL: Pick; + identityDAL: Pick; + identityGroupMembershipDAL: Pick; groupDAL: Pick< TGroupDALFactory, | "create" | "findOne" | "update" | "delete" + | "findAllGroupPossibleUsers" + | "findAllGroupPossibleMachineIdentities" | "findAllGroupPossibleMembers" | "findById" | "transaction" | "findAllGroupProjects" >; membershipGroupDAL: Pick; + membershipDAL: Pick; membershipRoleDAL: Pick; orgDAL: Pick; userGroupMembershipDAL: Pick< @@ -65,6 +82,9 @@ type TGroupServiceFactoryDep = { export type TGroupServiceFactory = ReturnType; export const groupServiceFactory = ({ + identityDAL, + membershipDAL, + identityGroupMembershipDAL, userDAL, groupDAL, orgDAL, @@ -362,7 +382,7 @@ export const groupServiceFactory = ({ message: `Failed to find group with ID ${id}` }); - const { members, totalCount } = await groupDAL.findAllGroupPossibleMembers({ + const { members, totalCount } = await groupDAL.findAllGroupPossibleUsers({ orgId: group.orgId, groupId: group.id, offset, @@ -375,6 +395,100 @@ export const groupServiceFactory = ({ return { users: members, totalCount }; }; + const listGroupMachineIdentities = async ({ + id, + offset, + limit, + actor, + actorId, + actorAuthMethod, + actorOrgId, + search, + filter + }: TListGroupMachineIdentitiesDTO) => { + if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID provided in request" }); + + const { permission } = await permissionService.getOrgPermission({ + scope: OrganizationActionScope.Any, + actor, + actorId, + orgId: actorOrgId, + actorAuthMethod, + actorOrgId + }); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Read, OrgPermissionSubjects.Groups); + + const group = await groupDAL.findOne({ + orgId: actorOrgId, + id + }); + + if (!group) + throw new NotFoundError({ + message: `Failed to find group with ID ${id}` + }); + + const { machineIdentities, totalCount } = await groupDAL.findAllGroupPossibleMachineIdentities({ + orgId: group.orgId, + groupId: group.id, + offset, + limit, + search, + filter + }); + + return { machineIdentities, totalCount }; + }; + + const listGroupMembers = async ({ + id, + offset, + limit, + search, + orderBy, + orderDirection, + memberTypeFilter, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TListGroupMembersDTO) => { + if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID provided in request" }); + + const { permission } = await permissionService.getOrgPermission({ + scope: OrganizationActionScope.Any, + actor, + actorId, + orgId: actorOrgId, + actorAuthMethod, + actorOrgId + }); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Read, OrgPermissionSubjects.Groups); + + const group = await groupDAL.findOne({ + orgId: actorOrgId, + id + }); + + if (!group) + throw new NotFoundError({ + message: `Failed to find group with ID ${id}` + }); + + const { members, totalCount } = await groupDAL.findAllGroupPossibleMembers({ + orgId: group.orgId, + groupId: group.id, + offset, + limit, + search, + orderBy, + orderDirection, + memberTypeFilter + }); + + return { members, totalCount }; + }; + const listGroupProjects = async ({ id, offset, @@ -504,6 +618,81 @@ export const groupServiceFactory = ({ return users[0]; }; + const addMachineIdentityToGroup = async ({ + id, + identityId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TAddMachineIdentityToGroupDTO) => { + if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID provided in request" }); + + const { permission } = await permissionService.getOrgPermission({ + scope: OrganizationActionScope.Any, + actor, + actorId, + orgId: actorOrgId, + actorAuthMethod, + actorOrgId + }); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups); + + // check if group with slug exists + const group = await groupDAL.findOne({ + orgId: actorOrgId, + id + }); + + if (!group) + throw new NotFoundError({ + message: `Failed to find group with ID ${id}` + }); + + const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId); + const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId); + + // check if user has broader or equal to privileges than group + const permissionBoundary = validatePrivilegeChangeOperation( + shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.AddIdentities, + OrgPermissionSubjects.Groups, + permission, + rolePermissionDetails.permission + ); + + if (!permissionBoundary.isValid) + throw new PermissionBoundaryError({ + message: constructPermissionErrorMessage( + "Failed to add identity to more privileged group", + shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.AddIdentities, + OrgPermissionSubjects.Groups + ), + details: { missingPermissions: permissionBoundary.missingPermissions } + }); + + const identityMembership = await membershipDAL.findOne({ + scope: AccessScope.Organization, + scopeOrgId: group.orgId, + actorIdentityId: identityId + }); + + if (!identityMembership) { + throw new NotFoundError({ message: `Identity with id ${identityId} is not part of the organization` }); + } + + const identities = await addIdentitiesToGroup({ + group, + identityIds: [identityId], + identityDAL, + membershipDAL, + identityGroupMembershipDAL + }); + + return identities[0]; + }; + const removeUserFromGroup = async ({ id, username, @@ -587,14 +776,91 @@ export const groupServiceFactory = ({ return users[0]; }; + const removeMachineIdentityFromGroup = async ({ + id, + identityId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TRemoveMachineIdentityFromGroupDTO) => { + if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID provided in request" }); + + const { permission } = await permissionService.getOrgPermission({ + scope: OrganizationActionScope.Any, + actor, + actorId, + orgId: actorOrgId, + actorAuthMethod, + actorOrgId + }); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups); + + const group = await groupDAL.findOne({ + orgId: actorOrgId, + id + }); + + if (!group) + throw new NotFoundError({ + message: `Failed to find group with ID ${id}` + }); + + const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId); + const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId); + + // check if user has broader or equal to privileges than group + const permissionBoundary = validatePrivilegeChangeOperation( + shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.RemoveIdentities, + OrgPermissionSubjects.Groups, + permission, + rolePermissionDetails.permission + ); + if (!permissionBoundary.isValid) + throw new PermissionBoundaryError({ + message: constructPermissionErrorMessage( + "Failed to remove identity from more privileged group", + shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.RemoveIdentities, + OrgPermissionSubjects.Groups + ), + details: { missingPermissions: permissionBoundary.missingPermissions } + }); + + const identityMembership = await membershipDAL.findOne({ + scope: AccessScope.Organization, + scopeOrgId: group.orgId, + actorIdentityId: identityId + }); + + if (!identityMembership) { + throw new NotFoundError({ message: `Identity with id ${identityId} is not part of the organization` }); + } + + const identities = await removeIdentitiesFromGroup({ + group, + identityIds: [identityId], + identityDAL, + membershipDAL, + identityGroupMembershipDAL + }); + + return identities[0]; + }; + return { createGroup, updateGroup, deleteGroup, listGroupUsers, + listGroupMachineIdentities, + listGroupMembers, listGroupProjects, addUserToGroup, + addMachineIdentityToGroup, removeUserFromGroup, + removeMachineIdentityFromGroup, getGroupById }; }; diff --git a/backend/src/ee/services/group/group-types.ts b/backend/src/ee/services/group/group-types.ts index 335b6d72bb..044dc4bca1 100644 --- a/backend/src/ee/services/group/group-types.ts +++ b/backend/src/ee/services/group/group-types.ts @@ -3,6 +3,8 @@ import { Knex } from "knex"; import { TGroups } from "@app/db/schemas"; import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal"; import { OrderByDirection, TGenericPermission } from "@app/lib/types"; +import { TIdentityDALFactory } from "@app/services/identity/identity-dal"; +import { TMembershipDALFactory } from "@app/services/membership/membership-dal"; import { TMembershipGroupDALFactory } from "@app/services/membership-group/membership-group-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; @@ -10,6 +12,8 @@ import { TProjectBotDALFactory } from "@app/services/project-bot/project-bot-dal import { TProjectKeyDALFactory } from "@app/services/project-key/project-key-dal"; import { TUserDALFactory } from "@app/services/user/user-dal"; +import { TIdentityGroupMembershipDALFactory } from "./identity-group-membership-dal"; + export type TCreateGroupDTO = { name: string; slug?: string; @@ -39,7 +43,25 @@ export type TListGroupUsersDTO = { limit: number; username?: string; search?: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedUsers; +} & TGenericPermission; + +export type TListGroupMachineIdentitiesDTO = { + id: string; + offset: number; + limit: number; + search?: string; + filter?: FilterReturnedMachineIdentities; +} & TGenericPermission; + +export type TListGroupMembersDTO = { + id: string; + offset: number; + limit: number; + search?: string; + orderBy?: GroupMembersOrderBy; + orderDirection?: OrderByDirection; + memberTypeFilter?: FilterMemberType[]; } & TGenericPermission; export type TListGroupProjectsDTO = { @@ -47,8 +69,8 @@ export type TListGroupProjectsDTO = { offset: number; limit: number; search?: string; - filter?: EFilterReturnedProjects; - orderBy?: EGroupProjectsOrderBy; + filter?: FilterReturnedProjects; + orderBy?: GroupProjectsOrderBy; orderDirection?: OrderByDirection; } & TGenericPermission; @@ -61,11 +83,21 @@ export type TAddUserToGroupDTO = { username: string; } & TGenericPermission; +export type TAddMachineIdentityToGroupDTO = { + id: string; + identityId: string; +} & TGenericPermission; + export type TRemoveUserFromGroupDTO = { id: string; username: string; } & TGenericPermission; +export type TRemoveMachineIdentityFromGroupDTO = { + id: string; + identityId: string; +} & TGenericPermission; + // group fns types export type TAddUsersToGroup = { @@ -93,6 +125,14 @@ export type TAddUsersToGroupByUserIds = { tx?: Knex; }; +export type TAddIdentitiesToGroup = { + group: TGroups; + identityIds: string[]; + identityDAL: Pick; + identityGroupMembershipDAL: Pick; + membershipDAL: Pick; +}; + export type TRemoveUsersFromGroupByUserIds = { group: TGroups; userIds: string[]; @@ -103,6 +143,14 @@ export type TRemoveUsersFromGroupByUserIds = { tx?: Knex; }; +export type TRemoveIdentitiesFromGroup = { + group: TGroups; + identityIds: string[]; + identityDAL: Pick; + membershipDAL: Pick; + identityGroupMembershipDAL: Pick; +}; + export type TConvertPendingGroupAdditionsToGroupMemberships = { userIds: string[]; userDAL: Pick; @@ -117,16 +165,30 @@ export type TConvertPendingGroupAdditionsToGroupMemberships = { tx?: Knex; }; -export enum EFilterReturnedUsers { +export enum FilterReturnedUsers { EXISTING_MEMBERS = "existingMembers", NON_MEMBERS = "nonMembers" } -export enum EFilterReturnedProjects { +export enum FilterReturnedMachineIdentities { + ASSIGNED_MACHINE_IDENTITIES = "assignedMachineIdentities", + NON_ASSIGNED_MACHINE_IDENTITIES = "nonAssignedMachineIdentities" +} + +export enum FilterReturnedProjects { ASSIGNED_PROJECTS = "assignedProjects", UNASSIGNED_PROJECTS = "unassignedProjects" } -export enum EGroupProjectsOrderBy { +export enum GroupProjectsOrderBy { Name = "name" } + +export enum GroupMembersOrderBy { + Name = "name" +} + +export enum FilterMemberType { + USERS = "users", + MACHINE_IDENTITIES = "machineIdentities" +} diff --git a/backend/src/ee/services/group/identity-group-membership-dal.ts b/backend/src/ee/services/group/identity-group-membership-dal.ts new file mode 100644 index 0000000000..7b6d67244d --- /dev/null +++ b/backend/src/ee/services/group/identity-group-membership-dal.ts @@ -0,0 +1,13 @@ +import { TDbClient } from "@app/db"; +import { TableName } from "@app/db/schemas"; +import { ormify } from "@app/lib/knex"; + +export type TIdentityGroupMembershipDALFactory = ReturnType; + +export const identityGroupMembershipDALFactory = (db: TDbClient) => { + const identityGroupMembershipOrm = ormify(db, TableName.IdentityGroupMembership); + + return { + ...identityGroupMembershipOrm + }; +}; diff --git a/backend/src/ee/services/permission/org-permission.ts b/backend/src/ee/services/permission/org-permission.ts index 743dcd63fb..0c00c8b408 100644 --- a/backend/src/ee/services/permission/org-permission.ts +++ b/backend/src/ee/services/permission/org-permission.ts @@ -88,8 +88,10 @@ export enum OrgPermissionGroupActions { Edit = "edit", Delete = "delete", GrantPrivileges = "grant-privileges", + AddIdentities = "add-identities", AddMembers = "add-members", - RemoveMembers = "remove-members" + RemoveMembers = "remove-members", + RemoveIdentities = "remove-identities" } export enum OrgPermissionBillingActions { @@ -381,8 +383,10 @@ const buildAdminPermission = () => { can(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups); can(OrgPermissionGroupActions.Delete, OrgPermissionSubjects.Groups); can(OrgPermissionGroupActions.GrantPrivileges, OrgPermissionSubjects.Groups); + can(OrgPermissionGroupActions.AddIdentities, OrgPermissionSubjects.Groups); can(OrgPermissionGroupActions.AddMembers, OrgPermissionSubjects.Groups); can(OrgPermissionGroupActions.RemoveMembers, OrgPermissionSubjects.Groups); + can(OrgPermissionGroupActions.RemoveIdentities, OrgPermissionSubjects.Groups); can(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing); can(OrgPermissionBillingActions.ManageBilling, OrgPermissionSubjects.Billing); diff --git a/backend/src/ee/services/permission/permission-dal.ts b/backend/src/ee/services/permission/permission-dal.ts index efe17edad4..c58bec1561 100644 --- a/backend/src/ee/services/permission/permission-dal.ts +++ b/backend/src/ee/services/permission/permission-dal.ts @@ -178,6 +178,16 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => { .where(`${TableName.UserGroupMembership}.userId`, actorId) .select(db.ref("id").withSchema(TableName.Groups)); + const identityGroupSubquery = (tx || db)(TableName.Groups) + .leftJoin( + TableName.IdentityGroupMembership, + `${TableName.IdentityGroupMembership}.groupId`, + `${TableName.Groups}.id` + ) + .where(`${TableName.Groups}.orgId`, scopeData.orgId) + .where(`${TableName.IdentityGroupMembership}.identityId`, actorId) + .select(db.ref("id").withSchema(TableName.Groups)); + const docs = await (tx || db) .replicaNode()(TableName.Membership) .join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`) @@ -214,7 +224,9 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => { .where(`${TableName.Membership}.actorUserId`, actorId) .orWhereIn(`${TableName.Membership}.actorGroupId`, userGroupSubquery); } else if (actorType === ActorType.IDENTITY) { - void qb.where(`${TableName.Membership}.actorIdentityId`, actorId); + void qb + .where(`${TableName.Membership}.actorIdentityId`, actorId) + .orWhereIn(`${TableName.Membership}.actorGroupId`, identityGroupSubquery); } }) .where((qb) => { @@ -653,6 +665,15 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => { orgId: string ) => { try { + const identityGroupSubquery = db(TableName.Groups) + .leftJoin( + TableName.IdentityGroupMembership, + `${TableName.IdentityGroupMembership}.groupId`, + `${TableName.Groups}.id` + ) + .where(`${TableName.Groups}.orgId`, orgId) + .select(db.ref("id").withSchema(TableName.Groups)); + const docs = await db .replicaNode()(TableName.Membership) .join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`) @@ -668,7 +689,11 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => { void queryBuilder.on(`${TableName.Membership}.actorIdentityId`, `${TableName.IdentityMetadata}.identityId`); }) .where(`${TableName.Membership}.scopeOrgId`, orgId) - .whereNotNull(`${TableName.Membership}.actorIdentityId`) + .where((qb) => { + void qb + .whereNotNull(`${TableName.Membership}.actorIdentityId`) + .orWhereIn(`${TableName.Membership}.actorGroupId`, identityGroupSubquery); + }) .where(`${TableName.Membership}.scope`, AccessScope.Project) .where(`${TableName.Membership}.scopeProjectId`, projectId) .select(selectAllTableCols(TableName.MembershipRole)) diff --git a/backend/src/ee/services/pki-acme/pki-acme-challenge-dal.ts b/backend/src/ee/services/pki-acme/pki-acme-challenge-dal.ts index 74cbd14660..abc3a654b5 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-challenge-dal.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-challenge-dal.ts @@ -122,6 +122,11 @@ export const pkiAcmeChallengeDALFactory = (db: TDbClient) => { const result = await (tx || db)(TableName.PkiAcmeChallenge) .join(TableName.PkiAcmeAuth, `${TableName.PkiAcmeChallenge}.authId`, `${TableName.PkiAcmeAuth}.id`) .join(TableName.PkiAcmeAccount, `${TableName.PkiAcmeAuth}.accountId`, `${TableName.PkiAcmeAccount}.id`) + .join( + TableName.PkiCertificateProfile, + `${TableName.PkiAcmeAccount}.profileId`, + `${TableName.PkiCertificateProfile}.id` + ) .select( selectAllTableCols(TableName.PkiAcmeChallenge), db.ref("id").withSchema(TableName.PkiAcmeAuth).as("authId"), @@ -131,7 +136,9 @@ export const pkiAcmeChallengeDALFactory = (db: TDbClient) => { db.ref("identifierValue").withSchema(TableName.PkiAcmeAuth).as("authIdentifierValue"), db.ref("expiresAt").withSchema(TableName.PkiAcmeAuth).as("authExpiresAt"), db.ref("id").withSchema(TableName.PkiAcmeAccount).as("accountId"), - db.ref("publicKeyThumbprint").withSchema(TableName.PkiAcmeAccount).as("accountPublicKeyThumbprint") + db.ref("publicKeyThumbprint").withSchema(TableName.PkiAcmeAccount).as("accountPublicKeyThumbprint"), + db.ref("profileId").withSchema(TableName.PkiAcmeAccount).as("profileId"), + db.ref("projectId").withSchema(TableName.PkiCertificateProfile).as("projectId") ) // For all challenges, acquire update lock on the auth to avoid race conditions .forUpdate(TableName.PkiAcmeAuth) @@ -149,6 +156,8 @@ export const pkiAcmeChallengeDALFactory = (db: TDbClient) => { authExpiresAt, accountId, accountPublicKeyThumbprint, + profileId, + projectId, ...challenge } = result; return { @@ -161,7 +170,11 @@ export const pkiAcmeChallengeDALFactory = (db: TDbClient) => { expiresAt: authExpiresAt, account: { id: accountId, - publicKeyThumbprint: accountPublicKeyThumbprint + publicKeyThumbprint: accountPublicKeyThumbprint, + project: { + id: projectId + }, + profileId } } }; diff --git a/backend/src/ee/services/pki-acme/pki-acme-challenge-service.ts b/backend/src/ee/services/pki-acme/pki-acme-challenge-service.ts index 7379d7ece2..510d05c044 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-challenge-service.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-challenge-service.ts @@ -1,11 +1,16 @@ +import { resolve4, Resolver } from "node:dns/promises"; + import axios, { AxiosError } from "axios"; import { TPkiAcmeChallenges } from "@app/db/schemas/pki-acme-challenges"; import { getConfig } from "@app/lib/config/env"; +import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { isPrivateIp } from "@app/lib/ip/ipRange"; import { logger } from "@app/lib/logger"; +import { ActorType } from "@app/services/auth/auth-type"; +import { EventType, TAuditLogServiceFactory } from "../audit-log/audit-log-types"; import { TPkiAcmeChallengeDALFactory } from "./pki-acme-challenge-dal"; import { AcmeConnectionError, @@ -15,6 +20,7 @@ import { } from "./pki-acme-errors"; import { AcmeAuthStatus, AcmeChallengeStatus, AcmeChallengeType } from "./pki-acme-schemas"; import { TPkiAcmeChallengeServiceFactory } from "./pki-acme-types"; +import { isValidIp } from "@app/lib/ip"; type TPkiAcmeChallengeServiceFactoryDep = { acmeChallengeDAL: Pick< @@ -25,12 +31,17 @@ type TPkiAcmeChallengeServiceFactoryDep = { | "markAsInvalidCascadeById" | "updateById" >; + auditLogService: Pick; }; export const pkiAcmeChallengeServiceFactory = ({ - acmeChallengeDAL + acmeChallengeDAL, + auditLogService }: TPkiAcmeChallengeServiceFactoryDep): TPkiAcmeChallengeServiceFactory => { const appCfg = getConfig(); + + type ChallengeWithAuth = NonNullable>>; + const markChallengeAsReady = async (challengeId: string): Promise => { return acmeChallengeDAL.transaction(async (tx) => { logger.info({ challengeId }, "Validating ACME challenge response"); @@ -51,31 +62,19 @@ export const pkiAcmeChallengeServiceFactory = ({ message: `ACME auth status is ${challenge.auth.status} instead of ${AcmeAuthStatus.Pending}` }); } - - // TODO: support other challenge types here. Currently only HTTP-01 is supported - if (challenge.type !== AcmeChallengeType.HTTP_01) { - throw new BadRequestError({ message: "Only HTTP-01 challenges are supported for now" }); - } const host = challenge.auth.identifierValue; // check if host is a private ip address if (isPrivateIp(host)) { throw new BadRequestError({ message: "Private IP addresses are not allowed" }); } + if (challenge.type !== AcmeChallengeType.HTTP_01 && challenge.type !== AcmeChallengeType.DNS_01) { + throw new BadRequestError({ message: "Only HTTP-01 or DNS-01 challenges are supported for now" }); + } return acmeChallengeDAL.updateById(challengeId, { status: AcmeChallengeStatus.Processing }, tx); }); }; - const validateChallengeResponse = async (challengeId: string, retryCount: number): Promise => { - logger.info({ challengeId, retryCount }, "Validating ACME challenge response"); - const challenge = await acmeChallengeDAL.findByIdForChallengeValidation(challengeId); - if (!challenge) { - throw new NotFoundError({ message: "ACME challenge not found" }); - } - if (challenge.status !== AcmeChallengeStatus.Processing) { - throw new BadRequestError({ - message: `ACME challenge is ${challenge.status} instead of ${AcmeChallengeStatus.Processing}` - }); - } + const validateHttp01Challenge = async (challenge: ChallengeWithAuth): Promise => { let host = challenge.auth.identifierValue; if (appCfg.isAcmeDevelopmentMode && appCfg.ACME_DEVELOPMENT_HTTP01_CHALLENGE_HOST_OVERRIDES[host]) { host = appCfg.ACME_DEVELOPMENT_HTTP01_CHALLENGE_HOST_OVERRIDES[host]; @@ -86,42 +85,85 @@ export const pkiAcmeChallengeServiceFactory = ({ } const challengeUrl = new URL(`/.well-known/acme-challenge/${challenge.auth.token}`, `http://${host}`); logger.info({ challengeUrl }, "Performing ACME HTTP-01 challenge validation"); - try { - // TODO: read config from the profile to get the timeout instead - const timeoutMs = 10 * 1000; // 10 seconds - // Notice: well, we are in a transaction, ideally we should not hold transaction and perform - // a long running operation for long time. But assuming we are not performing a tons of - // challenge validation at the same time, it should be fine. - const challengeResponse = await axios.get(challengeUrl.toString(), { - // In case if we override the host in the development mode, still provide the original host in the header - // to help the upstream server to validate the request - headers: { Host: challenge.auth.identifierValue }, - timeout: timeoutMs, - responseType: "text", - validateStatus: () => true + + // TODO: read config from the profile to get the timeout instead + const timeoutMs = 10 * 1000; // 10 seconds + // Notice: well, we are in a transaction, ideally we should not hold transaction and perform + // a long running operation for long time. But assuming we are not performing a tons of + // challenge validation at the same time, it should be fine. + const challengeResponse = await axios.get(challengeUrl.toString(), { + // In case if we override the host in the development mode, still provide the original host in the header + // to help the upstream server to validate the request + headers: { Host: challenge.auth.identifierValue }, + timeout: timeoutMs, + responseType: "text", + validateStatus: () => true + }); + + if (challengeResponse.status !== 200) { + throw new AcmeIncorrectResponseError({ + message: `ACME challenge response is not 200: ${challengeResponse.status}` }); - if (challengeResponse.status !== 200) { - throw new AcmeIncorrectResponseError({ - message: `ACME challenge response is not 200: ${challengeResponse.status}` - }); - } - const challengeResponseBody: string = challengeResponse.data; - const thumbprint = challenge.auth.account.publicKeyThumbprint; - const expectedChallengeResponseBody = `${challenge.auth.token}.${thumbprint}`; - if (challengeResponseBody.trimEnd() !== expectedChallengeResponseBody) { - throw new AcmeIncorrectResponseError({ message: "ACME challenge response is not correct" }); - } - logger.info({ challengeId }, "ACME challenge response is correct, marking challenge as valid"); - await acmeChallengeDAL.markAsValidCascadeById(challengeId); - } catch (exp) { - if (retryCount >= 2) { - logger.error( - exp, - `Last attempt to validate ACME challenge response failed, marking ${challengeId} challenge as invalid` - ); - // This is the last attempt to validate the challenge response, if it fails, we mark the challenge as invalid - await acmeChallengeDAL.markAsInvalidCascadeById(challengeId); - } + } + + const challengeResponseBody: string = challengeResponse.data; + const thumbprint = challenge.auth.account.publicKeyThumbprint; + const expectedChallengeResponseBody = `${challenge.auth.token}.${thumbprint}`; + + if (challengeResponseBody.trimEnd() !== expectedChallengeResponseBody) { + throw new AcmeIncorrectResponseError({ message: "ACME HTTP-01 challenge response is not correct" }); + } + }; + + const validateDns01Challenge = async (challenge: ChallengeWithAuth): Promise => { + const resolver = new Resolver(); + if (appCfg.ACME_DNS_RESOLVER_SERVERS.length > 0) { + const servers = appCfg.ACME_DNS_RESOLVE_RESOLVER_SERVERS_HOST_ENABLED + ? await Promise.all( + appCfg.ACME_DNS_RESOLVER_SERVERS.map(async (server) => { + if (isValidIp(server)) { + return server; + } + const ips = await resolve4(server); + return ips[0]; + }) + ) + : appCfg.ACME_DNS_RESOLVER_SERVERS; + resolver.setServers(servers); + } + + const recordName = `_acme-challenge.${challenge.auth.identifierValue}`; + const records = await resolver.resolveTxt(recordName); + const recordValues = records.map((chunks) => chunks.join("")); + + const thumbprint = challenge.auth.account.publicKeyThumbprint; + const keyAuthorization = `${challenge.auth.token}.${thumbprint}`; + const digest = crypto.nativeCrypto.createHash("sha256").update(keyAuthorization).digest(); + const expectedChallengeResponseValue = Buffer.from(digest).toString("base64url"); + + if (!recordValues.some((recordValue) => recordValue.trim() === expectedChallengeResponseValue)) { + throw new AcmeIncorrectResponseError({ message: "ACME DNS-01 challenge response is not correct" }); + } + }; + + const handleChallengeValidationError = async ( + exp: unknown, + challenge: ChallengeWithAuth, + challengeId: string, + retryCount: number + ): Promise => { + let finalAttempt = false; + if (retryCount >= 2) { + logger.error( + exp, + `Last attempt to validate ACME challenge response failed, marking ${challengeId} challenge as invalid` + ); + // This is the last attempt to validate the challenge response, if it fails, we mark the challenge as invalid + await acmeChallengeDAL.markAsInvalidCascadeById(challengeId); + finalAttempt = true; + } + + try { // Properly type and inspect the error if (axios.isAxiosError(exp)) { const axiosError = exp as AxiosError; @@ -145,11 +187,80 @@ export const pkiAcmeChallengeServiceFactory = ({ throw new AcmeServerInternalError({ message: "Unknown error validating ACME challenge response" }); } if (exp instanceof Error) { + if ((exp as unknown as { code?: string })?.code === "ENOTFOUND") { + throw new AcmeDnsFailureError({ message: "Hostname could not be resolved (DNS failure)" }); + } logger.error(exp, "Error validating ACME challenge response"); throw exp; } logger.error(exp, "Unknown error validating ACME challenge response"); throw new AcmeServerInternalError({ message: "Unknown error validating ACME challenge response" }); + } catch (outterExp) { + await auditLogService.createAuditLog({ + projectId: challenge.auth.account.project.id, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId: challenge.auth.account.profileId, + accountId: challenge.auth.account.id + } + }, + event: { + type: finalAttempt ? EventType.FAIL_ACME_CHALLENGE : EventType.ATTEMPT_ACME_CHALLENGE, + metadata: { + challengeId, + type: challenge.type as AcmeChallengeType, + retryCount, + errorMessage: exp instanceof Error ? exp.message : "Unknown error" + } + } + }); + throw outterExp; + } + }; + + const validateChallengeResponse = async (challengeId: string, retryCount: number): Promise => { + logger.info({ challengeId, retryCount }, "Validating ACME challenge response"); + const challenge = await acmeChallengeDAL.findByIdForChallengeValidation(challengeId); + if (!challenge) { + throw new NotFoundError({ message: "ACME challenge not found" }); + } + if (challenge.status !== AcmeChallengeStatus.Processing) { + throw new BadRequestError({ + message: `ACME challenge is ${challenge.status} instead of ${AcmeChallengeStatus.Processing}` + }); + } + + try { + if (challenge.type === AcmeChallengeType.HTTP_01) { + await validateHttp01Challenge(challenge); + } else if (challenge.type === AcmeChallengeType.DNS_01) { + await validateDns01Challenge(challenge); + } else { + throw new BadRequestError({ message: `Unsupported challenge type: ${challenge.type}` }); + } + + logger.info({ challengeId }, "ACME challenge response is correct, marking challenge as valid"); + await acmeChallengeDAL.markAsValidCascadeById(challengeId); + await auditLogService.createAuditLog({ + projectId: challenge.auth.account.project.id, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId: challenge.auth.account.profileId, + accountId: challenge.auth.account.id + } + }, + event: { + type: EventType.PASS_ACME_CHALLENGE, + metadata: { + challengeId, + type: challenge.type as AcmeChallengeType + } + } + }); + } catch (exp) { + await handleChallengeValidationError(exp, challenge, challengeId, retryCount); } }; diff --git a/backend/src/ee/services/pki-acme/pki-acme-order-dal.ts b/backend/src/ee/services/pki-acme/pki-acme-order-dal.ts index 5aab0be631..cf7d96e876 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-order-dal.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-order-dal.ts @@ -4,6 +4,7 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; +import { CertificateRequestStatus } from "@app/services/certificate-request/certificate-request-types"; export type TPkiAcmeOrderDALFactory = ReturnType; @@ -19,6 +20,43 @@ export const pkiAcmeOrderDALFactory = (db: TDbClient) => { } }; + const findWithCertificateRequestForSync = async (id: string, tx?: Knex) => { + try { + const order = await (tx || db)(TableName.PkiAcmeOrder) + .leftJoin( + TableName.CertificateRequests, + `${TableName.PkiAcmeOrder}.id`, + `${TableName.CertificateRequests}.acmeOrderId` + ) + .select( + selectAllTableCols(TableName.PkiAcmeOrder), + db.ref("id").withSchema(TableName.CertificateRequests).as("certificateRequestId"), + db.ref("status").withSchema(TableName.CertificateRequests).as("certificateRequestStatus"), + db.ref("certificateId").withSchema(TableName.CertificateRequests).as("certificateId") + ) + .forUpdate(TableName.PkiAcmeOrder) + .where(`${TableName.PkiAcmeOrder}.id`, id) + .first(); + if (!order) { + return null; + } + const { certificateRequestId, certificateRequestStatus, certificateId, ...details } = order; + return { + ...details, + certificateRequest: + certificateRequestId && certificateRequestStatus + ? { + id: certificateRequestId, + status: certificateRequestStatus as CertificateRequestStatus, + certificateId + } + : undefined + }; + } catch (error) { + throw new DatabaseError({ error, name: "Find PKI ACME order by id with certificate request" }); + } + }; + const findByAccountAndOrderIdWithAuthorizations = async (accountId: string, orderId: string, tx?: Knex) => { try { const rows = await (tx || db)(TableName.PkiAcmeOrder) @@ -72,6 +110,7 @@ export const pkiAcmeOrderDALFactory = (db: TDbClient) => { return { ...pkiAcmeOrderOrm, findByIdForFinalization, + findWithCertificateRequestForSync, findByAccountAndOrderIdWithAuthorizations, listByAccountId }; diff --git a/backend/src/ee/services/pki-acme/pki-acme-schemas.ts b/backend/src/ee/services/pki-acme/pki-acme-schemas.ts index 23b86d172c..ebd17c26a8 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-schemas.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-schemas.ts @@ -6,8 +6,8 @@ export enum AcmeIdentifierType { export enum AcmeOrderStatus { Pending = "pending", - Processing = "processing", Ready = "ready", + Processing = "processing", Valid = "valid", Invalid = "invalid" } diff --git a/backend/src/ee/services/pki-acme/pki-acme-service.ts b/backend/src/ee/services/pki-acme/pki-acme-service.ts index d9654e50b4..c217211a02 100644 --- a/backend/src/ee/services/pki-acme/pki-acme-service.ts +++ b/backend/src/ee/services/pki-acme/pki-acme-service.ts @@ -7,8 +7,10 @@ import { importJWK, JWSHeaderParameters } from "jose"; +import { Knex } from "knex"; import { z, ZodError } from "zod"; +import { TPkiAcmeOrders } from "@app/db/schemas"; import { TPkiAcmeAccounts } from "@app/db/schemas/pki-acme-accounts"; import { TPkiAcmeAuths } from "@app/db/schemas/pki-acme-auths"; import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore"; @@ -17,20 +19,15 @@ import { crypto } from "@app/lib/crypto/cryptography"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { isPrivateIp } from "@app/lib/ip/ipRange"; import { logger } from "@app/lib/logger"; -import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { ActorType } from "@app/services/auth/auth-type"; import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal"; -import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; -import { TCertificateSecretDALFactory } from "@app/services/certificate/certificate-secret-dal"; -import { - CertExtendedKeyUsage, - CertKeyUsage, - CertSubjectAlternativeNameType -} from "@app/services/certificate/certificate-types"; -import { orderCertificate } from "@app/services/certificate-authority/acme/acme-certificate-authority-fns"; +import { CertSubjectAlternativeNameType } from "@app/services/certificate/certificate-types"; import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal"; import { CaType } from "@app/services/certificate-authority/certificate-authority-enums"; -import { TExternalCertificateAuthorityDALFactory } from "@app/services/certificate-authority/external-certificate-authority-dal"; +import { + TCertificateIssuanceQueueFactory, + TIssueCertificateFromProfileJobData +} from "@app/services/certificate-authority/certificate-issuance-queue"; import { extractAlgorithmsFromCSR, extractCertificateRequestFromCSR @@ -40,6 +37,8 @@ import { EnrollmentType, TCertificateProfileWithConfigs } from "@app/services/certificate-profile/certificate-profile-types"; +import { TCertificateRequestServiceFactory } from "@app/services/certificate-request/certificate-request-service"; +import { CertificateRequestStatus } from "@app/services/certificate-request/certificate-request-types"; import { TCertificateTemplateV2DALFactory } from "@app/services/certificate-template-v2/certificate-template-v2-dal"; import { TCertificateTemplateV2ServiceFactory } from "@app/services/certificate-template-v2/certificate-template-v2-service"; import { TCertificateV3ServiceFactory } from "@app/services/certificate-v3/certificate-v3-service"; @@ -47,6 +46,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; +import { EventType, TAuditLogServiceFactory } from "../audit-log/audit-log-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { TPkiAcmeAccountDALFactory } from "./pki-acme-account-dal"; import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal"; @@ -99,13 +99,9 @@ import { type TPkiAcmeServiceFactoryDep = { projectDAL: Pick; - appConnectionDAL: Pick; - certificateDAL: Pick; certificateAuthorityDAL: Pick; - externalCertificateAuthorityDAL: Pick; certificateProfileDAL: Pick; certificateBodyDAL: Pick; - certificateSecretDAL: Pick; certificateTemplateV2DAL: Pick; acmeAccountDAL: Pick< TPkiAcmeAccountDALFactory, @@ -113,11 +109,13 @@ type TPkiAcmeServiceFactoryDep = { >; acmeOrderDAL: Pick< TPkiAcmeOrderDALFactory, + | "findById" | "create" | "transaction" | "updateById" | "findByAccountAndOrderIdWithAuthorizations" | "findByIdForFinalization" + | "findWithCertificateRequestForSync" | "listByAccountId" >; acmeAuthDAL: Pick; @@ -134,19 +132,18 @@ type TPkiAcmeServiceFactoryDep = { licenseService: Pick; certificateV3Service: Pick; certificateTemplateV2Service: Pick; + certificateRequestService: Pick; + certificateIssuanceQueue: Pick; acmeChallengeService: Pick; pkiAcmeQueueService: Pick; + auditLogService: Pick; }; export const pkiAcmeServiceFactory = ({ projectDAL, - appConnectionDAL, - certificateDAL, certificateAuthorityDAL, - externalCertificateAuthorityDAL, certificateProfileDAL, certificateBodyDAL, - certificateSecretDAL, certificateTemplateV2DAL, acmeAccountDAL, acmeOrderDAL, @@ -158,8 +155,11 @@ export const pkiAcmeServiceFactory = ({ licenseService, certificateV3Service, certificateTemplateV2Service, + certificateRequestService, + certificateIssuanceQueue, acmeChallengeService, - pkiAcmeQueueService + pkiAcmeQueueService, + auditLogService }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => { const validateAcmeProfile = async (profileId: string): Promise => { const profile = await certificateProfileDAL.findByIdWithConfigs(profileId); @@ -364,6 +364,52 @@ export const pkiAcmeServiceFactory = ({ }; }; + const checkAndSyncAcmeOrderStatus = async ({ orderId }: { orderId: string }): Promise => { + const order = await acmeOrderDAL.findById(orderId); + if (!order) { + throw new NotFoundError({ message: "ACME order not found" }); + } + if (order.status !== AcmeOrderStatus.Processing) { + // We only care about processing orders, as they are the ones that have async certificate requests + return order; + } + return acmeOrderDAL.transaction(async (tx) => { + // Lock the order for syncing with async cert request + const orderWithCertificateRequest = await acmeOrderDAL.findWithCertificateRequestForSync(orderId, tx); + if (!orderWithCertificateRequest) { + throw new NotFoundError({ message: "ACME order not found" }); + } + // Check the status again after we have acquired the lock, as things may have changed since we last checked + if ( + orderWithCertificateRequest.status !== AcmeOrderStatus.Processing || + !orderWithCertificateRequest.certificateRequest + ) { + return orderWithCertificateRequest; + } + let newStatus: AcmeOrderStatus | undefined; + let newCertificateId: string | undefined; + switch (orderWithCertificateRequest.certificateRequest.status) { + case CertificateRequestStatus.PENDING: + break; + case CertificateRequestStatus.ISSUED: + newStatus = AcmeOrderStatus.Valid; + newCertificateId = orderWithCertificateRequest.certificateRequest.certificateId ?? undefined; + break; + case CertificateRequestStatus.FAILED: + newStatus = AcmeOrderStatus.Invalid; + break; + default: + throw new AcmeServerInternalError({ + message: `Invalid certificate request status: ${orderWithCertificateRequest.certificateRequest.status as string}` + }); + } + if (newStatus) { + return acmeOrderDAL.updateById(orderId, { status: newStatus, certificateId: newCertificateId }, tx); + } + return orderWithCertificateRequest; + }); + }; + const getAcmeDirectory = async (profileId: string): Promise => { const profile = await validateAcmeProfile(profileId); return { @@ -446,6 +492,23 @@ export const pkiAcmeServiceFactory = ({ throw new AcmeExternalAccountRequiredError({ message: "External account binding is required" }); } if (existingAccount) { + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_PROFILE, + metadata: { + profileId: profile.id + } + }, + event: { + type: EventType.RETRIEVE_ACME_ACCOUNT, + metadata: { + accountId: existingAccount.id, + publicKeyThumbprint + } + } + }); + return { status: 200, body: { @@ -518,7 +581,25 @@ export const pkiAcmeServiceFactory = ({ publicKeyThumbprint, emails: contact ?? [] }); - // TODO: create audit log here + + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_PROFILE, + metadata: { + profileId: profile.id + } + }, + event: { + type: EventType.CREATE_ACME_ACCOUNT, + metadata: { + accountId: newAccount.id, + publicKeyThumbprint: newAccount.publicKeyThumbprint, + emails: newAccount.emails + } + } + }); + return { status: 201, body: { @@ -567,6 +648,8 @@ export const pkiAcmeServiceFactory = ({ accountId: string; payload: TCreateAcmeOrderPayload; }): Promise> => { + const profile = await validateAcmeProfile(profileId); + const skipDnsOwnershipVerification = profile.acmeConfig?.skipDnsOwnershipVerification ?? false; // TODO: check and see if we have existing orders for this account that meet the criteria // if we do, return the existing order // TODO: check the identifiers and see if are they even allowed for this profile. @@ -592,7 +675,7 @@ export const pkiAcmeServiceFactory = ({ const createdOrder = await acmeOrderDAL.create( { accountId: account.id, - status: AcmeOrderStatus.Pending, + status: skipDnsOwnershipVerification ? AcmeOrderStatus.Ready : AcmeOrderStatus.Pending, notBefore: payload.notBefore ? new Date(payload.notBefore) : undefined, notAfter: payload.notAfter ? new Date(payload.notAfter) : undefined, // TODO: read config from the profile to get the expiration time instead @@ -611,7 +694,7 @@ export const pkiAcmeServiceFactory = ({ const auth = await acmeAuthDAL.create( { accountId: account.id, - status: AcmeAuthStatus.Pending, + status: skipDnsOwnershipVerification ? AcmeAuthStatus.Valid : AcmeAuthStatus.Pending, identifierType: identifier.type, identifierValue: identifier.value, // RFC 8555 suggests a token with at least 128 bits of entropy @@ -623,15 +706,19 @@ export const pkiAcmeServiceFactory = ({ }, tx ); - // TODO: support other challenge types here. Currently only HTTP-01 is supported. - await acmeChallengeDAL.create( - { - authId: auth.id, - status: AcmeChallengeStatus.Pending, - type: AcmeChallengeType.HTTP_01 - }, - tx - ); + if (!skipDnsOwnershipVerification) { + for (const challengeType of [AcmeChallengeType.HTTP_01, AcmeChallengeType.DNS_01]) { + // eslint-disable-next-line no-await-in-loop + await acmeChallengeDAL.create( + { + authId: auth.id, + status: AcmeChallengeStatus.Pending, + type: challengeType + }, + tx + ); + } + } return auth; }) ); @@ -643,7 +730,26 @@ export const pkiAcmeServiceFactory = ({ })), tx ); - // TODO: create audit log here + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId: account.profileId, + accountId: account.id + } + }, + event: { + type: EventType.CREATE_ACME_ORDER, + metadata: { + orderId: createdOrder.id, + identifiers: authorizations.map((auth) => ({ + type: auth.identifierType as AcmeIdentifierType, + value: auth.identifierValue + })) + } + } + }); return { ...createdOrder, authorizations, account }; }); @@ -673,9 +779,12 @@ export const pkiAcmeServiceFactory = ({ if (!order) { throw new NotFoundError({ message: "ACME order not found" }); } + // Sync order first in case if there is a certificate request that needs to be processed + await checkAndSyncAcmeOrderStatus({ orderId }); + const updatedOrder = (await acmeOrderDAL.findByAccountAndOrderIdWithAuthorizations(accountId, orderId))!; return { status: 200, - body: buildAcmeOrderResource({ profileId, order }), + body: buildAcmeOrderResource({ profileId, order: updatedOrder }), headers: { Location: buildUrl(profileId, `/orders/${orderId}`), Link: `<${buildUrl(profileId, "/directory")}>;rel="index"` @@ -683,6 +792,129 @@ export const pkiAcmeServiceFactory = ({ }; }; + const processCertificateIssuanceForOrder = async ({ + caType, + accountId, + actorOrgId, + profileId, + orderId, + csr, + finalizingOrder, + certificateRequest, + profile, + ca, + tx + }: { + caType: CaType; + accountId: string; + actorOrgId: string; + profileId: string; + orderId: string; + csr: string; + finalizingOrder: { + notBefore?: Date | null; + notAfter?: Date | null; + }; + certificateRequest: ReturnType; + profile: TCertificateProfileWithConfigs; + ca: Awaited>; + tx?: Knex; + }): Promise<{ certificateId?: string; certIssuanceJobData?: TIssueCertificateFromProfileJobData }> => { + if (caType === CaType.INTERNAL) { + const result = await certificateV3Service.signCertificateFromProfile({ + actor: ActorType.ACME_ACCOUNT, + actorId: accountId, + actorAuthMethod: null, + actorOrgId, + profileId, + csr, + notBefore: finalizingOrder.notBefore ? new Date(finalizingOrder.notBefore) : undefined, + notAfter: finalizingOrder.notAfter ? new Date(finalizingOrder.notAfter) : undefined, + validity: !finalizingOrder.notAfter + ? { + // 47 days, the default TTL comes with Let's Encrypt + // TODO: read config from the profile to get the expiration time instead + ttl: `${47}d` + } + : // ttl is not used if notAfter is provided + ({ ttl: "0d" } as const), + enrollmentType: EnrollmentType.ACME + }); + return { + certificateId: result.certificateId + }; + } + + const { keyAlgorithm: extractedKeyAlgorithm, signatureAlgorithm: extractedSignatureAlgorithm } = + extractAlgorithmsFromCSR(csr); + const updatedCertificateRequest = { + ...certificateRequest, + keyAlgorithm: extractedKeyAlgorithm, + signatureAlgorithm: extractedSignatureAlgorithm, + validity: finalizingOrder.notAfter + ? (() => { + const notBefore = finalizingOrder.notBefore ? new Date(finalizingOrder.notBefore) : new Date(); + const notAfter = new Date(finalizingOrder.notAfter); + const diffMs = notAfter.getTime() - notBefore.getTime(); + const diffDays = Math.round(diffMs / (1000 * 60 * 60 * 24)); + return { ttl: `${diffDays}d` }; + })() + : certificateRequest.validity + }; + + const template = await certificateTemplateV2DAL.findById(profile.certificateTemplateId); + if (!template) { + throw new NotFoundError({ message: "Certificate template not found" }); + } + const validationResult = await certificateTemplateV2Service.validateCertificateRequest( + template.id, + updatedCertificateRequest + ); + if (!validationResult.isValid) { + throw new AcmeBadCSRError({ message: `Invalid CSR: ${validationResult.errors.join(", ")}` }); + } + + const certRequest = await certificateRequestService.createCertificateRequest({ + actor: ActorType.ACME_ACCOUNT, + actorId: accountId, + actorAuthMethod: null, + actorOrgId, + projectId: profile.projectId, + caId: ca.id, + profileId: profile.id, + commonName: updatedCertificateRequest.commonName ?? "", + keyUsages: updatedCertificateRequest.keyUsages?.map((usage) => usage.toString()) ?? [], + extendedKeyUsages: updatedCertificateRequest.extendedKeyUsages?.map((usage) => usage.toString()) ?? [], + keyAlgorithm: updatedCertificateRequest.keyAlgorithm || "", + signatureAlgorithm: updatedCertificateRequest.signatureAlgorithm || "", + altNames: updatedCertificateRequest.subjectAlternativeNames?.map((san) => san.value).join(","), + notBefore: updatedCertificateRequest.notBefore, + notAfter: updatedCertificateRequest.notAfter, + status: CertificateRequestStatus.PENDING, + acmeOrderId: orderId, + csr, + tx + }); + const csrObj = new x509.Pkcs10CertificateRequest(csr); + const csrPem = csrObj.toString("pem"); + return { + certIssuanceJobData: { + certificateId: orderId, + profileId: profile.id, + caId: profile.caId || "", + ttl: updatedCertificateRequest.validity?.ttl || "1y", + signatureAlgorithm: updatedCertificateRequest.signatureAlgorithm || "", + keyAlgorithm: updatedCertificateRequest.keyAlgorithm || "", + commonName: updatedCertificateRequest.commonName || "", + altNames: updatedCertificateRequest.subjectAlternativeNames?.map((san) => san.value) || [], + keyUsages: updatedCertificateRequest.keyUsages?.map((usage) => usage.toString()) ?? [], + extendedKeyUsages: updatedCertificateRequest.extendedKeyUsages?.map((usage) => usage.toString()) ?? [], + certificateRequestId: certRequest.id, + csr: csrPem + } + }; + }; + const finalizeAcmeOrder = async ({ profileId, accountId, @@ -707,7 +939,11 @@ export const pkiAcmeServiceFactory = ({ throw new NotFoundError({ message: "ACME order not found" }); } if (order.status === AcmeOrderStatus.Ready) { - const { order: updatedOrder, error } = await acmeOrderDAL.transaction(async (tx) => { + const { + order: updatedOrder, + error, + certIssuanceJobData + } = await acmeOrderDAL.transaction(async (tx) => { const finalizingOrder = (await acmeOrderDAL.findByIdForFinalization(orderId, tx))!; // TODO: ideally, this should be doen with onRequest: verifyAuth([AuthMode.ACME_JWS_SIGNATURE]), instead? const { ownerOrgId: actorOrgId } = (await certificateProfileDAL.findByIdWithOwnerOrgId(profileId, tx))!; @@ -754,94 +990,31 @@ export const pkiAcmeServiceFactory = ({ } const caType = (ca.externalCa?.type as CaType) ?? CaType.INTERNAL; let errorToReturn: Error | undefined; + let certIssuanceJobDataToReturn: TIssueCertificateFromProfileJobData | undefined; try { - const { certificateId } = await (async () => { - if (caType === CaType.INTERNAL) { - const result = await certificateV3Service.signCertificateFromProfile({ - actor: ActorType.ACME_ACCOUNT, - actorId: accountId, - actorAuthMethod: null, - actorOrgId, - profileId, - csr, - notBefore: finalizingOrder.notBefore ? new Date(finalizingOrder.notBefore) : undefined, - notAfter: finalizingOrder.notAfter ? new Date(finalizingOrder.notAfter) : undefined, - validity: !finalizingOrder.notAfter - ? { - // 47 days, the default TTL comes with Let's Encrypt - // TODO: read config from the profile to get the expiration time instead - ttl: `${47}d` - } - : // ttl is not used if notAfter is provided - ({ ttl: "0d" } as const), - enrollmentType: EnrollmentType.ACME - }); - return { certificateId: result.certificateId }; - } - const { certificateAuthority } = (await certificateProfileDAL.findByIdWithConfigs(profileId, tx))!; - const csrObj = new x509.Pkcs10CertificateRequest(csr); - const csrPem = csrObj.toString("pem"); - - const { keyAlgorithm: extractedKeyAlgorithm, signatureAlgorithm: extractedSignatureAlgorithm } = - extractAlgorithmsFromCSR(csr); - - certificateRequest.keyAlgorithm = extractedKeyAlgorithm; - certificateRequest.signatureAlgorithm = extractedSignatureAlgorithm; - if (finalizingOrder.notAfter) { - const notBefore = finalizingOrder.notBefore ? new Date(finalizingOrder.notBefore) : new Date(); - const notAfter = new Date(finalizingOrder.notAfter); - const diffMs = notAfter.getTime() - notBefore.getTime(); - const diffDays = Math.round(diffMs / (1000 * 60 * 60 * 24)); - certificateRequest.validity = { ttl: `${diffDays}d` }; - } - - const template = await certificateTemplateV2DAL.findById(profile.certificateTemplateId); - if (!template) { - throw new NotFoundError({ message: "Certificate template not found" }); - } - const validationResult = await certificateTemplateV2Service.validateCertificateRequest( - template.id, - certificateRequest - ); - if (!validationResult.isValid) { - throw new AcmeBadCSRError({ message: `Invalid CSR: ${validationResult.errors.join(", ")}` }); - } - // TODO: this is pretty slow, and we are holding the transaction open for a long time, - // we should queue the certificate issuance to a background job instead - const cert = await orderCertificate( - { - caId: certificateAuthority!.id, - // It is possible that the CSR does not have a common name, in which case we use an empty string - // (more likely than not for a CSR from a modern ACME client like certbot, cert-manager, etc.) - commonName: certificateRequest.commonName ?? "", - altNames: certificateRequest.subjectAlternativeNames?.map((san) => san.value), - csr: Buffer.from(csrPem), - // TODO: not 100% sure what are these columns for, but let's put the values for common website SSL certs for now - keyUsages: [CertKeyUsage.DIGITAL_SIGNATURE, CertKeyUsage.KEY_ENCIPHERMENT, CertKeyUsage.KEY_AGREEMENT], - extendedKeyUsages: [CertExtendedKeyUsage.SERVER_AUTH] - }, - { - appConnectionDAL, - certificateAuthorityDAL, - externalCertificateAuthorityDAL, - certificateDAL, - certificateBodyDAL, - certificateSecretDAL, - kmsService, - projectDAL - } - ); - return { certificateId: cert.id }; - })(); + const result = await processCertificateIssuanceForOrder({ + caType, + accountId, + actorOrgId, + profileId, + orderId, + csr, + finalizingOrder, + certificateRequest, + profile, + ca, + tx + }); await acmeOrderDAL.updateById( orderId, { - status: AcmeOrderStatus.Valid, + status: result.certificateId ? AcmeOrderStatus.Valid : AcmeOrderStatus.Processing, csr, - certificateId + certificateId: result.certificateId }, tx ); + certIssuanceJobDataToReturn = result.certIssuanceJobData; } catch (exp) { await acmeOrderDAL.updateById( orderId, @@ -859,18 +1032,43 @@ export const pkiAcmeServiceFactory = ({ } else if (exp instanceof AcmeError) { errorToReturn = exp; } else { - errorToReturn = new AcmeServerInternalError({ message: "Failed to sign certificate with internal error" }); + errorToReturn = new AcmeServerInternalError({ + message: "Failed to sign certificate with internal error" + }); } } return { order: (await acmeOrderDAL.findByAccountAndOrderIdWithAuthorizations(accountId, orderId, tx))!, - error: errorToReturn + error: errorToReturn, + certIssuanceJobData: certIssuanceJobDataToReturn }; }); if (error) { throw error; } + if (certIssuanceJobData) { + // TODO: ideally, this should be done inside the transaction, but the pg-boss queue doesn't support external transactions + // as it seems to be. we need to commit the transaction before queuing the job, otherwise the job will fail (not found error). + await certificateIssuanceQueue.queueCertificateIssuance(certIssuanceJobData); + } order = updatedOrder; + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId, + accountId + } + }, + event: { + type: EventType.FINALIZE_ACME_ORDER, + metadata: { + orderId: updatedOrder.id, + csr: updatedOrder.csr! + } + } + }); } else if (order.status !== AcmeOrderStatus.Valid) { throw new AcmeOrderNotReadyError({ message: "ACME order is not ready" }); } @@ -898,14 +1096,16 @@ export const pkiAcmeServiceFactory = ({ if (!order) { throw new NotFoundError({ message: "ACME order not found" }); } - if (order.status !== AcmeOrderStatus.Valid) { + // Sync order first in case if there is a certificate request that needs to be processed + const syncedOrder = await checkAndSyncAcmeOrderStatus({ orderId }); + if (syncedOrder.status !== AcmeOrderStatus.Valid) { throw new AcmeOrderNotReadyError({ message: "ACME order is not valid" }); } - if (!order.certificateId) { + if (!syncedOrder.certificateId) { throw new NotFoundError({ message: "The certificate for this ACME order no longer exists" }); } - const certBody = await certificateBodyDAL.findOne({ certId: order.certificateId }); + const certBody = await certificateBodyDAL.findOne({ certId: syncedOrder.certificateId }); const certificateManagerKeyId = await getProjectKmsCertificateKeyId({ projectId: profile.projectId, projectDAL, @@ -926,6 +1126,24 @@ export const pkiAcmeServiceFactory = ({ const certLeaf = certObj.toString("pem").trim().replace("\n", "\r\n"); const certChain = certificateChain.trim().replace("\n", "\r\n"); + + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId, + accountId + } + }, + event: { + type: EventType.DOWNLOAD_ACME_CERTIFICATE, + metadata: { + orderId + } + } + }); + return { status: 200, body: @@ -1008,6 +1226,7 @@ export const pkiAcmeServiceFactory = ({ authzId: string; challengeId: string; }): Promise> => { + const profile = await validateAcmeProfile(profileId); const result = await acmeChallengeDAL.findByAccountAuthAndChallengeId(accountId, authzId, challengeId); if (!result) { throw new NotFoundError({ message: "ACME challenge not found" }); @@ -1015,6 +1234,23 @@ export const pkiAcmeServiceFactory = ({ await acmeChallengeService.markChallengeAsReady(challengeId); await pkiAcmeQueueService.queueChallengeValidation(challengeId); const challenge = (await acmeChallengeDAL.findByIdForChallengeValidation(challengeId))!; + await auditLogService.createAuditLog({ + projectId: profile.projectId, + actor: { + type: ActorType.ACME_ACCOUNT, + metadata: { + profileId, + accountId + } + }, + event: { + type: EventType.RESPOND_TO_ACME_CHALLENGE, + metadata: { + challengeId, + type: challenge.type as AcmeChallengeType + } + } + }); return { status: 200, body: { diff --git a/backend/src/ee/services/scim/scim-service.ts b/backend/src/ee/services/scim/scim-service.ts index 465ed3ee58..9433c46277 100644 --- a/backend/src/ee/services/scim/scim-service.ts +++ b/backend/src/ee/services/scim/scim-service.ts @@ -72,7 +72,7 @@ type TScimServiceFactoryDep = { TGroupDALFactory, | "create" | "findOne" - | "findAllGroupPossibleMembers" + | "findAllGroupPossibleUsers" | "delete" | "findGroups" | "transaction" @@ -952,7 +952,7 @@ export const scimServiceFactory = ({ } const users = await groupDAL - .findAllGroupPossibleMembers({ + .findAllGroupPossibleUsers({ orgId: group.orgId, groupId: group.id }) diff --git a/backend/src/lib/api-docs/constants.ts b/backend/src/lib/api-docs/constants.ts index 81b0c0de2a..60e930e691 100644 --- a/backend/src/lib/api-docs/constants.ts +++ b/backend/src/lib/api-docs/constants.ts @@ -77,6 +77,7 @@ export enum ApiDocsTags { OidcSso = "OIDC SSO", SamlSso = "SAML SSO", LdapSso = "LDAP SSO", + Scim = "SCIM", Events = "Event Subscriptions" } @@ -106,6 +107,25 @@ export const GROUPS = { filterUsers: "Whether to filter the list of returned users. 'existingMembers' will only return existing users in the group, 'nonMembers' will only return users not in the group, undefined will return all users in the organization." }, + LIST_MACHINE_IDENTITIES: { + id: "The ID of the group to list identities for.", + offset: "The offset to start from. If you enter 10, it will start from the 10th identity.", + limit: "The number of identities to return.", + search: "The text string that machine identity name will be filtered by.", + filterMachineIdentities: + "Whether to filter the list of returned identities. 'assignedMachineIdentities' will only return identities assigned to the group, 'nonAssignedMachineIdentities' will only return identities not assigned to the group, undefined will return all identities in the organization." + }, + LIST_MEMBERS: { + id: "The ID of the group to list members for.", + offset: "The offset to start from. If you enter 10, it will start from the 10th member.", + limit: "The number of members to return.", + search: + "The text string that member email(in case of users) or name(in case of machine identities) will be filtered by.", + orderBy: "The column to order members by.", + orderDirection: "The direction to order members in.", + memberTypeFilter: + "Filter members by type. Can be a single value ('users' or 'machineIdentities') or an array of values. If not specified, both users and machine identities will be returned." + }, LIST_PROJECTS: { id: "The ID of the group to list projects for.", offset: "The offset to start from. If you enter 10, it will start from the 10th project.", @@ -120,12 +140,20 @@ export const GROUPS = { id: "The ID of the group to add the user to.", username: "The username of the user to add to the group." }, + ADD_MACHINE_IDENTITY: { + id: "The ID of the group to add the machine identity to.", + machineIdentityId: "The ID of the machine identity to add to the group." + }, GET_BY_ID: { id: "The ID of the group to fetch." }, DELETE_USER: { id: "The ID of the group to remove the user from.", username: "The username of the user to remove from the group." + }, + DELETE_MACHINE_IDENTITY: { + id: "The ID of the group to remove the machine identity from.", + machineIdentityId: "The ID of the machine identity to remove from the group." } } as const; @@ -2522,6 +2550,10 @@ export const AppConnections = { orgName: "The short name of the Chef organization to connect to.", userName: "The username used to access Chef.", privateKey: "The private key used to access Chef." + }, + OCTOPUS_DEPLOY: { + instanceUrl: "The Octopus Deploy instance URL to connect to.", + apiKey: "The API key used to authenticate with Octopus Deploy." } } }; @@ -2682,6 +2714,14 @@ export const SecretSyncs = { siteId: "The ID of the Laravel Forge site to sync secrets to.", siteName: "The name of the Laravel Forge site to sync secrets to." }, + OCTOPUS_DEPLOY: { + spaceId: "The ID of the Octopus Deploy space to sync secrets to.", + spaceName: "The name of the Octopus Deploy space to sync secrets to.", + projectId: "The ID of the Octopus Deploy project to sync secrets to.", + projectName: "The name of the Octopus Deploy project to sync secrets to.", + scope: "The Octopus Deploy scope that secrets should be synced to.", + scopeValues: "The Octopus Deploy scope values that secrets should be synced to." + }, WINDMILL: { workspace: "The Windmill workspace to sync secrets to.", path: "The Windmill workspace path to sync secrets to." @@ -3124,6 +3164,13 @@ export const LdapSso = { } }; +export const Scim = { + UPDATE_GROUP_ORG_ROLE_MAPPINGS: { + groupName: "The name of the group in the SCIM provider.", + roleSlug: "The slug of the role that group members should be assigned when provisioned." + } +}; + export const EventSubscriptions = { SUBSCRIBE_PROJECT_EVENTS: { projectId: "The ID of the project to subscribe to events for.", diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index 14eb601925..a034a7b136 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -119,6 +119,16 @@ const envSchema = z }) .default("{}") ), + ACME_DNS_RESOLVER_SERVERS: zpStr( + z + .string() + .optional() + .transform((val) => { + if (!val) return []; + return val.split(","); + }) + ), + ACME_DNS_RESOLVE_RESOLVER_SERVERS_HOST_ENABLED: zodStrBool.default("false").optional(), DNS_MADE_EASY_SANDBOX_ENABLED: zodStrBool.default("false").optional(), // smtp options SMTP_HOST: zpStr(z.string().optional()), @@ -229,6 +239,7 @@ const envSchema = z CAPTCHA_SECRET: zpStr(z.string().optional()), CAPTCHA_SITE_KEY: zpStr(z.string().optional()), INTERCOM_ID: zpStr(z.string().optional()), + CDN_HOST: zpStr(z.string().optional()), // TELEMETRY OTEL_TELEMETRY_COLLECTION_ENABLED: zodStrBool.default("false"), diff --git a/backend/src/lib/fn/object.ts b/backend/src/lib/fn/object.ts index 6ff7278aae..c40e5c53c0 100644 --- a/backend/src/lib/fn/object.ts +++ b/backend/src/lib/fn/object.ts @@ -103,3 +103,98 @@ export const deepEqualSkipFields = (obj1: unknown, obj2: unknown, skipFields: st return deepEqual(filtered1, filtered2); }; + +export const deterministicStringify = (value: unknown): string => { + if (value === null || value === undefined) { + return JSON.stringify(value); + } + + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + return JSON.stringify(value); + } + + if (Array.isArray(value)) { + const items = value.map((item) => deterministicStringify(item)); + return `[${items.join(",")}]`; + } + + if (typeof value === "object") { + const sortedKeys = Object.keys(value).sort(); + const sortedObj: Record = {}; + for (const key of sortedKeys) { + const val = (value as Record)[key]; + if (typeof val === "object" && val !== null) { + sortedObj[key] = JSON.parse(deterministicStringify(val)); + } else { + sortedObj[key] = val; + } + } + return JSON.stringify(sortedObj); + } + + return JSON.stringify(value); +}; + +/** + * Recursively extracts all field paths from a nested object structure. + * Returns an array of dot-notation paths (e.g., ["password", "username", "field.nestedField"]) + */ +export const extractObjectFieldPaths = (obj: unknown, prefix = ""): string[] => { + const paths: string[] = []; + + if (obj === null || obj === undefined) { + return paths; + } + + if (typeof obj !== "object") { + // return the path if it exists + if (prefix) { + paths.push(prefix); + } + return paths; + } + + if (Array.isArray(obj)) { + // for arrays, we log the array itself and optionally nested paths + if (prefix) { + paths.push(prefix); + } + // we just want to know the array field changed + obj.forEach((item, index) => { + if (typeof item === "object" && item !== null) { + const nestedPaths = extractObjectFieldPaths(item, `${prefix}[${index}]`); + paths.push(...nestedPaths); + } + }); + return paths; + } + + // for objects, extract all keys and recurse + const keys = Object.keys(obj); + if (keys.length === 0 && prefix) { + // empty object with prefix + paths.push(prefix); + } + + keys.forEach((key) => { + const currentPath = prefix ? `${prefix}.${key}` : key; + const value = (obj as Record)[key]; + + if (value === null || value === undefined) { + paths.push(currentPath); + } else if (typeof value === "object") { + // recurse into nested objects/arrays + const nestedPaths = extractObjectFieldPaths(value, currentPath); + if (nestedPaths.length === 0) { + // if nested object is empty, add the path itself + paths.push(currentPath); + } else { + paths.push(...nestedPaths); + } + } else { + paths.push(currentPath); + } + }); + + return paths; +}; diff --git a/backend/src/lib/fn/string.ts b/backend/src/lib/fn/string.ts index 61e5a7e208..30a0b8ce55 100644 --- a/backend/src/lib/fn/string.ts +++ b/backend/src/lib/fn/string.ts @@ -33,3 +33,7 @@ export const sanitizeString = (dto: { unsanitizedString: string; tokens: string[ }); return sanitizedWords.join(""); }; + +export const sanitizeSqlLikeString = (value: string): string => { + return String(value).replace(new RE2("[%_\\\\]", "g"), "\\$&"); +}; diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index 633b4211a3..2d86e6bc8a 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -1,6 +1,8 @@ +import fs from "node:fs"; import path from "node:path"; import staticServe from "@fastify/static"; +import RE2 from "re2"; import { getConfig, IS_PACKAGED } from "@app/lib/config/env"; @@ -15,6 +17,9 @@ export const registerServeUI = async ( dir: string; } ) => { + const appCfg = getConfig(); + const cdnHost = appCfg.CDN_HOST || ""; + // use this only for frontend runtime static non-sensitive configuration in standalone mode // that app needs before loading like posthog dsn key // for most of the other usecase use server config @@ -25,15 +30,26 @@ export const registerServeUI = async ( hide: true }, handler: (_req, res) => { - const appCfg = getConfig(); void res.type("application/javascript"); const config = { CAPTCHA_SITE_KEY: appCfg.CAPTCHA_SITE_KEY, POSTHOG_API_KEY: appCfg.POSTHOG_PROJECT_API_KEY, INTERCOM_ID: appCfg.INTERCOM_ID, - TELEMETRY_CAPTURING_ENABLED: appCfg.TELEMETRY_ENABLED + TELEMETRY_CAPTURING_ENABLED: appCfg.TELEMETRY_ENABLED, + CDN_HOST: cdnHost }; - const js = `window.__INFISICAL_RUNTIME_ENV__ = Object.freeze(${JSON.stringify(config)});`; + // Define window.__toCdnUrl for Vite's experimental.renderBuiltUrl runtime support + // This function is called by dynamically imported chunks to resolve CDN URLs + const js = ` + window.__INFISICAL_RUNTIME_ENV__ = Object.freeze(${JSON.stringify(config)}); + window.__toCdnUrl = function(filename) { + var cdnHost = window.__INFISICAL_RUNTIME_ENV__.CDN_HOST || ""; + if (cdnHost && filename.startsWith("assets/")) { + return cdnHost + "/" + filename; + } + return "/" + filename; + }; + `.trim(); return res.send(js); } }); @@ -41,11 +57,30 @@ export const registerServeUI = async ( if (standaloneMode) { const frontendName = IS_PACKAGED ? "frontend" : "frontend-build"; const frontendPath = path.join(dir, frontendName); + + const indexHtmlPath = path.join(frontendPath, "index.html"); + let indexHtml = fs.readFileSync(indexHtmlPath, "utf-8"); + + if (cdnHost) { + // Replace relative asset paths with CDN URLs in script and link tags + indexHtml = indexHtml + .replace(/src="\/assets\//g, `src="${cdnHost}/assets/`) + .replace(/href="\/assets\//g, `href="${cdnHost}/assets/`); + + // Inject CDN host into CSP directives that need it + const cspDirectives = ["script-src", "style-src", "font-src", "connect-src", "media-src"]; + for (const directive of cspDirectives) { + const regex = new RE2(`(${directive}\\s+'self')`, "g"); + indexHtml = indexHtml.replace(regex, `$1 ${cdnHost}`); + } + } + await server.register(staticServe, { root: frontendPath, wildcard: false, maxAge: "30d", - immutable: true + immutable: true, + index: false }); server.route({ @@ -60,12 +95,12 @@ export const registerServeUI = async ( return; } - return reply.sendFile("index.html", { - immutable: false, - maxAge: 0, - lastModified: false, - etag: false - }); + return reply + .type("text/html") + .header("Cache-Control", "no-cache, no-store, must-revalidate") + .header("Pragma", "no-cache") + .header("Expires", "0") + .send(indexHtml); } }); } diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 6611f4a594..5b46633b5f 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -46,6 +46,7 @@ import { githubOrgSyncDALFactory } from "@app/ee/services/github-org-sync/github import { githubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service"; import { groupDALFactory } from "@app/ee/services/group/group-dal"; import { groupServiceFactory } from "@app/ee/services/group/group-service"; +import { identityGroupMembershipDALFactory } from "@app/ee/services/group/identity-group-membership-dal"; import { userGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal"; import { isHsmActiveAndEnabled } from "@app/ee/services/hsm/hsm-fns"; import { THsmServiceFactory } from "@app/ee/services/hsm/hsm-service"; @@ -470,6 +471,7 @@ export const registerRoutes = async ( const identityMetadataDAL = identityMetadataDALFactory(db); const identityAccessTokenDAL = identityAccessTokenDALFactory(db); const identityOrgMembershipDAL = identityOrgDALFactory(db); + const identityGroupMembershipDAL = identityGroupMembershipDALFactory(db); const identityProjectDAL = identityProjectDALFactory(db); const identityAuthTemplateDAL = identityAuthTemplateDALFactory(db); @@ -754,6 +756,9 @@ export const registerRoutes = async ( membershipGroupDAL }); const groupService = groupServiceFactory({ + identityDAL, + membershipDAL, + identityGroupMembershipDAL, userDAL, groupDAL, orgDAL, @@ -1356,10 +1361,7 @@ export const registerRoutes = async ( permissionService, projectDAL, projectSshConfigDAL, - secretDAL, - secretV2BridgeDAL, projectQueue: projectQueueService, - projectBotService, userDAL, projectEnvDAL, orgDAL, @@ -1386,7 +1388,6 @@ export const registerRoutes = async ( microsoftTeamsIntegrationDAL, projectTemplateService, smtpService, - reminderService, notificationService, membershipGroupDAL, membershipIdentityDAL, @@ -2303,7 +2304,8 @@ export const registerRoutes = async ( }); const acmeChallengeService = pkiAcmeChallengeServiceFactory({ - acmeChallengeDAL + acmeChallengeDAL, + auditLogService }); const pkiAcmeQueueService = await pkiAcmeQueueServiceFactory({ @@ -2313,13 +2315,9 @@ export const registerRoutes = async ( const pkiAcmeService = pkiAcmeServiceFactory({ projectDAL, - appConnectionDAL, - certificateDAL, certificateAuthorityDAL, - externalCertificateAuthorityDAL, certificateProfileDAL, certificateBodyDAL, - certificateSecretDAL, certificateTemplateV2DAL, acmeAccountDAL, acmeOrderDAL, @@ -2331,8 +2329,11 @@ export const registerRoutes = async ( licenseService, certificateV3Service, certificateTemplateV2Service, + certificateRequestService, + certificateIssuanceQueue, acmeChallengeService, - pkiAcmeQueueService + pkiAcmeQueueService, + auditLogService }); const pkiSubscriberService = pkiSubscriberServiceFactory({ diff --git a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts index 072abbadb7..a67f2c0bf2 100644 --- a/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts +++ b/backend/src/server/routes/v1/app-connection-routers/app-connection-router.ts @@ -101,6 +101,10 @@ import { NorthflankConnectionListItemSchema, SanitizedNorthflankConnectionSchema } from "@app/services/app-connection/northflank"; +import { + OctopusDeployConnectionListItemSchema, + SanitizedOctopusDeployConnectionSchema +} from "@app/services/app-connection/octopus-deploy"; import { OktaConnectionListItemSchema, SanitizedOktaConnectionSchema } from "@app/services/app-connection/okta"; import { PostgresConnectionListItemSchema, @@ -180,7 +184,8 @@ const SanitizedAppConnectionSchema = z.union([ ...SanitizedMongoDBConnectionSchema.options, ...SanitizedLaravelForgeConnectionSchema.options, ...SanitizedChefConnectionSchema.options, - ...SanitizedDNSMadeEasyConnectionSchema.options + ...SanitizedDNSMadeEasyConnectionSchema.options, + ...SanitizedOctopusDeployConnectionSchema.options ]); const AppConnectionOptionsSchema = z.discriminatedUnion("app", [ @@ -227,7 +232,8 @@ const AppConnectionOptionsSchema = z.discriminatedUnion("app", [ MongoDBConnectionListItemSchema, LaravelForgeConnectionListItemSchema, ChefConnectionListItemSchema, - DNSMadeEasyConnectionListItemSchema + DNSMadeEasyConnectionListItemSchema, + OctopusDeployConnectionListItemSchema ]); export const registerAppConnectionRouter = async (server: FastifyZodProvider) => { diff --git a/backend/src/server/routes/v1/app-connection-routers/index.ts b/backend/src/server/routes/v1/app-connection-routers/index.ts index 0738f0407e..cf48378196 100644 --- a/backend/src/server/routes/v1/app-connection-routers/index.ts +++ b/backend/src/server/routes/v1/app-connection-routers/index.ts @@ -33,6 +33,7 @@ import { registerMsSqlConnectionRouter } from "./mssql-connection-router"; import { registerMySqlConnectionRouter } from "./mysql-connection-router"; import { registerNetlifyConnectionRouter } from "./netlify-connection-router"; import { registerNorthflankConnectionRouter } from "./northflank-connection-router"; +import { registerOctopusDeployConnectionRouter } from "./octopus-deploy-connection-router"; import { registerOktaConnectionRouter } from "./okta-connection-router"; import { registerPostgresConnectionRouter } from "./postgres-connection-router"; import { registerRailwayConnectionRouter } from "./railway-connection-router"; @@ -92,5 +93,6 @@ export const APP_CONNECTION_REGISTER_ROUTER_MAP: Record { + registerAppConnectionEndpoints({ + app: AppConnection.OctopusDeploy, + server, + sanitizedResponseSchema: SanitizedOctopusDeployConnectionSchema, + createSchema: CreateOctopusDeployConnectionSchema, + updateSchema: UpdateOctopusDeployConnectionSchema + }); + + server.route({ + method: "GET", + url: `/:connectionId/spaces`, + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + connectionId: z.string().uuid() + }), + response: { + 200: z.array( + z.object({ + id: z.string(), + name: z.string(), + slug: z.string(), + isDefault: z.boolean() + }) + ) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const { connectionId } = req.params; + + const spaces = await server.services.appConnection.octopusDeploy.listSpaces(connectionId, req.permission); + + return spaces; + } + }); + + server.route({ + method: "GET", + url: `/:connectionId/projects`, + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + connectionId: z.string().uuid() + }), + querystring: z.object({ + spaceId: z.string().min(1, "Space ID is required") + }), + response: { + 200: z.array( + z.object({ + id: z.string(), + name: z.string(), + slug: z.string() + }) + ) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const { connectionId } = req.params; + const { spaceId } = req.query; + + const projects = await server.services.appConnection.octopusDeploy.listProjects( + connectionId, + spaceId, + req.permission + ); + + return projects; + } + }); + + server.route({ + method: "GET", + url: `/:connectionId/scope-values`, + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + connectionId: z.string().uuid() + }), + querystring: z.object({ + spaceId: z.string().min(1, "Space ID is required"), + projectId: z.string().min(1, "Project ID is required") + }), + response: { + 200: z.object({ + environments: z + .object({ + id: z.string(), + name: z.string() + }) + .array(), + roles: z + .object({ + id: z.string(), + name: z.string() + }) + .array(), + machines: z + .object({ + id: z.string(), + name: z.string() + }) + .array(), + processes: z + .object({ + id: z.string(), + name: z.string() + }) + .array(), + actions: z + .object({ + id: z.string(), + name: z.string() + }) + .array(), + channels: z + .object({ + id: z.string(), + name: z.string() + }) + .array() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const { connectionId } = req.params; + const { spaceId, projectId } = req.query; + + const scopeValues = await server.services.appConnection.octopusDeploy.getScopeValues( + connectionId, + spaceId, + projectId, + req.permission + ); + + if (!scopeValues) { + throw new BadRequestError({ message: "Unable to get Octopus Deploy scope values" }); + } + + return scopeValues; + } + }); +}; diff --git a/backend/src/server/routes/v1/approval-policy-routers/approval-policy-endpoints.ts b/backend/src/server/routes/v1/approval-policy-routers/approval-policy-endpoints.ts index 91e0425422..750290f3db 100644 --- a/backend/src/server/routes/v1/approval-policy-routers/approval-policy-endpoints.ts +++ b/backend/src/server/routes/v1/approval-policy-routers/approval-policy-endpoints.ts @@ -7,6 +7,7 @@ import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ApprovalPolicyType } from "@app/services/approval-policy/approval-policy-enums"; import { TApprovalPolicy, + TApprovalPolicyInputs, TCreatePolicyDTO, TCreateRequestDTO, TUpdatePolicyDTO @@ -21,7 +22,8 @@ export const registerApprovalPolicyEndpoints =

({ policyResponseSchema, createRequestSchema, requestResponseSchema, - grantResponseSchema + grantResponseSchema, + inputsSchema }: { server: FastifyZodProvider; policyType: ApprovalPolicyType; @@ -41,6 +43,7 @@ export const registerApprovalPolicyEndpoints =

({ createRequestSchema: z.ZodType; requestResponseSchema: z.ZodTypeAny; grantResponseSchema: z.ZodTypeAny; + inputsSchema: z.ZodType; }) => { // Policies server.route({ @@ -622,4 +625,31 @@ export const registerApprovalPolicyEndpoints =

({ return { grant }; } }); + + server.route({ + method: "POST", + url: "/check-policy-match", + config: { + rateLimit: readLimit + }, + schema: { + description: "Check if a resource path matches any approval policy and if the user has an active grant", + body: z.object({ + projectId: z.string().uuid(), + inputs: inputsSchema + }), + response: { + 200: z.object({ + requiresApproval: z.boolean(), + hasActiveGrant: z.boolean() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT]), + handler: async (req) => { + const result = await server.services.approvalPolicy.checkPolicyMatch(policyType, req.body, req.permission); + + return result; + } + }); }; diff --git a/backend/src/server/routes/v1/approval-policy-routers/index.ts b/backend/src/server/routes/v1/approval-policy-routers/index.ts index c848e2e47b..de5250c570 100644 --- a/backend/src/server/routes/v1/approval-policy-routers/index.ts +++ b/backend/src/server/routes/v1/approval-policy-routers/index.ts @@ -2,6 +2,7 @@ import { ApprovalPolicyType } from "@app/services/approval-policy/approval-polic import { CreatePamAccessPolicySchema, CreatePamAccessRequestSchema, + PamAccessPolicyInputsSchema, PamAccessPolicySchema, PamAccessRequestGrantSchema, PamAccessRequestSchema, @@ -23,7 +24,8 @@ export const APPROVAL_POLICY_REGISTER_ROUTER_MAP: Record< policyResponseSchema: PamAccessPolicySchema, createRequestSchema: CreatePamAccessRequestSchema, requestResponseSchema: PamAccessRequestSchema, - grantResponseSchema: PamAccessRequestGrantSchema + grantResponseSchema: PamAccessRequestGrantSchema, + inputsSchema: PamAccessPolicyInputsSchema }); } }; diff --git a/backend/src/server/routes/v1/certificate-profiles-router.ts b/backend/src/server/routes/v1/certificate-profiles-router.ts index ff770326d6..a3402bd858 100644 --- a/backend/src/server/routes/v1/certificate-profiles-router.ts +++ b/backend/src/server/routes/v1/certificate-profiles-router.ts @@ -47,7 +47,11 @@ export const registerCertificateProfilesRouter = async (server: FastifyZodProvid renewBeforeDays: z.number().min(1).max(30).optional() }) .optional(), - acmeConfig: z.object({}).optional(), + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) + .optional(), externalConfigs: ExternalConfigUnionSchema }) .refine( @@ -245,7 +249,8 @@ export const registerCertificateProfilesRouter = async (server: FastifyZodProvid acmeConfig: z .object({ id: z.string(), - directoryUrl: z.string() + directoryUrl: z.string(), + skipDnsOwnershipVerification: z.boolean().optional() }) .optional(), externalConfigs: ExternalConfigUnionSchema @@ -434,6 +439,11 @@ export const registerCertificateProfilesRouter = async (server: FastifyZodProvid renewBeforeDays: z.number().min(1).max(30).optional() }) .optional(), + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) + .optional(), externalConfigs: ExternalConfigUnionSchema }) .refine( diff --git a/backend/src/server/routes/v1/certificate-router.ts b/backend/src/server/routes/v1/certificate-router.ts index 25beb710cd..d598bd9aa6 100644 --- a/backend/src/server/routes/v1/certificate-router.ts +++ b/backend/src/server/routes/v1/certificate-router.ts @@ -25,6 +25,7 @@ import { EnrollmentType } from "@app/services/certificate-profile/certificate-pr import { CertificateRequestStatus } from "@app/services/certificate-request/certificate-request-types"; import { validateTemplateRegexField } from "@app/services/certificate-template/certificate-template-validators"; import { TCertificateFromProfileResponse } from "@app/services/certificate-v3/certificate-v3-types"; +import { ProjectFilterType } from "@app/services/project/project-types"; import { booleanSchema } from "../sanitizedSchemas"; @@ -353,6 +354,123 @@ export const registerCertificateRouter = async (server: FastifyZodProvider) => { } }); + server.route({ + method: "GET", + url: "/certificate-requests", + config: { + rateLimit: readLimit + }, + schema: { + hide: false, + tags: [ApiDocsTags.PkiCertificates], + querystring: z.object({ + projectSlug: z.string().min(1).trim(), + offset: z.coerce.number().min(0).default(0), + limit: z.coerce.number().min(1).max(100).default(20), + search: z.string().trim().optional(), + status: z.nativeEnum(CertificateRequestStatus).optional(), + fromDate: z.coerce.date().optional(), + toDate: z.coerce.date().optional(), + profileIds: z + .string() + .transform((val) => val.split(",").map((id) => id.trim())) + .pipe(z.array(z.string().uuid())) + .optional() + .describe("Comma-separated list of profile IDs"), + sortBy: z.string().trim().optional(), + sortOrder: z.enum(["asc", "desc"]).optional() + }), + response: { + 200: z.object({ + certificateRequests: z.array( + z.object({ + id: z.string(), + status: z.nativeEnum(CertificateRequestStatus), + commonName: z.string().nullable(), + altNames: z.string().nullable(), + profileId: z.string().nullable(), + profileName: z.string().nullable(), + caId: z.string().nullable(), + certificateId: z.string().nullable(), + errorMessage: z.string().nullable(), + createdAt: z.date(), + updatedAt: z.date(), + certificate: z + .object({ + id: z.string(), + serialNumber: z.string(), + status: z.string() + }) + .nullable() + }) + ), + totalCount: z.number() + }) + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const project = await server.services.project.getAProject({ + actor: req.permission.type, + actorId: req.permission.id, + actorOrgId: req.permission.orgId, + actorAuthMethod: req.permission.authMethod, + filter: { + type: ProjectFilterType.SLUG, + slug: req.query.projectSlug, + orgId: req.permission.orgId + } + }); + + const { certificateRequests, totalCount } = await server.services.certificateRequest.listCertificateRequests({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + projectId: project.id, + offset: req.query.offset, + limit: req.query.limit, + search: req.query.search, + status: req.query.status, + fromDate: req.query.fromDate, + toDate: req.query.toDate, + profileIds: req.query.profileIds, + sortBy: req.query.sortBy, + sortOrder: req.query.sortOrder + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId: project.id, + event: { + type: EventType.LIST_CERTIFICATE_REQUESTS, + metadata: { + offset: req.query.offset, + limit: req.query.limit, + search: req.query.search, + status: req.query.status, + count: certificateRequests.length, + certificateRequestIds: certificateRequests.map((certReq) => certReq.id) + } + } + }); + + return { + certificateRequests: certificateRequests.map((certReq) => ({ + ...certReq, + profileId: certReq.profileId ?? null, + caId: certReq.caId ?? null, + certificateId: certReq.certificateId ?? null, + commonName: certReq.commonName ?? null, + altNames: certReq.altNames ?? null, + errorMessage: certReq.errorMessage ?? null, + profileName: certReq.profileName ?? null + })), + totalCount + }; + } + }); + server.route({ method: "POST", url: "/issue-certificate", diff --git a/backend/src/server/routes/v1/dashboard-router.ts b/backend/src/server/routes/v1/dashboard-router.ts index 7dc763730f..4287150f73 100644 --- a/backend/src/server/routes/v1/dashboard-router.ts +++ b/backend/src/server/routes/v1/dashboard-router.ts @@ -359,6 +359,21 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { // get the count of unique dynamic secret names to properly adjust remaining limit const uniqueDynamicSecretsCount = new Set(dynamicSecrets.map((dynamicSecret) => dynamicSecret.name)).size; + if (dynamicSecrets.length) { + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.LIST_DYNAMIC_SECRETS, + metadata: { + environment: [...new Set(dynamicSecrets.map((dynamicSecret) => dynamicSecret.environment))].join(","), + secretPath, + projectId + } + } + }); + } + remainingLimit -= uniqueDynamicSecretsCount; adjustedOffset = 0; } else { @@ -738,7 +753,9 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { reminder: Awaited>[string] | null; })[] | undefined; - let dynamicSecrets: Awaited> | undefined; + let dynamicSecrets: + | Awaited>["dynamicSecrets"] + | undefined; let secretRotations: | (Awaited>[number] & { secrets: (NonNullable< @@ -923,7 +940,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { }); if (remainingLimit > 0 && totalDynamicSecretCount > adjustedOffset) { - dynamicSecrets = await server.services.dynamicSecret.listDynamicSecretsByEnv({ + const { dynamicSecrets: dynamicSecretCfgs } = await server.services.dynamicSecret.listDynamicSecretsByEnv({ actor: req.permission.type, actorId: req.permission.id, actorAuthMethod: req.permission.authMethod, @@ -938,6 +955,23 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { offset: adjustedOffset }); + if (dynamicSecretCfgs.length) { + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + projectId, + event: { + type: EventType.LIST_DYNAMIC_SECRETS, + metadata: { + environment, + secretPath, + projectId + } + } + }); + } + + dynamicSecrets = dynamicSecretCfgs; + remainingLimit -= dynamicSecrets.length; adjustedOffset = 0; } else { @@ -1263,6 +1297,27 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => { const sliceQuickSearch = (array: T[]) => array.slice(0, 25); + const filteredDynamicSecrets = sliceQuickSearch( + searchPath ? dynamicSecrets.filter((dynamicSecret) => dynamicSecret.path.endsWith(searchPath)) : dynamicSecrets + ); + + if (filteredDynamicSecrets?.length) { + await server.services.auditLog.createAuditLog({ + projectId, + ...req.auditLogInfo, + event: { + type: EventType.LIST_DYNAMIC_SECRETS, + metadata: { + environment: [...new Set(filteredDynamicSecrets.map((dynamicSecret) => dynamicSecret.environment))].join( + "," + ), + secretPath: [...new Set(filteredDynamicSecrets.map((dynamicSecret) => dynamicSecret.path))].join(","), + projectId + } + } + }); + } + return { secrets: sliceQuickSearch( searchPath ? secrets.filter((secret) => secret.secretPath.endsWith(searchPath)) : secrets diff --git a/backend/src/server/routes/v1/external-group-org-role-mapping-router.ts b/backend/src/server/routes/v1/external-group-org-role-mapping-router.ts index 67db5de6fe..22371f7905 100644 --- a/backend/src/server/routes/v1/external-group-org-role-mapping-router.ts +++ b/backend/src/server/routes/v1/external-group-org-role-mapping-router.ts @@ -2,6 +2,7 @@ import { z } from "zod"; import { ExternalGroupOrgRoleMappingsSchema } from "@app/db/schemas/external-group-org-role-mappings"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { ApiDocsTags, Scim } from "@app/lib/api-docs"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { slugSchema } from "@app/server/lib/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; @@ -16,6 +17,8 @@ export const registerExternalGroupOrgRoleMappingRouter = async (server: FastifyZ rateLimit: readLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Scim], response: { 200: ExternalGroupOrgRoleMappingsSchema.array() } @@ -44,11 +47,13 @@ export const registerExternalGroupOrgRoleMappingRouter = async (server: FastifyZ rateLimit: writeLimit }, schema: { + hide: false, + tags: [ApiDocsTags.Scim], body: z.object({ mappings: z .object({ - groupName: z.string().trim().min(1), - roleSlug: slugSchema({ max: 64 }) + groupName: z.string().trim().min(1).describe(Scim.UPDATE_GROUP_ORG_ROLE_MAPPINGS.groupName), + roleSlug: slugSchema({ max: 64 }).describe(Scim.UPDATE_GROUP_ORG_ROLE_MAPPINGS.roleSlug) }) .array() }), diff --git a/backend/src/server/routes/v1/group-project-router.ts b/backend/src/server/routes/v1/group-project-router.ts index 93caf50351..146891c80e 100644 --- a/backend/src/server/routes/v1/group-project-router.ts +++ b/backend/src/server/routes/v1/group-project-router.ts @@ -9,7 +9,7 @@ import { TemporaryPermissionMode, UsersSchema } from "@app/db/schemas"; -import { EFilterReturnedUsers } from "@app/ee/services/group/group-types"; +import { FilterReturnedUsers } from "@app/ee/services/group/group-types"; import { ApiDocsTags, GROUPS, PROJECTS } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { isUuidV4 } from "@app/lib/validator"; @@ -355,9 +355,10 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => rateLimit: readLimit }, schema: { - hide: false, + hide: true, + deprecated: true, tags: [ApiDocsTags.ProjectGroups], - description: "Return project group users", + description: "Return project group users (Deprecated: Use /api/v1/groups/{id}/users instead)", params: z.object({ projectId: z.string().trim().describe(GROUPS.LIST_USERS.projectId), groupId: z.string().trim().describe(GROUPS.LIST_USERS.id) @@ -367,7 +368,7 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) => limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_USERS.limit), username: z.string().trim().optional().describe(GROUPS.LIST_USERS.username), search: z.string().trim().optional().describe(GROUPS.LIST_USERS.search), - filter: z.nativeEnum(EFilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) + filter: z.nativeEnum(FilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/index.ts b/backend/src/server/routes/v1/index.ts index 3b4b10b88c..34810c5b13 100644 --- a/backend/src/server/routes/v1/index.ts +++ b/backend/src/server/routes/v1/index.ts @@ -236,7 +236,7 @@ export const registerV1Routes = async (server: FastifyZodProvider) => { await server.register(registerUserEngagementRouter, { prefix: "/user-engagement" }); await server.register(registerDashboardRouter, { prefix: "/dashboard" }); await server.register(registerCmekRouter, { prefix: "/kms" }); - await server.register(registerExternalGroupOrgRoleMappingRouter, { prefix: "/external-group-mappings" }); + await server.register(registerExternalGroupOrgRoleMappingRouter, { prefix: "/scim/group-org-role-mappings" }); await server.register( async (appConnectionRouter) => { diff --git a/backend/src/server/routes/v1/project-router.ts b/backend/src/server/routes/v1/project-router.ts index e3838cddc2..6ae9ef27bd 100644 --- a/backend/src/server/routes/v1/project-router.ts +++ b/backend/src/server/routes/v1/project-router.ts @@ -1209,7 +1209,16 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => { .boolean() .default(false) .optional() - .describe("Retrieve only certificates available for PKI sync") + .describe("Retrieve only certificates available for PKI sync"), + search: z.string().trim().optional().describe("Search by SAN, CN, certificate ID, or serial number"), + status: z.string().optional().describe("Filter by certificate status"), + profileIds: z + .union([z.string().uuid(), z.array(z.string().uuid())]) + .transform((val) => (Array.isArray(val) ? val : [val])) + .optional() + .describe("Filter by profile IDs"), + fromDate: z.coerce.date().optional().describe("Filter certificates created from this date"), + toDate: z.coerce.date().optional().describe("Filter certificates created until this date") }), response: { 200: z.object({ diff --git a/backend/src/server/routes/v1/secret-sync-routers/index.ts b/backend/src/server/routes/v1/secret-sync-routers/index.ts index 810e5b7faf..3699bc95d2 100644 --- a/backend/src/server/routes/v1/secret-sync-routers/index.ts +++ b/backend/src/server/routes/v1/secret-sync-routers/index.ts @@ -25,6 +25,7 @@ import { registerHumanitecSyncRouter } from "./humanitec-sync-router"; import { registerLaravelForgeSyncRouter } from "./laravel-forge-sync-router"; import { registerNetlifySyncRouter } from "./netlify-sync-router"; import { registerNorthflankSyncRouter } from "./northflank-sync-router"; +import { registerOctopusDeploySyncRouter } from "./octopus-deploy-sync-router"; import { registerRailwaySyncRouter } from "./railway-sync-router"; import { registerRenderSyncRouter } from "./render-sync-router"; import { registerSupabaseSyncRouter } from "./supabase-sync-router"; @@ -69,5 +70,6 @@ export const SECRET_SYNC_REGISTER_ROUTER_MAP: Record + registerSyncSecretsEndpoints({ + destination: SecretSync.OctopusDeploy, + server, + responseSchema: OctopusDeploySyncSchema, + createSchema: CreateOctopusDeploySyncSchema, + updateSchema: UpdateOctopusDeploySyncSchema + }); diff --git a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-router.ts b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-router.ts index 61e4ab79d6..a1ba5d7d9c 100644 --- a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-router.ts +++ b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-router.ts @@ -48,6 +48,7 @@ import { HumanitecSyncListItemSchema, HumanitecSyncSchema } from "@app/services/ import { LaravelForgeSyncListItemSchema, LaravelForgeSyncSchema } from "@app/services/secret-sync/laravel-forge"; import { NetlifySyncListItemSchema, NetlifySyncSchema } from "@app/services/secret-sync/netlify"; import { NorthflankSyncListItemSchema, NorthflankSyncSchema } from "@app/services/secret-sync/northflank"; +import { OctopusDeploySyncListItemSchema, OctopusDeploySyncSchema } from "@app/services/secret-sync/octopus-deploy"; import { RailwaySyncListItemSchema, RailwaySyncSchema } from "@app/services/secret-sync/railway/railway-sync-schemas"; import { RenderSyncListItemSchema, RenderSyncSchema } from "@app/services/secret-sync/render/render-sync-schemas"; import { SupabaseSyncListItemSchema, SupabaseSyncSchema } from "@app/services/secret-sync/supabase"; @@ -90,7 +91,8 @@ const SecretSyncSchema = z.discriminatedUnion("destination", [ NorthflankSyncSchema, BitbucketSyncSchema, LaravelForgeSyncSchema, - ChefSyncSchema + ChefSyncSchema, + OctopusDeploySyncSchema ]); const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [ @@ -126,7 +128,8 @@ const SecretSyncOptionsSchema = z.discriminatedUnion("destination", [ NorthflankSyncListItemSchema, BitbucketSyncListItemSchema, LaravelForgeSyncListItemSchema, - ChefSyncListItemSchema + ChefSyncListItemSchema, + OctopusDeploySyncListItemSchema ]); export const registerSecretSyncRouter = async (server: FastifyZodProvider) => { diff --git a/backend/src/server/routes/v2/deprecated-group-project-router.ts b/backend/src/server/routes/v2/deprecated-group-project-router.ts index 5be7df8387..acfd72a59f 100644 --- a/backend/src/server/routes/v2/deprecated-group-project-router.ts +++ b/backend/src/server/routes/v2/deprecated-group-project-router.ts @@ -9,7 +9,7 @@ import { TemporaryPermissionMode, UsersSchema } from "@app/db/schemas"; -import { EFilterReturnedUsers } from "@app/ee/services/group/group-types"; +import { FilterReturnedUsers } from "@app/ee/services/group/group-types"; import { ApiDocsTags, GROUPS, PROJECTS } from "@app/lib/api-docs"; import { ms } from "@app/lib/ms"; import { isUuidV4 } from "@app/lib/validator"; @@ -367,7 +367,7 @@ export const registerDeprecatedGroupProjectRouter = async (server: FastifyZodPro limit: z.coerce.number().min(1).max(100).default(10).describe(GROUPS.LIST_USERS.limit), username: z.string().trim().optional().describe(GROUPS.LIST_USERS.username), search: z.string().trim().optional().describe(GROUPS.LIST_USERS.search), - filter: z.nativeEnum(EFilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) + filter: z.nativeEnum(FilterReturnedUsers).optional().describe(GROUPS.LIST_USERS.filterUsers) }), response: { 200: z.object({ diff --git a/backend/src/services/app-connection/app-connection-enums.ts b/backend/src/services/app-connection/app-connection-enums.ts index e7e2bca760..968d837b43 100644 --- a/backend/src/services/app-connection/app-connection-enums.ts +++ b/backend/src/services/app-connection/app-connection-enums.ts @@ -42,7 +42,8 @@ export enum AppConnection { MongoDB = "mongodb", LaravelForge = "laravel-forge", Chef = "chef", - Northflank = "northflank" + Northflank = "northflank", + OctopusDeploy = "octopus-deploy" } export enum AWSRegion { diff --git a/backend/src/services/app-connection/app-connection-fns.ts b/backend/src/services/app-connection/app-connection-fns.ts index f28508efba..e32e3f35f3 100644 --- a/backend/src/services/app-connection/app-connection-fns.ts +++ b/backend/src/services/app-connection/app-connection-fns.ts @@ -129,6 +129,11 @@ import { NorthflankConnectionMethod, validateNorthflankConnectionCredentials } from "./northflank"; +import { + getOctopusDeployConnectionListItem, + OctopusDeployConnectionMethod, + validateOctopusDeployConnectionCredentials +} from "./octopus-deploy"; import { getOktaConnectionListItem, OktaConnectionMethod, validateOktaConnectionCredentials } from "./okta"; import { getPostgresConnectionListItem, PostgresConnectionMethod } from "./postgres"; import { getRailwayConnectionListItem, validateRailwayConnectionCredentials } from "./railway"; @@ -211,6 +216,7 @@ export const listAppConnectionOptions = (projectType?: ProjectType) => { getHerokuConnectionListItem(), getRenderConnectionListItem(), getLaravelForgeConnectionListItem(), + getOctopusDeployConnectionListItem(), getFlyioConnectionListItem(), getGitLabConnectionListItem(), getCloudflareConnectionListItem(), @@ -360,7 +366,8 @@ export const validateAppConnectionCredentials = async ( [AppConnection.Okta]: validateOktaConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Chef]: validateChefConnectionCredentials as TAppConnectionCredentialsValidator, [AppConnection.Redis]: validateRedisConnectionCredentials as TAppConnectionCredentialsValidator, - [AppConnection.MongoDB]: validateMongoDBConnectionCredentials as TAppConnectionCredentialsValidator + [AppConnection.MongoDB]: validateMongoDBConnectionCredentials as TAppConnectionCredentialsValidator, + [AppConnection.OctopusDeploy]: validateOctopusDeployConnectionCredentials as TAppConnectionCredentialsValidator }; return VALIDATE_APP_CONNECTION_CREDENTIALS_MAP[appConnection.app](appConnection, gatewayService, gatewayV2Service); @@ -430,6 +437,7 @@ export const getAppConnectionMethodName = (method: TAppConnection["method"]) => return "Simple Bind"; case RenderConnectionMethod.ApiKey: case ChecklyConnectionMethod.ApiKey: + case OctopusDeployConnectionMethod.ApiKey: return "API Key"; case ChefConnectionMethod.UserKey: return "User Key"; @@ -510,7 +518,8 @@ export const TRANSITION_CONNECTION_CREDENTIALS_TO_PLATFORM: Record< [AppConnection.Redis]: platformManagedCredentialsNotSupported, [AppConnection.MongoDB]: platformManagedCredentialsNotSupported, [AppConnection.LaravelForge]: platformManagedCredentialsNotSupported, - [AppConnection.Chef]: platformManagedCredentialsNotSupported + [AppConnection.Chef]: platformManagedCredentialsNotSupported, + [AppConnection.OctopusDeploy]: platformManagedCredentialsNotSupported }; export const enterpriseAppCheck = async ( diff --git a/backend/src/services/app-connection/app-connection-maps.ts b/backend/src/services/app-connection/app-connection-maps.ts index a41589d123..0dfe2335e6 100644 --- a/backend/src/services/app-connection/app-connection-maps.ts +++ b/backend/src/services/app-connection/app-connection-maps.ts @@ -44,7 +44,8 @@ export const APP_CONNECTION_NAME_MAP: Record = { [AppConnection.Redis]: "Redis", [AppConnection.MongoDB]: "MongoDB", [AppConnection.Chef]: "Chef", - [AppConnection.Northflank]: "Northflank" + [AppConnection.Northflank]: "Northflank", + [AppConnection.OctopusDeploy]: "Octopus Deploy" }; export const APP_CONNECTION_PLAN_MAP: Record = { @@ -91,5 +92,6 @@ export const APP_CONNECTION_PLAN_MAP: Record>>; @@ -354,6 +361,7 @@ export type TAppConnectionInput = { id: string } & ( | TRedisConnectionInput | TMongoDBConnectionInput | TChefConnectionInput + | TOctopusDeployConnectionInput ); export type TSqlConnectionInput = @@ -422,7 +430,8 @@ export type TAppConnectionConfig = | TOktaConnectionConfig | TRedisConnectionConfig | TMongoDBConnectionConfig - | TChefConnectionConfig; + | TChefConnectionConfig + | TOctopusDeployConnectionConfig; export type TValidateAppConnectionCredentialsSchema = | TValidateAwsConnectionCredentialsSchema @@ -468,7 +477,8 @@ export type TValidateAppConnectionCredentialsSchema = | TValidateOktaConnectionCredentialsSchema | TValidateRedisConnectionCredentialsSchema | TValidateMongoDBConnectionCredentialsSchema - | TValidateChefConnectionCredentialsSchema; + | TValidateChefConnectionCredentialsSchema + | TValidateOctopusDeployConnectionCredentialsSchema; export type TListAwsConnectionKmsKeys = { connectionId: string; diff --git a/backend/src/services/app-connection/octopus-deploy/index.ts b/backend/src/services/app-connection/octopus-deploy/index.ts new file mode 100644 index 0000000000..d225f65e3d --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/index.ts @@ -0,0 +1,4 @@ +export * from "./octopus-deploy-connection-enums"; +export * from "./octopus-deploy-connection-fns"; +export * from "./octopus-deploy-connection-schemas"; +export * from "./octopus-deploy-connection-types"; diff --git a/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-enums.ts b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-enums.ts new file mode 100644 index 0000000000..39a45664b8 --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-enums.ts @@ -0,0 +1,3 @@ +export enum OctopusDeployConnectionMethod { + ApiKey = "api-key" +} diff --git a/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-fns.ts b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-fns.ts new file mode 100644 index 0000000000..c4f328c5fe --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-fns.ts @@ -0,0 +1,204 @@ +import { AxiosError } from "axios"; + +import { request } from "@app/lib/config/request"; +import { BadRequestError } from "@app/lib/errors"; +import { removeTrailingSlash } from "@app/lib/fn"; +import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; + +import { AppConnection } from "../app-connection-enums"; +import { OctopusDeployConnectionMethod } from "./octopus-deploy-connection-enums"; +import { + TOctopusDeployConnection, + TOctopusDeployConnectionConfig, + TOctopusDeployProject, + TOctopusDeployProjectResponse, + TOctopusDeployScopeValues, + TOctopusDeployScopeValuesResponse, + TOctopusDeploySpace, + TOctopusDeploySpaceResponse +} from "./octopus-deploy-connection-types"; + +export const getOctopusDeployInstanceUrl = async (config: TOctopusDeployConnectionConfig) => { + const instanceUrl = removeTrailingSlash(config.credentials.instanceUrl); + + await blockLocalAndPrivateIpAddresses(instanceUrl); + + return instanceUrl; +}; + +export const getOctopusDeployConnectionListItem = () => { + return { + name: "Octopus Deploy" as const, + app: AppConnection.OctopusDeploy as const, + methods: Object.values(OctopusDeployConnectionMethod) as [OctopusDeployConnectionMethod.ApiKey] + }; +}; + +export const validateOctopusDeployConnectionCredentials = async (config: TOctopusDeployConnectionConfig) => { + const instanceUrl = await getOctopusDeployInstanceUrl(config); + const { apiKey } = config.credentials; + try { + await request.get(`${instanceUrl}/api/users/me`, { + headers: { + "X-Octopus-ApiKey": apiKey, + "X-NuGet-ApiKey": apiKey, + Accept: "application/json" + } + }); + } catch (error: unknown) { + if (error instanceof AxiosError) { + throw new BadRequestError({ + message: `Failed to validate Octopus Deploy credentials: ${error.message || "Unknown error"}` + }); + } + + throw new BadRequestError({ + message: `Failed to validate Octopus Deploy credentials - verify API key is correct` + }); + } + + return config.credentials; +}; + +export const getOctopusDeploySpaces = async ( + appConnection: TOctopusDeployConnection +): Promise => { + const instanceUrl = await getOctopusDeployInstanceUrl(appConnection); + const { apiKey } = appConnection.credentials; + + try { + const { data } = await request.get(`${instanceUrl}/api/spaces/all`, { + headers: { + "X-Octopus-ApiKey": apiKey, + "X-NuGet-ApiKey": apiKey, + Accept: "application/json" + } + }); + + return data.map((space) => ({ + id: space.Id, + name: space.Name, + slug: space.Slug, + isDefault: space.IsDefault + })); + } catch (error: unknown) { + if (error instanceof AxiosError) { + const errorMessage = (error.response?.data as { error: { ErrorMessage: string } })?.error?.ErrorMessage; + + throw new BadRequestError({ + message: `Failed to list Octopus Deploy spaces: ${errorMessage || "Unknown error"}`, + error: error.response?.data + }); + } + + throw new BadRequestError({ + message: "Unable to list Octopus Deploy spaces", + error + }); + } +}; + +export const getOctopusDeployProjects = async ( + appConnection: TOctopusDeployConnection, + spaceId: string +): Promise => { + const instanceUrl = await getOctopusDeployInstanceUrl(appConnection); + const { apiKey } = appConnection.credentials; + + try { + const { data } = await request.get(`${instanceUrl}/api/${spaceId}/projects/all`, { + headers: { + "X-Octopus-ApiKey": apiKey, + "X-NuGet-ApiKey": apiKey, + Accept: "application/json" + } + }); + + return data.map((project) => ({ + id: project.Id, + name: project.Name, + slug: project.Slug + })); + } catch (error: unknown) { + if (error instanceof AxiosError) { + const errorMessage = (error.response?.data as { error: { ErrorMessage: string } })?.error?.ErrorMessage; + + throw new BadRequestError({ + message: `Failed to list Octopus Deploy projects: ${errorMessage || "Unknown error"}`, + error: error.response?.data + }); + } + + throw new BadRequestError({ + message: "Unable to list Octopus Deploy projects", + error + }); + } +}; + +export const getOctopusDeployScopeValues = async ( + appConnection: TOctopusDeployConnection, + spaceId: string, + projectId: string +): Promise => { + const instanceUrl = await getOctopusDeployInstanceUrl(appConnection); + const { apiKey } = appConnection.credentials; + + try { + const { data } = await request.get( + `${instanceUrl}/api/${spaceId}/projects/${projectId}/variables`, + { + headers: { + "X-Octopus-ApiKey": apiKey, + "X-NuGet-ApiKey": apiKey, + Accept: "application/json" + } + } + ); + + const { ScopeValues } = data; + + const scopeValues: TOctopusDeployScopeValues = { + environments: ScopeValues.Environments.map((environment) => ({ + id: environment.Id, + name: environment.Name + })), + roles: ScopeValues.Roles.map((role) => ({ + id: role.Id, + name: role.Name + })), + machines: ScopeValues.Machines.map((machine) => ({ + id: machine.Id, + name: machine.Name + })), + processes: ScopeValues.Processes.map((process) => ({ + id: process.Id, + name: process.Name + })), + actions: ScopeValues.Actions.map((action) => ({ + id: action.Id, + name: action.Name + })), + channels: ScopeValues.Channels.map((channel) => ({ + id: channel.Id, + name: channel.Name + })) + }; + + return scopeValues; + } catch (error: unknown) { + if (error instanceof AxiosError) { + const errorMessage = (error.response?.data as { error: { ErrorMessage: string } })?.error?.ErrorMessage; + + throw new BadRequestError({ + message: `Failed to get Octopus Deploy scope values: ${errorMessage || "Unknown error"}`, + error: error.response?.data + }); + } + + throw new BadRequestError({ + message: "Unable to get Octopus Deploy scope values", + error + }); + } +}; diff --git a/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-schemas.ts b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-schemas.ts new file mode 100644 index 0000000000..30f7cf5022 --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-schemas.ts @@ -0,0 +1,72 @@ +import z from "zod"; + +import { AppConnections } from "@app/lib/api-docs"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { + BaseAppConnectionSchema, + GenericCreateAppConnectionFieldsSchema, + GenericUpdateAppConnectionFieldsSchema +} from "@app/services/app-connection/app-connection-schemas"; + +import { APP_CONNECTION_NAME_MAP } from "../app-connection-maps"; +import { OctopusDeployConnectionMethod } from "./octopus-deploy-connection-enums"; + +export const OctopusDeployConnectionApiKeyCredentialsSchema = z.object({ + instanceUrl: z + .string() + .trim() + .url("Invalid Instance URL") + .min(1, "Instance URL required") + .max(255) + .describe(AppConnections.CREDENTIALS.OCTOPUS_DEPLOY.instanceUrl), + apiKey: z.string().trim().min(1, "API key required").describe(AppConnections.CREDENTIALS.OCTOPUS_DEPLOY.apiKey) +}); + +const BaseOctopusDeployConnectionSchema = BaseAppConnectionSchema.extend({ + app: z.literal(AppConnection.OctopusDeploy) +}); + +export const OctopusDeployConnectionSchema = z.discriminatedUnion("method", [ + BaseOctopusDeployConnectionSchema.extend({ + method: z.literal(OctopusDeployConnectionMethod.ApiKey), + credentials: OctopusDeployConnectionApiKeyCredentialsSchema + }) +]); + +export const SanitizedOctopusDeployConnectionSchema = z.discriminatedUnion("method", [ + BaseOctopusDeployConnectionSchema.extend({ + method: z.literal(OctopusDeployConnectionMethod.ApiKey), + credentials: OctopusDeployConnectionApiKeyCredentialsSchema.pick({ instanceUrl: true }) + }).describe(JSON.stringify({ title: `${APP_CONNECTION_NAME_MAP[AppConnection.OctopusDeploy]} (API Key)` })) +]); + +export const ValidateOctopusDeployConnectionCredentialsSchema = z.discriminatedUnion("method", [ + z.object({ + method: z + .literal(OctopusDeployConnectionMethod.ApiKey) + .describe(AppConnections.CREATE(AppConnection.OctopusDeploy).method), + credentials: OctopusDeployConnectionApiKeyCredentialsSchema.describe( + AppConnections.CREATE(AppConnection.OctopusDeploy).credentials + ) + }) +]); + +export const CreateOctopusDeployConnectionSchema = ValidateOctopusDeployConnectionCredentialsSchema.and( + GenericCreateAppConnectionFieldsSchema(AppConnection.OctopusDeploy) +); + +export const UpdateOctopusDeployConnectionSchema = z + .object({ + credentials: OctopusDeployConnectionApiKeyCredentialsSchema.optional().describe( + AppConnections.UPDATE(AppConnection.OctopusDeploy).credentials + ) + }) + .and(GenericUpdateAppConnectionFieldsSchema(AppConnection.OctopusDeploy)); + +export const OctopusDeployConnectionListItemSchema = z + .object({ + name: z.literal("Octopus Deploy"), + app: z.literal(AppConnection.OctopusDeploy), + methods: z.nativeEnum(OctopusDeployConnectionMethod).array() + }) + .describe(JSON.stringify({ title: APP_CONNECTION_NAME_MAP[AppConnection.OctopusDeploy] })); diff --git a/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-service.ts b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-service.ts new file mode 100644 index 0000000000..a8f969224a --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-service.ts @@ -0,0 +1,65 @@ +import { logger } from "@app/lib/logger"; +import { OrgServiceActor } from "@app/lib/types"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; + +import { + getOctopusDeployProjects, + getOctopusDeployScopeValues, + getOctopusDeploySpaces +} from "./octopus-deploy-connection-fns"; +import { TOctopusDeployConnection } from "./octopus-deploy-connection-types"; + +type TGetAppConnectionFunc = ( + app: AppConnection, + connectionId: string, + actor: OrgServiceActor +) => Promise; + +export const octopusDeployConnectionService = (getAppConnection: TGetAppConnectionFunc) => { + const listSpaces = async (connectionId: string, actor: OrgServiceActor) => { + const appConnection = await getAppConnection(AppConnection.OctopusDeploy, connectionId, actor); + try { + const spaces = await getOctopusDeploySpaces(appConnection); + + return spaces; + } catch (error) { + logger.error({ error, connectionId, actor: actor.type }, "Failed to list Octopus Deploy spaces"); + return []; + } + }; + + const listProjects = async (connectionId: string, spaceId: string, actor: OrgServiceActor) => { + const appConnection = await getAppConnection(AppConnection.OctopusDeploy, connectionId, actor); + + try { + const projects = await getOctopusDeployProjects(appConnection, spaceId); + + return projects; + } catch (error) { + logger.error({ error, connectionId, spaceId, actor: actor.type }, "Failed to list Octopus Deploy projects"); + return []; + } + }; + + const getScopeValues = async (connectionId: string, spaceId: string, projectId: string, actor: OrgServiceActor) => { + const appConnection = await getAppConnection(AppConnection.OctopusDeploy, connectionId, actor); + + try { + const scopeValues = await getOctopusDeployScopeValues(appConnection, spaceId, projectId); + + return scopeValues; + } catch (error) { + logger.error( + { error, connectionId, spaceId, projectId, actor: actor.type }, + "Failed to get Octopus Deploy scope values" + ); + return null; + } + }; + + return { + listSpaces, + listProjects, + getScopeValues + }; +}; diff --git a/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-types.ts b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-types.ts new file mode 100644 index 0000000000..dd5cd22b70 --- /dev/null +++ b/backend/src/services/app-connection/octopus-deploy/octopus-deploy-connection-types.ts @@ -0,0 +1,69 @@ +import z from "zod"; + +import { DiscriminativePick } from "@app/lib/types"; + +import { AppConnection } from "../app-connection-enums"; +import { + CreateOctopusDeployConnectionSchema, + OctopusDeployConnectionSchema, + ValidateOctopusDeployConnectionCredentialsSchema +} from "./octopus-deploy-connection-schemas"; + +export type TOctopusDeployConnection = z.infer; + +export type TOctopusDeployConnectionInput = z.infer & { + app: AppConnection.OctopusDeploy; +}; + +export type TValidateOctopusDeployConnectionCredentialsSchema = typeof ValidateOctopusDeployConnectionCredentialsSchema; + +export type TOctopusDeployConnectionConfig = DiscriminativePick< + TOctopusDeployConnectionInput, + "method" | "app" | "credentials" +>; + +export type TOctopusDeploySpaceResponse = { + Id: string; + Name: string; + Slug: string; + IsDefault: boolean; +}; + +export type TOctopusDeploySpace = { + id: string; + name: string; + slug: string; + isDefault: boolean; +}; + +export type TOctopusDeployProjectResponse = { + Id: string; + Name: string; + Slug: string; +}; + +export type TOctopusDeployProject = { + id: string; + name: string; + slug: string; +}; + +export type TOctopusDeployScopeValuesResponse = { + ScopeValues: { + Environments: { Id: string; Name: string }[]; + Roles: { Id: string; Name: string }[]; + Machines: { Id: string; Name: string }[]; + Processes: { Id: string; Name: string }[]; + Actions: { Id: string; Name: string }[]; + Channels: { Id: string; Name: string }[]; + }; +}; + +export type TOctopusDeployScopeValues = { + environments: { id: string; name: string }[]; + roles: { id: string; name: string }[]; + machines: { id: string; name: string }[]; + processes: { id: string; name: string }[]; + actions: { id: string; name: string }[]; + channels: { id: string; name: string }[]; +}; diff --git a/backend/src/services/approval-policy/approval-policy-service.ts b/backend/src/services/approval-policy/approval-policy-service.ts index 80fa820ac4..882684f353 100644 --- a/backend/src/services/approval-policy/approval-policy-service.ts +++ b/backend/src/services/approval-policy/approval-policy-service.ts @@ -31,6 +31,7 @@ import { import { APPROVAL_POLICY_FACTORY_MAP } from "./approval-policy-factory"; import { ApprovalPolicyStep, + TApprovalPolicyInputs, TApprovalRequest, TCreatePolicyDTO, TCreateRequestDTO, @@ -819,7 +820,18 @@ export const approvalPolicyServiceFactory = ({ ); const grants = await approvalRequestGrantsDAL.find({ projectId, type: policyType }); - return { grants }; + const updatedGrants = grants.map((grant) => { + if ( + grant.status === ApprovalRequestGrantStatus.Active && + grant.expiresAt && + new Date(grant.expiresAt) < new Date() + ) { + return { ...grant, status: ApprovalRequestGrantStatus.Expired }; + } + return grant; + }); + + return { grants: updatedGrants }; }; const getGrantById = async (grantId: string, actor: OrgServiceActor) => { @@ -842,7 +854,15 @@ export const approvalPolicyServiceFactory = ({ ProjectPermissionSub.ApprovalRequestGrants ); - return { grant }; + let { status } = grant; + if ( + grant.status === ApprovalRequestGrantStatus.Active && + grant.expiresAt && + new Date(grant.expiresAt) < new Date() + ) { + status = ApprovalRequestGrantStatus.Expired; + } + return { grant: { ...grant, status } }; }; const revokeGrant = async ( @@ -883,6 +903,36 @@ export const approvalPolicyServiceFactory = ({ return { grant: updatedGrant }; }; + const checkPolicyMatch = async ( + policyType: ApprovalPolicyType, + { projectId, inputs }: { projectId: string; inputs: TApprovalPolicyInputs }, + actor: OrgServiceActor + ) => { + await permissionService.getProjectPermission({ + actor: actor.type, + actorAuthMethod: actor.authMethod, + actorId: actor.id, + actorOrgId: actor.orgId, + projectId, + actionProjectType: ActionProjectType.Any + }); + + const fac = APPROVAL_POLICY_FACTORY_MAP[policyType](policyType); + + const policy = await fac.matchPolicy(approvalPolicyDAL, projectId, inputs); + + if (!policy) { + return { requiresApproval: false, hasActiveGrant: false }; + } + + const hasActiveGrant = await fac.canAccess(approvalRequestGrantsDAL, projectId, actor.id, inputs); + + return { + requiresApproval: !hasActiveGrant, + hasActiveGrant + }; + }; + return { create, list, @@ -897,6 +947,7 @@ export const approvalPolicyServiceFactory = ({ cancelRequest, listGrants, getGrantById, - revokeGrant + revokeGrant, + checkPolicyMatch }; }; diff --git a/backend/src/services/approval-policy/pam-access/pam-access-policy-factory.ts b/backend/src/services/approval-policy/pam-access/pam-access-policy-factory.ts index 21b97e0d16..dce43e3198 100644 --- a/backend/src/services/approval-policy/pam-access/pam-access-policy-factory.ts +++ b/backend/src/services/approval-policy/pam-access/pam-access-policy-factory.ts @@ -26,13 +26,16 @@ export const pamAccessPolicyFactory: TApprovalResourceFactory< let bestMatch: { policy: TPamAccessPolicy; wildcardCount: number; pathLength: number } | null = null; + const normalizedAccountPath = inputs.accountPath.startsWith("/") ? inputs.accountPath.slice(1) : inputs.accountPath; + for (const policy of policies) { const p = policy as TPamAccessPolicy; for (const c of p.conditions.conditions) { // Find the most specific path pattern // TODO(andrey): Make matching logic more advanced by accounting for wildcard positions for (const pathPattern of c.accountPaths) { - if (picomatch(pathPattern)(inputs.accountPath)) { + const normalizedPathPattern = pathPattern.startsWith("/") ? pathPattern.slice(1) : pathPattern; + if (picomatch(normalizedPathPattern)(normalizedAccountPath)) { const wildcardCount = (pathPattern.match(/\*/g) || []).length; const pathLength = pathPattern.length; @@ -65,11 +68,16 @@ export const pamAccessPolicyFactory: TApprovalResourceFactory< revokedAt: null }); + const normalizedAccountPath = inputs.accountPath.startsWith("/") ? inputs.accountPath.slice(1) : inputs.accountPath; + // TODO(andrey): Move some of this check to be part of SQL query return grants.some((grant) => { const grantAttributes = grant.attributes as TPamAccessPolicyInputs; - const isMatch = picomatch(grantAttributes.accountPath); - return isMatch(inputs.accountPath) && (!grant.expiresAt || grant.expiresAt > new Date()); + const normalizedGrantPath = grantAttributes.accountPath.startsWith("/") + ? grantAttributes.accountPath.slice(1) + : grantAttributes.accountPath; + const isMatch = picomatch(normalizedGrantPath); + return isMatch(normalizedAccountPath) && (!grant.expiresAt || grant.expiresAt > new Date()); }); }; diff --git a/backend/src/services/auth/auth-type.ts b/backend/src/services/auth/auth-type.ts index 9e692dcd37..f93f511dd1 100644 --- a/backend/src/services/auth/auth-type.ts +++ b/backend/src/services/auth/auth-type.ts @@ -41,6 +41,7 @@ export enum ActorType { // would extend to AWS, Azure, ... IDENTITY = "identity", Machine = "machine", SCIM_CLIENT = "scimClient", + ACME_PROFILE = "acmeProfile", ACME_ACCOUNT = "acmeAccount", UNKNOWN_USER = "unknownUser" } diff --git a/backend/src/services/certificate-profile/certificate-profile-dal.ts b/backend/src/services/certificate-profile/certificate-profile-dal.ts index 3a8f99f1ae..1572746830 100644 --- a/backend/src/services/certificate-profile/certificate-profile-dal.ts +++ b/backend/src/services/certificate-profile/certificate-profile-dal.ts @@ -168,7 +168,11 @@ export const certificateProfileDALFactory = (db: TDbClient) => { db.ref("autoRenew").withSchema(TableName.PkiApiEnrollmentConfig).as("apiConfigAutoRenew"), db.ref("renewBeforeDays").withSchema(TableName.PkiApiEnrollmentConfig).as("apiConfigRenewBeforeDays"), db.ref("id").withSchema(TableName.PkiAcmeEnrollmentConfig).as("acmeConfigId"), - db.ref("encryptedEabSecret").withSchema(TableName.PkiAcmeEnrollmentConfig).as("acmeConfigEncryptedEabSecret") + db.ref("encryptedEabSecret").withSchema(TableName.PkiAcmeEnrollmentConfig).as("acmeConfigEncryptedEabSecret"), + db + .ref("skipDnsOwnershipVerification") + .withSchema(TableName.PkiAcmeEnrollmentConfig) + .as("acmeConfigSkipDnsOwnershipVerification") ) .where(`${TableName.PkiCertificateProfile}.id`, id) .first(); @@ -198,7 +202,8 @@ export const certificateProfileDALFactory = (db: TDbClient) => { const acmeConfig = result.acmeConfigId ? ({ id: result.acmeConfigId, - encryptedEabSecret: result.acmeConfigEncryptedEabSecret + encryptedEabSecret: result.acmeConfigEncryptedEabSecret, + skipDnsOwnershipVerification: result.acmeConfigSkipDnsOwnershipVerification ?? false } as TCertificateProfileWithConfigs["acmeConfig"]) : undefined; @@ -356,7 +361,11 @@ export const certificateProfileDALFactory = (db: TDbClient) => { db.ref("id").withSchema(TableName.PkiApiEnrollmentConfig).as("apiId"), db.ref("autoRenew").withSchema(TableName.PkiApiEnrollmentConfig).as("apiAutoRenew"), db.ref("renewBeforeDays").withSchema(TableName.PkiApiEnrollmentConfig).as("apiRenewBeforeDays"), - db.ref("id").withSchema(TableName.PkiAcmeEnrollmentConfig).as("acmeId") + db.ref("id").withSchema(TableName.PkiAcmeEnrollmentConfig).as("acmeId"), + db + .ref("skipDnsOwnershipVerification") + .withSchema(TableName.PkiAcmeEnrollmentConfig) + .as("acmeSkipDnsOwnershipVerification") ); if (processedRules) { @@ -393,7 +402,8 @@ export const certificateProfileDALFactory = (db: TDbClient) => { const acmeConfig = result.acmeId ? { - id: result.acmeId as string + id: result.acmeId as string, + skipDnsOwnershipVerification: !!result.acmeSkipDnsOwnershipVerification } : undefined; diff --git a/backend/src/services/certificate-profile/certificate-profile-schemas.ts b/backend/src/services/certificate-profile/certificate-profile-schemas.ts index e6b574dea5..3ac4def572 100644 --- a/backend/src/services/certificate-profile/certificate-profile-schemas.ts +++ b/backend/src/services/certificate-profile/certificate-profile-schemas.ts @@ -30,7 +30,11 @@ export const createCertificateProfileSchema = z renewBeforeDays: z.number().min(1).max(30).optional() }) .optional(), - acmeConfig: z.object({}).optional() + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) + .optional() }) .refine( (data) => { @@ -155,6 +159,11 @@ export const updateCertificateProfileSchema = z autoRenew: z.boolean().default(false), renewBeforeDays: z.number().min(1).max(30).optional() }) + .optional(), + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) .optional() }) .refine( diff --git a/backend/src/services/certificate-profile/certificate-profile-service.ts b/backend/src/services/certificate-profile/certificate-profile-service.ts index 59e3afbd99..4cb60a5229 100644 --- a/backend/src/services/certificate-profile/certificate-profile-service.ts +++ b/backend/src/services/certificate-profile/certificate-profile-service.ts @@ -403,7 +403,13 @@ export const certificateProfileServiceFactory = ({ apiConfigId = apiConfig.id; } else if (data.enrollmentType === EnrollmentType.ACME && data.acmeConfig) { const { encryptedEabSecret } = await generateAndEncryptAcmeEabSecret(projectId, kmsService, projectDAL); - const acmeConfig = await acmeEnrollmentConfigDAL.create({ encryptedEabSecret }, tx); + const acmeConfig = await acmeEnrollmentConfigDAL.create( + { + skipDnsOwnershipVerification: data.acmeConfig.skipDnsOwnershipVerification ?? false, + encryptedEabSecret + }, + tx + ); acmeConfigId = acmeConfig.id; } @@ -505,7 +511,7 @@ export const certificateProfileServiceFactory = ({ const updatedData = finalIssuerType === IssuerType.SELF_SIGNED && existingProfile.caId ? { ...data, caId: null } : data; - const { estConfig, apiConfig, ...profileUpdateData } = updatedData; + const { estConfig, apiConfig, acmeConfig, ...profileUpdateData } = updatedData; const updatedProfile = await certificateProfileDAL.transaction(async (tx) => { if (estConfig && existingProfile.estConfigId) { @@ -547,6 +553,16 @@ export const certificateProfileServiceFactory = ({ ); } + if (acmeConfig && existingProfile.acmeConfigId) { + await acmeEnrollmentConfigDAL.updateById( + existingProfile.acmeConfigId, + { + skipDnsOwnershipVerification: acmeConfig.skipDnsOwnershipVerification ?? false + }, + tx + ); + } + const profileResult = await certificateProfileDAL.updateById(profileId, profileUpdateData, tx); return profileResult; }); diff --git a/backend/src/services/certificate-profile/certificate-profile-types.ts b/backend/src/services/certificate-profile/certificate-profile-types.ts index 3eca249cd0..5b1d62387f 100644 --- a/backend/src/services/certificate-profile/certificate-profile-types.ts +++ b/backend/src/services/certificate-profile/certificate-profile-types.ts @@ -46,7 +46,9 @@ export type TCertificateProfileUpdate = Omit< autoRenew?: boolean; renewBeforeDays?: number; }; - acmeConfig?: unknown; + acmeConfig?: { + skipDnsOwnershipVerification?: boolean; + }; }; export type TCertificateProfileWithConfigs = TCertificateProfile & { @@ -83,6 +85,7 @@ export type TCertificateProfileWithConfigs = TCertificateProfile & { id: string; directoryUrl: string; encryptedEabSecret?: Buffer; + skipDnsOwnershipVerification?: boolean; }; }; diff --git a/backend/src/services/certificate-request/certificate-request-dal.ts b/backend/src/services/certificate-request/certificate-request-dal.ts index df2a4b0c4b..cf91a2a527 100644 --- a/backend/src/services/certificate-request/certificate-request-dal.ts +++ b/backend/src/services/certificate-request/certificate-request-dal.ts @@ -3,10 +3,23 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { TableName, TCertificateRequests, TCertificates } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; +import { sanitizeSqlLikeString } from "@app/lib/fn/string"; import { ormify, selectAllTableCols } from "@app/lib/knex"; +import { + applyProcessedPermissionRulesToQuery, + type ProcessedPermissionRules +} from "@app/lib/knex/permission-filter-utils"; type TCertificateRequestWithCertificate = TCertificateRequests & { certificate: TCertificates | null; + profileName: string | null; +}; + +type TCertificateRequestQueryResult = TCertificateRequests & { + certId: string | null; + certSerialNumber: string | null; + certStatus: string | null; + profileName: string | null; }; export type TCertificateRequestDALFactory = ReturnType; @@ -16,24 +29,41 @@ export const certificateRequestDALFactory = (db: TDbClient) => { const findByIdWithCertificate = async (id: string): Promise => { try { - const certificateRequest = await certificateRequestOrm.findById(id); - if (!certificateRequest) return null; + const result = (await db(TableName.CertificateRequests) + .leftJoin( + TableName.Certificate, + `${TableName.CertificateRequests}.certificateId`, + `${TableName.Certificate}.id` + ) + .leftJoin( + TableName.PkiCertificateProfile, + `${TableName.CertificateRequests}.profileId`, + `${TableName.PkiCertificateProfile}.id` + ) + .where(`${TableName.CertificateRequests}.id`, id) + .select(selectAllTableCols(TableName.CertificateRequests)) + .select(db.ref("slug").withSchema(TableName.PkiCertificateProfile).as("profileName")) + .select(db.ref("id").withSchema(TableName.Certificate).as("certId")) + .select(db.ref("serialNumber").withSchema(TableName.Certificate).as("certSerialNumber")) + .select(db.ref("status").withSchema(TableName.Certificate).as("certStatus")) + .first()) as TCertificateRequestQueryResult | undefined; - if (!certificateRequest.certificateId) { - return { - ...certificateRequest, - certificate: null - }; - } + if (!result) return null; - const certificate = await db(TableName.Certificate) - .where("id", certificateRequest.certificateId) - .select(selectAllTableCols(TableName.Certificate)) - .first(); + const { certId, certSerialNumber, certStatus, profileName, ...certificateRequestData } = result; + + const certificate: TCertificates | null = certId + ? ({ + id: certId, + serialNumber: certSerialNumber, + status: certStatus + } as TCertificates) + : null; return { - ...certificateRequest, - certificate: certificate || null + ...certificateRequestData, + profileName: profileName || null, + certificate }; } catch (error) { throw new DatabaseError({ error, name: "Find certificate request by ID with certificate" }); @@ -82,11 +112,259 @@ export const certificateRequestDALFactory = (db: TDbClient) => { } }; + const findByProjectId = async ( + projectId: string, + options: { + offset?: number; + limit?: number; + search?: string; + status?: string; + fromDate?: Date; + toDate?: Date; + profileIds?: string[]; + } = {}, + processedRules?: ProcessedPermissionRules, + tx?: Knex + ): Promise => { + try { + const { offset = 0, limit = 20, search, status, fromDate, toDate, profileIds } = options; + + let query = (tx || db)(TableName.CertificateRequests) + .leftJoin( + TableName.PkiCertificateProfile, + `${TableName.CertificateRequests}.profileId`, + `${TableName.PkiCertificateProfile}.id` + ) + .where(`${TableName.CertificateRequests}.projectId`, projectId); + + if (profileIds && profileIds.length > 0) { + query = query.whereIn(`${TableName.CertificateRequests}.profileId`, profileIds); + } + + if (search) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + const sanitizedSearch = sanitizeSqlLikeString(search); + query = query.where((builder) => { + void builder + .whereILike(`${TableName.CertificateRequests}.commonName`, `%${sanitizedSearch}%`) + .orWhereILike(`${TableName.CertificateRequests}.altNames`, `%${sanitizedSearch}%`); + }); + } + + if (status) { + query = query.where(`${TableName.CertificateRequests}.status`, status); + } + + if (fromDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, ">=", fromDate); + } + + if (toDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, "<=", toDate); + } + + query = query + .select(selectAllTableCols(TableName.CertificateRequests)) + .select(db.ref("slug").withSchema(TableName.PkiCertificateProfile).as("profileName")); + + if (processedRules) { + query = applyProcessedPermissionRulesToQuery( + query, + TableName.CertificateRequests, + processedRules + ) as typeof query; + } + + const certificateRequests = await query.orderBy("createdAt", "desc").offset(offset).limit(limit); + + return certificateRequests; + } catch (error) { + throw new DatabaseError({ error, name: "Find certificate requests by project ID" }); + } + }; + + const countByProjectId = async ( + projectId: string, + options: { + search?: string; + status?: string; + fromDate?: Date; + toDate?: Date; + profileIds?: string[]; + } = {}, + processedRules?: ProcessedPermissionRules, + tx?: Knex + ): Promise => { + try { + const { search, status, fromDate, toDate, profileIds } = options; + + let query = (tx || db)(TableName.CertificateRequests) + .leftJoin( + TableName.PkiCertificateProfile, + `${TableName.CertificateRequests}.profileId`, + `${TableName.PkiCertificateProfile}.id` + ) + .where(`${TableName.CertificateRequests}.projectId`, projectId); + if (profileIds && profileIds.length > 0) { + query = query.whereIn(`${TableName.CertificateRequests}.profileId`, profileIds); + } + + if (search) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + const sanitizedSearch = sanitizeSqlLikeString(search); + query = query.where((builder) => { + void builder + .whereILike(`${TableName.CertificateRequests}.commonName`, `%${sanitizedSearch}%`) + .orWhereILike(`${TableName.CertificateRequests}.altNames`, `%${sanitizedSearch}%`); + }); + } + + if (status) { + query = query.where(`${TableName.CertificateRequests}.status`, status); + } + + if (fromDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, ">=", fromDate); + } + + if (toDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, "<=", toDate); + } + + if (processedRules) { + query = applyProcessedPermissionRulesToQuery( + query, + TableName.CertificateRequests, + processedRules + ) as typeof query; + } + + const result = await query.count("*").first(); + const count = (result as unknown as Record)?.count; + return parseInt(String(count || "0"), 10); + } catch (error) { + throw new DatabaseError({ error, name: "Count certificate requests by project ID" }); + } + }; + + const findByProjectIdWithCertificate = async ( + projectId: string, + options: { + offset?: number; + limit?: number; + search?: string; + status?: string; + fromDate?: Date; + toDate?: Date; + profileIds?: string[]; + sortBy?: string; + sortOrder?: "asc" | "desc"; + } = {}, + processedRules?: ProcessedPermissionRules, + tx?: Knex + ): Promise => { + try { + const { + offset = 0, + limit = 20, + search, + status, + fromDate, + toDate, + profileIds, + sortBy = "createdAt", + sortOrder = "desc" + } = options; + + let query: Knex.QueryBuilder = (tx || db)(TableName.CertificateRequests) + .leftJoin( + TableName.Certificate, + `${TableName.CertificateRequests}.certificateId`, + `${TableName.Certificate}.id` + ) + .leftJoin( + TableName.PkiCertificateProfile, + `${TableName.CertificateRequests}.profileId`, + `${TableName.PkiCertificateProfile}.id` + ); + + if (profileIds && profileIds.length > 0) { + query = query.whereIn(`${TableName.CertificateRequests}.profileId`, profileIds); + } + + query = query + .select(selectAllTableCols(TableName.CertificateRequests)) + .select(db.ref("slug").withSchema(TableName.PkiCertificateProfile).as("profileName")) + .select(db.ref("id").withSchema(TableName.Certificate).as("certId")) + .select(db.ref("serialNumber").withSchema(TableName.Certificate).as("certSerialNumber")) + .select(db.ref("status").withSchema(TableName.Certificate).as("certStatus")) + .where(`${TableName.CertificateRequests}.projectId`, projectId); + + if (search) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call + const sanitizedSearch = sanitizeSqlLikeString(search); + query = query.where((builder) => { + void builder + .whereILike(`${TableName.CertificateRequests}.commonName`, `%${sanitizedSearch}%`) + .orWhereILike(`${TableName.CertificateRequests}.altNames`, `%${sanitizedSearch}%`); + }); + } + + if (status) { + query = query.where(`${TableName.CertificateRequests}.status`, status); + } + + if (fromDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, ">=", fromDate); + } + + if (toDate) { + query = query.where(`${TableName.CertificateRequests}.createdAt`, "<=", toDate); + } + + if (processedRules) { + query = applyProcessedPermissionRulesToQuery(query, TableName.CertificateRequests, processedRules); + } + + const allowedSortColumns = ["createdAt", "updatedAt", "status", "commonName"]; + const safeSortBy = allowedSortColumns.includes(sortBy) ? sortBy : "createdAt"; + const safeSortOrder = sortOrder === "asc" || sortOrder === "desc" ? sortOrder : "desc"; + + const results = (await query + .orderBy(`${TableName.CertificateRequests}.${safeSortBy}`, safeSortOrder) + .offset(offset) + .limit(limit)) as TCertificateRequestQueryResult[]; + + return results.map((row): TCertificateRequestWithCertificate => { + const { certId, certSerialNumber, certStatus, profileName: rowProfileName, ...certificateRequestData } = row; + + const certificate: TCertificates | null = certId + ? ({ + id: certId, + serialNumber: certSerialNumber, + status: certStatus + } as TCertificates) + : null; + + return { + ...certificateRequestData, + profileName: rowProfileName || null, + certificate + }; + }); + } catch (error) { + throw new DatabaseError({ error, name: "Find certificate requests by project ID with certificates" }); + } + }; + return { ...certificateRequestOrm, findByIdWithCertificate, findPendingByProjectId, updateStatus, - attachCertificate + attachCertificate, + findByProjectId, + countByProjectId, + findByProjectIdWithCertificate }; }; diff --git a/backend/src/services/certificate-request/certificate-request-service.ts b/backend/src/services/certificate-request/certificate-request-service.ts index 3bce23de88..b3e28028f6 100644 --- a/backend/src/services/certificate-request/certificate-request-service.ts +++ b/backend/src/services/certificate-request/certificate-request-service.ts @@ -9,6 +9,7 @@ import { ProjectPermissionCertificateProfileActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; +import { getProcessedPermissionRules } from "@app/lib/casl/permission-filter-utils"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; import { TCertificateServiceFactory } from "@app/services/certificate/certificate-service"; @@ -21,6 +22,7 @@ import { TCreateCertificateRequestDTO, TGetCertificateFromRequestDTO, TGetCertificateRequestDTO, + TListCertificateRequestsDTO, TUpdateCertificateRequestStatusDTO } from "./certificate-request-types"; @@ -91,6 +93,7 @@ export const certificateRequestServiceFactory = ({ permissionService }: TCertificateRequestServiceFactoryDep) => { const createCertificateRequest = async ({ + acmeOrderId, actor, actorId, actorAuthMethod, @@ -123,6 +126,7 @@ export const certificateRequestServiceFactory = ({ { status, projectId, + acmeOrderId, ...validatedData }, tx @@ -283,11 +287,76 @@ export const certificateRequestServiceFactory = ({ return certificateRequestDAL.attachCertificate(certificateRequestId, certificateId); }; + const listCertificateRequests = async ({ + actor, + actorId, + actorAuthMethod, + actorOrgId, + projectId, + offset = 0, + limit = 20, + search, + status, + fromDate, + toDate, + profileIds, + sortBy, + sortOrder + }: TListCertificateRequestsDTO) => { + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.CertificateManager + }); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionCertificateActions.Read, + ProjectPermissionSub.Certificates + ); + + const processedRules = getProcessedPermissionRules( + permission, + ProjectPermissionCertificateActions.Read, + ProjectPermissionSub.Certificates + ); + + const options: Parameters[1] = { + offset, + limit, + search, + status, + fromDate, + toDate, + profileIds, + sortBy, + sortOrder + }; + + const [certificateRequests, totalCount] = await Promise.all([ + certificateRequestDAL.findByProjectIdWithCertificate(projectId, options, processedRules), + certificateRequestDAL.countByProjectId(projectId, options, processedRules) + ]); + + const mappedCertificateRequests = certificateRequests.map((request) => ({ + ...request, + status: request.status as CertificateRequestStatus + })); + + return { + certificateRequests: mappedCertificateRequests, + totalCount + }; + }; + return { createCertificateRequest, getCertificateRequest, getCertificateFromRequest, updateCertificateRequestStatus, - attachCertificateToRequest + attachCertificateToRequest, + listCertificateRequests }; }; diff --git a/backend/src/services/certificate-request/certificate-request-types.ts b/backend/src/services/certificate-request/certificate-request-types.ts index 0c62973b2f..9b96515974 100644 --- a/backend/src/services/certificate-request/certificate-request-types.ts +++ b/backend/src/services/certificate-request/certificate-request-types.ts @@ -21,6 +21,7 @@ export type TCreateCertificateRequestDTO = TProjectPermission & { metadata?: string; status: CertificateRequestStatus; certificateId?: string; + acmeOrderId?: string; }; export type TGetCertificateRequestDTO = TProjectPermission & { @@ -41,3 +42,15 @@ export type TAttachCertificateToRequestDTO = { certificateRequestId: string; certificateId: string; }; + +export type TListCertificateRequestsDTO = TProjectPermission & { + offset?: number; + limit?: number; + search?: string; + status?: CertificateRequestStatus; + fromDate?: Date; + toDate?: Date; + profileIds?: string[]; + sortBy?: string; + sortOrder?: "asc" | "desc"; +}; diff --git a/backend/src/services/certificate/certificate-dal.ts b/backend/src/services/certificate/certificate-dal.ts index 72cef90fad..0c27c12833 100644 --- a/backend/src/services/certificate/certificate-dal.ts +++ b/backend/src/services/certificate/certificate-dal.ts @@ -1,13 +1,13 @@ -import RE2 from "re2"; - import { TDbClient } from "@app/db"; import { TableName, TCertificates } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; +import { sanitizeSqlLikeString } from "@app/lib/fn/string"; import { ormify, selectAllTableCols } from "@app/lib/knex"; import { applyProcessedPermissionRulesToQuery, type ProcessedPermissionRules } from "@app/lib/knex/permission-filter-utils"; +import { isUuidV4 } from "@app/lib/validator"; import { CertStatus } from "./certificate-types"; @@ -48,11 +48,21 @@ export const certificateDALFactory = (db: TDbClient) => { const countCertificatesInProject = async ({ projectId, friendlyName, - commonName + commonName, + search, + status, + profileIds, + fromDate, + toDate }: { projectId: string; friendlyName?: string; commonName?: string; + search?: string; + status?: string | string[]; + profileIds?: string[]; + fromDate?: Date; + toDate?: Date; }) => { try { interface CountResult { @@ -66,15 +76,69 @@ export const certificateDALFactory = (db: TDbClient) => { .where(`${TableName.Project}.id`, projectId); if (friendlyName) { - const sanitizedValue = String(friendlyName).replace(new RE2("[%_\\\\]", "g"), "\\$&"); + const sanitizedValue = sanitizeSqlLikeString(friendlyName); query = query.andWhere(`${TableName.Certificate}.friendlyName`, "like", `%${sanitizedValue}%`); } if (commonName) { - const sanitizedValue = String(commonName).replace(new RE2("[%_\\\\]", "g"), "\\$&"); + const sanitizedValue = sanitizeSqlLikeString(commonName); query = query.andWhere(`${TableName.Certificate}.commonName`, "like", `%${sanitizedValue}%`); } + if (search) { + const sanitizedValue = sanitizeSqlLikeString(search); + query = query.andWhere((qb) => { + void qb + .where(`${TableName.Certificate}.commonName`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.altNames`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.serialNumber`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.friendlyName`, "like", `%${sanitizedValue}%`); + + if (isUuidV4(sanitizedValue)) { + void qb.orWhere(`${TableName.Certificate}.id`, sanitizedValue); + } + }); + } + + if (status) { + const now = new Date(); + const statuses = Array.isArray(status) ? status : [status]; + + query = query.andWhere((qb) => { + statuses.forEach((statusValue, index) => { + const whereMethod = index === 0 ? "where" : "orWhere"; + + if (statusValue === CertStatus.ACTIVE) { + void qb[whereMethod]((innerQb) => { + void innerQb + .where(`${TableName.Certificate}.notAfter`, ">", now) + .andWhere(`${TableName.Certificate}.status`, "!=", CertStatus.REVOKED); + }); + } else if (statusValue === CertStatus.EXPIRED) { + void qb[whereMethod]((innerQb) => { + void innerQb + .where(`${TableName.Certificate}.notAfter`, "<=", now) + .andWhere(`${TableName.Certificate}.status`, "!=", CertStatus.REVOKED); + }); + } else { + void qb[whereMethod](`${TableName.Certificate}.status`, statusValue); + } + }); + }); + } + + if (fromDate) { + query = query.andWhere(`${TableName.Certificate}.createdAt`, ">=", fromDate); + } + + if (toDate) { + query = query.andWhere(`${TableName.Certificate}.createdAt`, "<=", toDate); + } + + if (profileIds) { + query = query.whereIn(`${TableName.Certificate}.profileId`, profileIds); + } + const count = await query.count("*").first(); return parseInt((count as unknown as CountResult).count || "0", 10); @@ -160,7 +224,7 @@ export const certificateDALFactory = (db: TDbClient) => { Object.entries(filter).forEach(([key, value]) => { if (value !== undefined && value !== null) { if (key === "friendlyName" || key === "commonName") { - const sanitizedValue = String(value).replace(new RE2("[%_\\\\]", "g"), "\\$&"); + const sanitizedValue = sanitizeSqlLikeString(String(value)); query = query.andWhere(`${TableName.Certificate}.${key}`, "like", `%${sanitizedValue}%`); } else { query = query.andWhere(`${TableName.Certificate}.${key}`, value); @@ -213,12 +277,12 @@ export const certificateDALFactory = (db: TDbClient) => { .whereNull(`${TableName.Certificate}.renewedByCertificateId`); if (friendlyName) { - const sanitizedValue = String(friendlyName).replace(new RE2("[%_\\\\]", "g"), "\\$&"); + const sanitizedValue = sanitizeSqlLikeString(friendlyName); query = query.andWhere(`${TableName.Certificate}.friendlyName`, "like", `%${sanitizedValue}%`); } if (commonName) { - const sanitizedValue = String(commonName).replace(new RE2("[%_\\\\]", "g"), "\\$&"); + const sanitizedValue = sanitizeSqlLikeString(commonName); query = query.andWhere(`${TableName.Certificate}.commonName`, "like", `%${sanitizedValue}%`); } @@ -275,7 +339,17 @@ export const certificateDALFactory = (db: TDbClient) => { }; const findWithPrivateKeyInfo = async ( - filter: Partial, + filter: Partial< + TCertificates & { + friendlyName?: string; + commonName?: string; + search?: string; + status?: string | string[]; + profileIds?: string[]; + fromDate?: Date; + toDate?: Date; + } + >, options?: { offset?: number; limit?: number; sort?: [string, "asc" | "desc"][] }, permissionFilters?: ProcessedPermissionRules ): Promise<(TCertificates & { hasPrivateKey: boolean })[]> => { @@ -286,17 +360,78 @@ export const certificateDALFactory = (db: TDbClient) => { .select(selectAllTableCols(TableName.Certificate)) .select(db.ref(`${TableName.CertificateSecret}.certId`).as("privateKeyRef")); - Object.entries(filter).forEach(([key, value]) => { + const { friendlyName, commonName, search, status, profileIds, fromDate, toDate, ...regularFilters } = filter; + + Object.entries(regularFilters).forEach(([key, value]) => { if (value !== undefined && value !== null) { - if (key === "friendlyName" || key === "commonName") { - const sanitizedValue = String(value).replace(new RE2("[%_\\\\]", "g"), "\\$&"); - query = query.andWhere(`${TableName.Certificate}.${key}`, "like", `%${sanitizedValue}%`); - } else { - query = query.andWhere(`${TableName.Certificate}.${key}`, value); - } + query = query.andWhere(`${TableName.Certificate}.${key}`, value); } }); + if (friendlyName) { + const sanitizedValue = sanitizeSqlLikeString(friendlyName); + query = query.andWhere(`${TableName.Certificate}.friendlyName`, "like", `%${sanitizedValue}%`); + } + + if (commonName) { + const sanitizedValue = sanitizeSqlLikeString(commonName); + query = query.andWhere(`${TableName.Certificate}.commonName`, "like", `%${sanitizedValue}%`); + } + + if (search) { + const sanitizedValue = sanitizeSqlLikeString(search); + query = query.andWhere((qb) => { + void qb + .where(`${TableName.Certificate}.commonName`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.altNames`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.serialNumber`, "like", `%${sanitizedValue}%`) + .orWhere(`${TableName.Certificate}.friendlyName`, "like", `%${sanitizedValue}%`); + + if (isUuidV4(sanitizedValue)) { + void qb.orWhere(`${TableName.Certificate}.id`, sanitizedValue); + } + }); + } + + if (status) { + const now = new Date(); + const statuses = Array.isArray(status) ? status : [status]; + + query = query.andWhere((qb) => { + statuses.forEach((statusValue, index) => { + const whereMethod = index === 0 ? "where" : "orWhere"; + + if (statusValue === CertStatus.ACTIVE) { + void qb[whereMethod]((innerQb) => { + void innerQb + .where(`${TableName.Certificate}.notAfter`, ">", now) + .andWhere(`${TableName.Certificate}.status`, "!=", CertStatus.REVOKED); + }); + } else if (statusValue === CertStatus.EXPIRED) { + void qb[whereMethod]((innerQb) => { + void innerQb + .where(`${TableName.Certificate}.notAfter`, "<=", now) + .andWhere(`${TableName.Certificate}.status`, "!=", CertStatus.REVOKED); + }); + } else { + void qb[whereMethod](`${TableName.Certificate}.status`, statusValue); + } + }); + }); + } + + if (fromDate) { + query = query.andWhere(`${TableName.Certificate}.createdAt`, ">=", fromDate); + } + + if (toDate) { + query = query.andWhere(`${TableName.Certificate}.createdAt`, "<=", toDate); + } + + if (profileIds) { + query = query.whereIn(`${TableName.Certificate}.profileId`, profileIds); + } + if (permissionFilters) { query = applyProcessedPermissionRulesToQuery(query, TableName.Certificate, permissionFilters) as typeof query; } diff --git a/backend/src/services/enrollment-config/acme-enrollment-config-dal.ts b/backend/src/services/enrollment-config/acme-enrollment-config-dal.ts index afa8f17ef5..758c08491d 100644 --- a/backend/src/services/enrollment-config/acme-enrollment-config-dal.ts +++ b/backend/src/services/enrollment-config/acme-enrollment-config-dal.ts @@ -1,61 +1,13 @@ -import { Knex } from "knex"; - import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { DatabaseError } from "@app/lib/errors"; import { ormify } from "@app/lib/knex"; -import { TAcmeEnrollmentConfigInsert, TAcmeEnrollmentConfigUpdate } from "./enrollment-config-types"; - export type TAcmeEnrollmentConfigDALFactory = ReturnType; export const acmeEnrollmentConfigDALFactory = (db: TDbClient) => { const acmeEnrollmentConfigOrm = ormify(db, TableName.PkiAcmeEnrollmentConfig); - const create = async (data: TAcmeEnrollmentConfigInsert, tx?: Knex) => { - try { - const result = await (tx || db)(TableName.PkiAcmeEnrollmentConfig).insert(data).returning("*"); - const [acmeConfig] = result; - - if (!acmeConfig) { - throw new Error("Failed to create ACME enrollment config"); - } - - return acmeConfig; - } catch (error) { - throw new DatabaseError({ error, name: "Create ACME enrollment config" }); - } - }; - - const updateById = async (id: string, data: TAcmeEnrollmentConfigUpdate, tx?: Knex) => { - try { - const result = await (tx || db)(TableName.PkiAcmeEnrollmentConfig).where({ id }).update(data).returning("*"); - const [acmeConfig] = result; - - if (!acmeConfig) { - return null; - } - - return acmeConfig; - } catch (error) { - throw new DatabaseError({ error, name: "Update ACME enrollment config" }); - } - }; - - const findById = async (id: string, tx?: Knex) => { - try { - const acmeConfig = await (tx || db)(TableName.PkiAcmeEnrollmentConfig).where({ id }).first(); - - return acmeConfig || null; - } catch (error) { - throw new DatabaseError({ error, name: "Find ACME enrollment config by id" }); - } - }; - return { - ...acmeEnrollmentConfigOrm, - create, - updateById, - findById + ...acmeEnrollmentConfigOrm }; }; diff --git a/backend/src/services/enrollment-config/enrollment-config-types.ts b/backend/src/services/enrollment-config/enrollment-config-types.ts index 7fe5a475d0..2ea68faa7f 100644 --- a/backend/src/services/enrollment-config/enrollment-config-types.ts +++ b/backend/src/services/enrollment-config/enrollment-config-types.ts @@ -37,4 +37,6 @@ export interface TApiConfigData { renewBeforeDays?: number; } -export interface TAcmeConfigData {} +export interface TAcmeConfigData { + skipDnsOwnershipVerification?: boolean; +} diff --git a/backend/src/services/group-project/group-project-service.ts b/backend/src/services/group-project/group-project-service.ts index 4a4a614967..77497a26cd 100644 --- a/backend/src/services/group-project/group-project-service.ts +++ b/backend/src/services/group-project/group-project-service.ts @@ -10,7 +10,7 @@ import { TGroupDALFactory } from "../../ee/services/group/group-dal"; import { TProjectDALFactory } from "../project/project-dal"; type TGroupProjectServiceFactoryDep = { - groupDAL: Pick; + groupDAL: Pick; projectDAL: Pick; permissionService: Pick; }; @@ -51,7 +51,7 @@ export const groupProjectServiceFactory = ({ }); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionGroupActions.Read, ProjectPermissionSub.Groups); - const { members, totalCount } = await groupDAL.findAllGroupPossibleMembers({ + const { members, totalCount } = await groupDAL.findAllGroupPossibleUsers({ orgId: project.orgId, groupId: id, offset, diff --git a/backend/src/services/identity-access-token/identity-access-token-dal.ts b/backend/src/services/identity-access-token/identity-access-token-dal.ts index 2a67866d3a..29b12ceb3d 100644 --- a/backend/src/services/identity-access-token/identity-access-token-dal.ts +++ b/backend/src/services/identity-access-token/identity-access-token-dal.ts @@ -32,7 +32,7 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => { const removeExpiredTokens = async (tx?: Knex) => { logger.info(`${QueueName.DailyResourceCleanUp}: remove expired access token started`); - const BATCH_SIZE = 10000; + const BATCH_SIZE = 5000; const MAX_RETRY_ON_FAILURE = 3; const QUERY_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes const MAX_TTL = 315_360_000; // Maximum TTL value in seconds (10 years) @@ -101,7 +101,7 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => { } finally { // eslint-disable-next-line no-await-in-loop await new Promise((resolve) => { - setTimeout(resolve, 10); // time to breathe for db + setTimeout(resolve, 500); // time to breathe for db }); } isRetrying = numberOfRetryOnFailure > 0; diff --git a/backend/src/services/project/project-dal.ts b/backend/src/services/project/project-dal.ts index 11d4239db0..a25329aee4 100644 --- a/backend/src/services/project/project-dal.ts +++ b/backend/src/services/project/project-dal.ts @@ -25,12 +25,27 @@ export const projectDALFactory = (db: TDbClient) => { const findIdentityProjects = async (identityId: string, orgId: string, projectType?: ProjectType) => { try { + const identityGroupSubquery = db + .replicaNode()(TableName.Groups) + .leftJoin( + TableName.IdentityGroupMembership, + `${TableName.IdentityGroupMembership}.groupId`, + `${TableName.Groups}.id` + ) + .where(`${TableName.Groups}.orgId`, orgId) + .where(`${TableName.IdentityGroupMembership}.identityId`, identityId) + .select(db.ref("id").withSchema(TableName.Groups)); + const workspaces = await db .replicaNode()(TableName.Membership) .where(`${TableName.Membership}.scope`, AccessScope.Project) - .where(`${TableName.Membership}.actorIdentityId`, identityId) .join(TableName.Project, `${TableName.Membership}.scopeProjectId`, `${TableName.Project}.id`) .where(`${TableName.Project}.orgId`, orgId) + .andWhere((qb) => { + void qb + .where(`${TableName.Membership}.actorIdentityId`, identityId) + .orWhereIn(`${TableName.Membership}.actorGroupId`, identityGroupSubquery); + }) .andWhere((qb) => { if (projectType) { void qb.where(`${TableName.Project}.type`, projectType); @@ -347,11 +362,25 @@ export const projectDALFactory = (db: TDbClient) => { .where(`${TableName.Groups}.orgId`, dto.orgId) .where(`${TableName.UserGroupMembership}.userId`, dto.actorId) .select(db.ref("id").withSchema(TableName.Groups)); + + const identityGroupMembershipSubquery = db + .replicaNode()(TableName.Groups) + .leftJoin( + TableName.IdentityGroupMembership, + `${TableName.IdentityGroupMembership}.groupId`, + `${TableName.Groups}.id` + ) + .where(`${TableName.Groups}.orgId`, dto.orgId) + .where(`${TableName.IdentityGroupMembership}.identityId`, dto.actorId) + .select(db.ref("id").withSchema(TableName.Groups)); + const membershipSubQuery = db(TableName.Membership) .where(`${TableName.Membership}.scope`, AccessScope.Project) .where((qb) => { if (dto.actor === ActorType.IDENTITY) { - void qb.where(`${TableName.Membership}.actorIdentityId`, dto.actorId); + void qb + .where(`${TableName.Membership}.actorIdentityId`, dto.actorId) + .orWhereIn(`${TableName.Membership}.actorGroupId`, identityGroupMembershipSubquery); } else { void qb .where(`${TableName.Membership}.actorUserId`, dto.actorId) diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index cf1771abad..cc2abe6f91 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -68,16 +68,11 @@ import { NotificationType } from "../notification/notification-types"; import { TOrgDALFactory } from "../org/org-dal"; import { TPkiAlertDALFactory } from "../pki-alert/pki-alert-dal"; import { TPkiCollectionDALFactory } from "../pki-collection/pki-collection-dal"; -import { TProjectBotServiceFactory } from "../project-bot/project-bot-service"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { getPredefinedRoles } from "../project-role/project-role-fns"; -import { TReminderServiceFactory } from "../reminder/reminder-types"; import { TRoleDALFactory } from "../role/role-dal"; -import { TSecretDALFactory } from "../secret/secret-dal"; -import { fnDeleteProjectSecretReminders } from "../secret/secret-fns"; import { ROOT_FOLDER_NAME, TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; -import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; import { TProjectSlackConfigDALFactory } from "../slack/project-slack-config-dal"; import { validateSlackChannelsField } from "../slack/slack-auth-validators"; import { TSlackIntegrationDALFactory } from "../slack/slack-integration-dal"; @@ -133,10 +128,7 @@ type TProjectServiceFactoryDep = { projectSshConfigDAL: Pick; projectQueue: TProjectQueueFactory; userDAL: TUserDALFactory; - projectBotService: Pick; folderDAL: Pick; - secretDAL: Pick; - secretV2BridgeDAL: Pick; projectEnvDAL: Pick; projectMembershipDAL: Pick; membershipUserDAL: Pick; @@ -192,7 +184,6 @@ type TProjectServiceFactoryDep = { | "createCipherPairWithDataKey" >; projectTemplateService: TProjectTemplateServiceFactory; - reminderService: Pick; notificationService: Pick; }; @@ -201,11 +192,8 @@ export type TProjectServiceFactory = ReturnType; export const projectServiceFactory = ({ projectDAL, projectSshConfigDAL, - secretDAL, - secretV2BridgeDAL, projectQueue, permissionService, - projectBotService, orgDAL, userDAL, folderDAL, @@ -232,7 +220,6 @@ export const projectServiceFactory = ({ microsoftTeamsIntegrationDAL, projectTemplateService, smtpService, - reminderService, notificationService, membershipIdentityDAL, membershipUserDAL, @@ -521,14 +508,6 @@ export const projectServiceFactory = ({ await userDAL.deleteById(projectGhostUser.id, tx); } - await fnDeleteProjectSecretReminders(project.id, { - secretDAL, - secretV2BridgeDAL, - reminderService, - projectBotService, - folderDAL - }); - return delProject; }); @@ -942,6 +921,11 @@ export const projectServiceFactory = ({ friendlyName, commonName, forPkiSync = false, + search, + status, + profileIds, + fromDate, + toDate, actorId, actorOrgId, actorAuthMethod, @@ -968,7 +952,12 @@ export const projectServiceFactory = ({ const regularFilters = { projectId, ...(friendlyName && { friendlyName }), - ...(commonName && { commonName }) + ...(commonName && { commonName }), + ...(search && { search }), + ...(status && { status: Array.isArray(status) ? status[0] : status }), + ...(profileIds && { profileIds }), + ...(fromDate && { fromDate }), + ...(toDate && { toDate }) }; const permissionFilters = getProcessedPermissionRules( permission, @@ -991,7 +980,12 @@ export const projectServiceFactory = ({ const countFilter = { projectId, ...(regularFilters.friendlyName && { friendlyName: String(regularFilters.friendlyName) }), - ...(regularFilters.commonName && { commonName: String(regularFilters.commonName) }) + ...(regularFilters.commonName && { commonName: String(regularFilters.commonName) }), + ...(regularFilters.search && { search: String(regularFilters.search) }), + ...(regularFilters.status && { status: String(regularFilters.status) }), + ...(regularFilters.profileIds && { profileIds: regularFilters.profileIds }), + ...(regularFilters.fromDate && { fromDate: regularFilters.fromDate }), + ...(regularFilters.toDate && { toDate: regularFilters.toDate }) }; const count = forPkiSync @@ -1986,7 +1980,7 @@ export const projectServiceFactory = ({ if (project.type === ProjectType.SecretManager) { projectTypeUrl = "secret-management"; } else if (project.type === ProjectType.CertificateManager) { - projectTypeUrl = "cert-management"; + projectTypeUrl = "cert-manager"; } const callbackPath = `/organizations/${project.orgId}/projects/${projectTypeUrl}/${project.id}/access-management?selectedTab=members&requesterEmail=${userDetails.email}`; diff --git a/backend/src/services/project/project-types.ts b/backend/src/services/project/project-types.ts index 2d27c7c446..483f857c2f 100644 --- a/backend/src/services/project/project-types.ts +++ b/backend/src/services/project/project-types.ts @@ -144,6 +144,11 @@ export type TListProjectCertsDTO = { friendlyName?: string; commonName?: string; forPkiSync?: boolean; + search?: string; + status?: string | string[]; + profileIds?: string[]; + fromDate?: Date; + toDate?: Date; } & Omit; export type TListProjectAlertsDTO = TProjectPermission; diff --git a/backend/src/services/secret-sync/octopus-deploy/index.ts b/backend/src/services/secret-sync/octopus-deploy/index.ts new file mode 100644 index 0000000000..4b1ad58b6e --- /dev/null +++ b/backend/src/services/secret-sync/octopus-deploy/index.ts @@ -0,0 +1,4 @@ +export * from "./octopus-deploy-sync-constants"; +export * from "./octopus-deploy-sync-fns"; +export * from "./octopus-deploy-sync-schemas"; +export * from "./octopus-deploy-sync-types"; diff --git a/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-constants.ts b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-constants.ts new file mode 100644 index 0000000000..8f16a4cec3 --- /dev/null +++ b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-constants.ts @@ -0,0 +1,10 @@ +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; +import { TSecretSyncListItem } from "@app/services/secret-sync/secret-sync-types"; + +export const OCTOPUS_DEPLOY_SYNC_LIST_OPTION: TSecretSyncListItem = { + name: "Octopus Deploy", + destination: SecretSync.OctopusDeploy, + connection: AppConnection.OctopusDeploy, + canImportSecrets: false +}; diff --git a/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-fns.ts b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-fns.ts new file mode 100644 index 0000000000..7795464a3c --- /dev/null +++ b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-fns.ts @@ -0,0 +1,151 @@ +import { request } from "@app/lib/config/request"; +import { BadRequestError } from "@app/lib/errors"; +import { getOctopusDeployInstanceUrl } from "@app/services/app-connection/octopus-deploy"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; +import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; + +import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps"; +import { + TOctopusDeploySyncWithCredentials, + TOctopusDeployVariable, + TOctopusDeployVariableSet +} from "./octopus-deploy-sync-types"; + +export const OctopusDeploySyncFns = { + getAuthHeader(apiKey: string): Record { + return { + "X-NuGet-ApiKey": apiKey, + "X-Octopus-ApiKey": apiKey, + Accept: "application/json", + "Content-Type": "application/json" + }; + }, + + buildVariableUrl(instanceUrl: string, spaceId: string, projectId: string, scope: string): string { + switch (scope) { + case "project": + return `${instanceUrl}/api/${spaceId}/projects/${projectId}/variables`; + default: + throw new BadRequestError({ + message: `Unsupported Octopus Deploy scope: ${scope}` + }); + } + }, + + async syncSecrets(secretSync: TOctopusDeploySyncWithCredentials, secretMap: TSecretMap) { + const { + connection, + environment, + syncOptions: { disableSecretDeletion, keySchema } + } = secretSync; + const instanceUrl = await getOctopusDeployInstanceUrl(connection); + const { apiKey } = connection.credentials; + + const { spaceId, projectId, scope } = secretSync.destinationConfig; + + const url = this.buildVariableUrl(instanceUrl, spaceId, projectId, scope); + + const { data: variableSet } = await request.get(url, { + headers: this.getAuthHeader(apiKey) + }); + + // Get scope values from destination config (if configured) + const scopeValues = secretSync.destinationConfig.scopeValues || {}; + + const nonSensitiveVariables: TOctopusDeployVariable[] = []; + let sensitiveVariables: TOctopusDeployVariable[] = []; + + variableSet.Variables.forEach((variable) => { + if (!variable.IsSensitive && variable.Type !== "Sensitive") { + nonSensitiveVariables.push(variable); + } else { + // sensitive variables, this could contain infisical secrets + sensitiveVariables.push(variable); + } + }); + + // Build new variables array from secret map + const newVariables: TOctopusDeployVariable[] = Object.entries(secretMap).map(([key, secret]) => ({ + Name: key, + Value: secret.value, + Description: secret.comment || "", + Scope: { + Environment: scopeValues.environments, + Role: scopeValues.roles, + Machine: scopeValues.machines, + ProcessOwner: scopeValues.processes, + Action: scopeValues.actions, + Channel: scopeValues.channels + }, + IsEditable: false, + Prompt: null, + Type: "Sensitive", + IsSensitive: true + })); + + const keysToDelete = new Set(); + + if (!disableSecretDeletion) { + sensitiveVariables.forEach((variable) => { + if (!matchesSchema(variable.Name, environment?.slug || "", keySchema)) return; + + if (!secretMap[variable.Name]) { + keysToDelete.add(variable.Name); + } + }); + } + + sensitiveVariables = sensitiveVariables.filter((variable) => !keysToDelete.has(variable.Name)); + + const newVariableKeys = newVariables.map((variable) => variable.Name); + // Keep sensitive variables that are not in the new variables array, to avoid duplication + sensitiveVariables = sensitiveVariables.filter((variable) => !newVariableKeys.includes(variable.Name)); + + await request.put( + url, + { + ...variableSet, + Variables: [...nonSensitiveVariables, ...sensitiveVariables, ...newVariables] + }, + { + headers: this.getAuthHeader(apiKey) + } + ); + }, + async removeSecrets(secretSync: TOctopusDeploySyncWithCredentials, secretMap: TSecretMap) { + const { + connection, + destinationConfig: { spaceId, projectId, scope } + } = secretSync; + + const instanceUrl = await getOctopusDeployInstanceUrl(connection); + const { apiKey } = connection.credentials; + + const url = this.buildVariableUrl(instanceUrl, spaceId, projectId, scope); + + const { data: variableSet } = await request.get(url, { + headers: this.getAuthHeader(apiKey) + }); + + const infisicalSecretKeys = Object.keys(secretMap); + + const variablesToDelete = variableSet.Variables.filter( + (variable) => + infisicalSecretKeys.includes(variable.Name) && variable.IsSensitive === true && variable.Type === "Sensitive" + ).map((variable) => variable.Id); + + await request.put( + url, + { + ...variableSet, + Variables: variableSet.Variables.filter((variable) => !variablesToDelete.includes(variable.Id)) + }, + { + headers: this.getAuthHeader(apiKey) + } + ); + }, + async getSecrets(secretSync: TOctopusDeploySyncWithCredentials): Promise { + throw new Error(`${SECRET_SYNC_NAME_MAP[secretSync.destination]} does not support importing secrets.`); + } +}; diff --git a/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-schemas.ts b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-schemas.ts new file mode 100644 index 0000000000..e51d5f85a0 --- /dev/null +++ b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-schemas.ts @@ -0,0 +1,80 @@ +import { z } from "zod"; + +import { SecretSyncs } from "@app/lib/api-docs"; +import { AppConnection } from "@app/services/app-connection/app-connection-enums"; +import { SecretSync } from "@app/services/secret-sync/secret-sync-enums"; +import { + BaseSecretSyncSchema, + GenericCreateSecretSyncFieldsSchema, + GenericUpdateSecretSyncFieldsSchema +} from "@app/services/secret-sync/secret-sync-schemas"; +import { TSyncOptionsConfig } from "@app/services/secret-sync/secret-sync-types"; + +import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps"; + +export enum OctopusDeploySyncScope { + Project = "project" +} + +const OctopusDeploySyncDestinationConfigBaseSchema = z.object({ + spaceId: z.string().min(1, "Space ID is required").describe(SecretSyncs.DESTINATION_CONFIG.OCTOPUS_DEPLOY.spaceId), + spaceName: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.OCTOPUS_DEPLOY.spaceName), + scope: z.nativeEnum(OctopusDeploySyncScope).default(OctopusDeploySyncScope.Project) +}); + +export const OctopusDeploySyncDestinationConfigSchema = z.intersection( + OctopusDeploySyncDestinationConfigBaseSchema, + z.discriminatedUnion("scope", [ + z.object({ + scope: z.literal(OctopusDeploySyncScope.Project), + projectId: z + .string() + .min(1, "Project ID is required") + .describe(SecretSyncs.DESTINATION_CONFIG.OCTOPUS_DEPLOY.projectId), + projectName: z.string().optional().describe(SecretSyncs.DESTINATION_CONFIG.OCTOPUS_DEPLOY.projectName), + scopeValues: z + .object({ + environments: z.array(z.string()).optional(), + roles: z.array(z.string()).optional(), + machines: z.array(z.string()).optional(), + processes: z.array(z.string()).optional(), + actions: z.array(z.string()).optional(), + channels: z.array(z.string()).optional() + }) + .optional() + .describe(SecretSyncs.DESTINATION_CONFIG.OCTOPUS_DEPLOY.scopeValues) + }) + ]) +); + +const OctopusDeploySyncOptionsConfig: TSyncOptionsConfig = { canImportSecrets: false }; + +export const OctopusDeploySyncSchema = BaseSecretSyncSchema(SecretSync.OctopusDeploy, OctopusDeploySyncOptionsConfig) + .extend({ + destination: z.literal(SecretSync.OctopusDeploy), + destinationConfig: OctopusDeploySyncDestinationConfigSchema + }) + .describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OctopusDeploy] })); + +export const CreateOctopusDeploySyncSchema = GenericCreateSecretSyncFieldsSchema( + SecretSync.OctopusDeploy, + OctopusDeploySyncOptionsConfig +).extend({ + destinationConfig: OctopusDeploySyncDestinationConfigSchema +}); + +export const UpdateOctopusDeploySyncSchema = GenericUpdateSecretSyncFieldsSchema( + SecretSync.OctopusDeploy, + OctopusDeploySyncOptionsConfig +).extend({ + destinationConfig: OctopusDeploySyncDestinationConfigSchema.optional() +}); + +export const OctopusDeploySyncListItemSchema = z + .object({ + name: z.literal("Octopus Deploy"), + connection: z.literal(AppConnection.OctopusDeploy), + destination: z.literal(SecretSync.OctopusDeploy), + canImportSecrets: z.literal(false) + }) + .describe(JSON.stringify({ title: SECRET_SYNC_NAME_MAP[SecretSync.OctopusDeploy] })); diff --git a/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-types.ts b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-types.ts new file mode 100644 index 0000000000..8cce9dae0c --- /dev/null +++ b/backend/src/services/secret-sync/octopus-deploy/octopus-deploy-sync-types.ts @@ -0,0 +1,67 @@ +import z from "zod"; + +import { TOctopusDeployConnection } from "@app/services/app-connection/octopus-deploy"; + +import { + CreateOctopusDeploySyncSchema, + OctopusDeploySyncListItemSchema, + OctopusDeploySyncSchema +} from "./octopus-deploy-sync-schemas"; + +export type TOctopusDeploySyncListItem = z.infer; +export type TOctopusDeploySync = z.infer; +export type TOctopusDeploySyncInput = z.infer; + +export type TOctopusDeploySyncWithCredentials = Omit & { + connection: TOctopusDeployConnection; +}; + +export type TOctopusDeployVariable = { + Id?: string; + Name: string; + Value: string; + Description: string; + Scope: { + Environment?: string[]; + Machine?: string[]; + Role?: string[]; + Action?: string[]; + Channel?: string[]; + ProcessOwner?: string[]; + Tenant?: string[]; + TenantTag?: string[]; + }; + IsEditable: boolean; + Prompt: { + Description: string; + DisplaySettings: Record; + Label: string; + Required: boolean; + } | null; + Type: "String" | "Sensitive"; + IsSensitive: boolean; +}; + +export type TOctopusDeployVariableSet = { + Id: string; + OwnerId: string; + Version: number; + Variables: TOctopusDeployVariable[]; + ScopeValues: { + Environments: { Id: string; Name: string }[]; + Machines: { Id: string; Name: string }[]; + Actions: { Id: string; Name: string }[]; + Roles: { Id: string; Name: string }[]; + Channels: { Id: string; Name: string }[]; + TenantTags: { Id: string; Name: string }[]; + Processes: { + ProcessType: string; + Id: string; + Name: string; + }[]; + }; + SpaceId: string; + Links: { + Self: string; + }; +}; diff --git a/backend/src/services/secret-sync/secret-sync-enums.ts b/backend/src/services/secret-sync/secret-sync-enums.ts index 835a314ca1..fc26f58e78 100644 --- a/backend/src/services/secret-sync/secret-sync-enums.ts +++ b/backend/src/services/secret-sync/secret-sync-enums.ts @@ -31,7 +31,8 @@ export enum SecretSync { Northflank = "northflank", Bitbucket = "bitbucket", LaravelForge = "laravel-forge", - Chef = "chef" + Chef = "chef", + OctopusDeploy = "octopus-deploy" } export enum SecretSyncInitialSyncBehavior { diff --git a/backend/src/services/secret-sync/secret-sync-fns.ts b/backend/src/services/secret-sync/secret-sync-fns.ts index 6ee9b91d3e..fb4e03c70c 100644 --- a/backend/src/services/secret-sync/secret-sync-fns.ts +++ b/backend/src/services/secret-sync/secret-sync-fns.ts @@ -53,6 +53,7 @@ import { HumanitecSyncFns } from "./humanitec/humanitec-sync-fns"; import { LARAVEL_FORGE_SYNC_LIST_OPTION, LaravelForgeSyncFns } from "./laravel-forge"; import { NETLIFY_SYNC_LIST_OPTION, NetlifySyncFns } from "./netlify"; import { NORTHFLANK_SYNC_LIST_OPTION, NorthflankSyncFns } from "./northflank"; +import { OCTOPUS_DEPLOY_SYNC_LIST_OPTION, OctopusDeploySyncFns } from "./octopus-deploy"; import { RAILWAY_SYNC_LIST_OPTION } from "./railway/railway-sync-constants"; import { RailwaySyncFns } from "./railway/railway-sync-fns"; import { RENDER_SYNC_LIST_OPTION, RenderSyncFns } from "./render"; @@ -97,7 +98,8 @@ const SECRET_SYNC_LIST_OPTIONS: Record = { [SecretSync.Northflank]: NORTHFLANK_SYNC_LIST_OPTION, [SecretSync.Bitbucket]: BITBUCKET_SYNC_LIST_OPTION, [SecretSync.LaravelForge]: LARAVEL_FORGE_SYNC_LIST_OPTION, - [SecretSync.Chef]: CHEF_SYNC_LIST_OPTION + [SecretSync.Chef]: CHEF_SYNC_LIST_OPTION, + [SecretSync.OctopusDeploy]: OCTOPUS_DEPLOY_SYNC_LIST_OPTION }; export const listSecretSyncOptions = () => { @@ -289,6 +291,8 @@ export const SecretSyncFns = { return LaravelForgeSyncFns.syncSecrets(secretSync, schemaSecretMap); case SecretSync.Chef: return ChefSyncFns.syncSecrets(secretSync, schemaSecretMap); + case SecretSync.OctopusDeploy: + return OctopusDeploySyncFns.syncSecrets(secretSync, schemaSecretMap); default: throw new Error( `Unhandled sync destination for sync secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` @@ -414,6 +418,9 @@ export const SecretSyncFns = { case SecretSync.Chef: secretMap = await ChefSyncFns.getSecrets(secretSync); break; + case SecretSync.OctopusDeploy: + secretMap = await OctopusDeploySyncFns.getSecrets(secretSync); + break; default: throw new Error( `Unhandled sync destination for get secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` @@ -513,6 +520,8 @@ export const SecretSyncFns = { return LaravelForgeSyncFns.removeSecrets(secretSync, schemaSecretMap); case SecretSync.Chef: return ChefSyncFns.removeSecrets(secretSync, schemaSecretMap); + case SecretSync.OctopusDeploy: + return OctopusDeploySyncFns.removeSecrets(secretSync, schemaSecretMap); default: throw new Error( `Unhandled sync destination for remove secrets fns: ${(secretSync as TSecretSyncWithCredentials).destination}` diff --git a/backend/src/services/secret-sync/secret-sync-maps.ts b/backend/src/services/secret-sync/secret-sync-maps.ts index 8829d46224..4511ce4bde 100644 --- a/backend/src/services/secret-sync/secret-sync-maps.ts +++ b/backend/src/services/secret-sync/secret-sync-maps.ts @@ -35,7 +35,8 @@ export const SECRET_SYNC_NAME_MAP: Record = { [SecretSync.Northflank]: "Northflank", [SecretSync.Bitbucket]: "Bitbucket", [SecretSync.LaravelForge]: "Laravel Forge", - [SecretSync.Chef]: "Chef" + [SecretSync.Chef]: "Chef", + [SecretSync.OctopusDeploy]: "Octopus Deploy" }; export const SECRET_SYNC_CONNECTION_MAP: Record = { @@ -71,7 +72,8 @@ export const SECRET_SYNC_CONNECTION_MAP: Record = { [SecretSync.Northflank]: AppConnection.Northflank, [SecretSync.Bitbucket]: AppConnection.Bitbucket, [SecretSync.LaravelForge]: AppConnection.LaravelForge, - [SecretSync.Chef]: AppConnection.Chef + [SecretSync.Chef]: AppConnection.Chef, + [SecretSync.OctopusDeploy]: AppConnection.OctopusDeploy }; export const SECRET_SYNC_PLAN_MAP: Record = { @@ -107,7 +109,8 @@ export const SECRET_SYNC_PLAN_MAP: Record = { [SecretSync.Northflank]: SecretSyncPlanType.Regular, [SecretSync.Bitbucket]: SecretSyncPlanType.Regular, [SecretSync.LaravelForge]: SecretSyncPlanType.Regular, - [SecretSync.Chef]: SecretSyncPlanType.Enterprise + [SecretSync.Chef]: SecretSyncPlanType.Enterprise, + [SecretSync.OctopusDeploy]: SecretSyncPlanType.Regular }; export const SECRET_SYNC_SKIP_FIELDS_MAP: Record = { @@ -152,7 +155,8 @@ export const SECRET_SYNC_SKIP_FIELDS_MAP: Record = { [SecretSync.Northflank]: [], [SecretSync.Bitbucket]: [], [SecretSync.LaravelForge]: [], - [SecretSync.Chef]: [] + [SecretSync.Chef]: [], + [SecretSync.OctopusDeploy]: [] }; const defaultDuplicateCheck: DestinationDuplicateCheckFn = () => true; @@ -214,5 +218,6 @@ export const DESTINATION_DUPLICATE_CHECK_MAP: Record { .leftJoin(TableName.Users, `${TableName.Users}.id`, `${TableName.SecretVersionV2}.userActorId`) .leftJoin(TableName.Identity, `${TableName.Identity}.id`, `${TableName.SecretVersionV2}.identityActorId`) .leftJoin(TableName.UserGroupMembership, `${TableName.UserGroupMembership}.userId`, `${TableName.Users}.id`) + .leftJoin( + TableName.IdentityGroupMembership, + `${TableName.IdentityGroupMembership}.identityId`, + `${TableName.Identity}.id` + ) .leftJoin(TableName.Membership, (qb) => { void qb .on(`${TableName.Membership}.scope`, db.raw("?", [AccessScope.Project])) @@ -208,7 +213,8 @@ export const secretVersionV2BridgeDALFactory = (db: TDbClient) => { void sqb .on(`${TableName.Membership}.actorUserId`, `${TableName.SecretVersionV2}.userActorId`) .orOn(`${TableName.Membership}.actorIdentityId`, `${TableName.SecretVersionV2}.identityActorId`) - .orOn(`${TableName.Membership}.actorGroupId`, `${TableName.UserGroupMembership}.groupId`); + .orOn(`${TableName.Membership}.actorGroupId`, `${TableName.UserGroupMembership}.groupId`) + .orOn(`${TableName.Membership}.actorGroupId`, `${TableName.IdentityGroupMembership}.groupId`); }); }) .leftJoin(TableName.SecretV2, `${TableName.SecretVersionV2}.secretId`, `${TableName.SecretV2}.id`) diff --git a/backend/src/services/smtp/emails/PkiExpirationAlertTemplate.tsx b/backend/src/services/smtp/emails/PkiExpirationAlertTemplate.tsx index f7a89f4e14..66df944393 100644 --- a/backend/src/services/smtp/emails/PkiExpirationAlertTemplate.tsx +++ b/backend/src/services/smtp/emails/PkiExpirationAlertTemplate.tsx @@ -61,9 +61,7 @@ export const PkiExpirationAlertTemplate = ({

- - View Certificate Alerts - + View Certificate Alerts
); diff --git a/backend/src/services/telemetry/telemetry-types.ts b/backend/src/services/telemetry/telemetry-types.ts index d2e977605b..560520f25f 100644 --- a/backend/src/services/telemetry/telemetry-types.ts +++ b/backend/src/services/telemetry/telemetry-types.ts @@ -1,4 +1,6 @@ import { + AcmeAccountActor, + AcmeProfileActor, IdentityActor, KmipClientActor, PlatformActor, @@ -60,6 +62,8 @@ export type TSecretModifiedEvent = { | ScimClientActor | PlatformActor | UnknownUserActor + | AcmeAccountActor + | AcmeProfileActor | KmipClientActor; }; }; diff --git a/docker-compose.bdd.yml b/docker-compose.bdd.yml index b736838677..ae3f8ef6bd 100644 --- a/docker-compose.bdd.yml +++ b/docker-compose.bdd.yml @@ -94,6 +94,13 @@ services: volumes: - ./backend/bdd/pebble/:/var/data/pebble:ro + technitium: + image: technitium/dns-server:14.2.0 + ports: + - "5380:5380/tcp" + environment: + - DNS_SERVER_ADMIN_PASSWORD=infisical + volumes: postgres-data: driver: local diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 5c3661cb7a..623ed5dc22 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -9,7 +9,7 @@ services: condition: service_healthy redis: condition: service_started - image: infisical/infisical:latest-postgres + image: infisical/infisical:latest # PIN THIS TO A SPECIFIC TAG pull_policy: always env_file: .env ports: diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/available.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/available.mdx new file mode 100644 index 0000000000..d4c84bd678 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/available.mdx @@ -0,0 +1,4 @@ +--- +title: "Available" +openapi: "GET /api/v1/app-connections/octopus-deploy/available" +--- diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/create.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/create.mdx new file mode 100644 index 0000000000..b60adbcc7e --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/create.mdx @@ -0,0 +1,10 @@ +--- +title: "Create" +openapi: "POST /api/v1/app-connections/octopus-deploy" +--- + + + Check out the configuration docs for [Octopus Deploy + Connections](/integrations/app-connections/octopus-deploy) to learn how to + obtain the required credentials. + diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/delete.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/delete.mdx new file mode 100644 index 0000000000..b8bf5e2266 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/delete.mdx @@ -0,0 +1,4 @@ +--- +title: "Delete" +openapi: "DELETE /api/v1/app-connections/octopus-deploy/{connectionId}" +--- diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-id.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-id.mdx new file mode 100644 index 0000000000..3cf7984ba0 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v1/app-connections/octopus-deploy/{connectionId}" +--- diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-name.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-name.mdx new file mode 100644 index 0000000000..c0cef40040 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/get-by-name.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by Name" +openapi: "GET /api/v1/app-connections/octopus-deploy/connection-name/{connectionName}" +--- diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/list.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/list.mdx new file mode 100644 index 0000000000..a91a22abdf --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v1/app-connections/octopus-deploy" +--- diff --git a/docs/api-reference/endpoints/app-connections/octopus-deploy/update.mdx b/docs/api-reference/endpoints/app-connections/octopus-deploy/update.mdx new file mode 100644 index 0000000000..d1e6a81bc1 --- /dev/null +++ b/docs/api-reference/endpoints/app-connections/octopus-deploy/update.mdx @@ -0,0 +1,10 @@ +--- +title: "Update" +openapi: "PATCH /api/v1/app-connections/octopus-deploy/{connectionId}" +--- + + + Check out the configuration docs for [Octopus Deploy + Connections](/integrations/app-connections/octopus-deploy) to learn how to + obtain the required credentials. + diff --git a/docs/api-reference/endpoints/certificates/certificate-request.mdx b/docs/api-reference/endpoints/certificates/certificate-request.mdx new file mode 100644 index 0000000000..fcf601f5ed --- /dev/null +++ b/docs/api-reference/endpoints/certificates/certificate-request.mdx @@ -0,0 +1,4 @@ +--- +title: "Get Certificate Request" +openapi: "GET /api/v1/cert-manager/certificates/certificate-requests/{requestId}" +--- diff --git a/docs/api-reference/endpoints/certificates/create-certificate.mdx b/docs/api-reference/endpoints/certificates/create-certificate.mdx new file mode 100644 index 0000000000..54b70c4641 --- /dev/null +++ b/docs/api-reference/endpoints/certificates/create-certificate.mdx @@ -0,0 +1,4 @@ +--- +title: "Issue Certificate" +openapi: "POST /api/v1/cert-manager/certificates" +--- diff --git a/docs/api-reference/endpoints/groups/add-group-machine-identity.mdx b/docs/api-reference/endpoints/groups/add-group-machine-identity.mdx new file mode 100644 index 0000000000..a997cddc7b --- /dev/null +++ b/docs/api-reference/endpoints/groups/add-group-machine-identity.mdx @@ -0,0 +1,4 @@ +--- +title: "Add Machine Identity to Group" +openapi: "POST /api/v1/groups/{id}/machine-identities/{machineIdentityId}" +--- diff --git a/docs/api-reference/endpoints/groups/list-group-machine-identities.mdx b/docs/api-reference/endpoints/groups/list-group-machine-identities.mdx new file mode 100644 index 0000000000..ebe0417132 --- /dev/null +++ b/docs/api-reference/endpoints/groups/list-group-machine-identities.mdx @@ -0,0 +1,4 @@ +--- +title: "List Group Machine Identities" +openapi: "GET /api/v1/groups/{id}/machine-identities" +--- diff --git a/docs/api-reference/endpoints/groups/list-group-members.mdx b/docs/api-reference/endpoints/groups/list-group-members.mdx new file mode 100644 index 0000000000..cf9f39a6ea --- /dev/null +++ b/docs/api-reference/endpoints/groups/list-group-members.mdx @@ -0,0 +1,5 @@ +--- +title: "List Group Members" +openapi: "GET /api/v1/groups/{id}/members" +--- + diff --git a/docs/api-reference/endpoints/groups/list-group-projects.mdx b/docs/api-reference/endpoints/groups/list-group-projects.mdx new file mode 100644 index 0000000000..6dc36a6cfd --- /dev/null +++ b/docs/api-reference/endpoints/groups/list-group-projects.mdx @@ -0,0 +1,5 @@ +--- +title: "List Group Projects" +openapi: "GET /api/v1/groups/{id}/projects" +--- + diff --git a/docs/api-reference/endpoints/groups/remove-group-identity.mdx b/docs/api-reference/endpoints/groups/remove-group-identity.mdx new file mode 100644 index 0000000000..b2ec485579 --- /dev/null +++ b/docs/api-reference/endpoints/groups/remove-group-identity.mdx @@ -0,0 +1,4 @@ +--- +title: "Remove Machine Identity from Group" +openapi: "DELETE /api/v1/groups/{id}/machine-identities/{machineIdentityId}" +--- diff --git a/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/list.mdx b/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/list.mdx new file mode 100644 index 0000000000..bd82dd0da0 --- /dev/null +++ b/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v1/scim/group-org-role-mappings" +--- diff --git a/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/update.mdx b/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/update.mdx new file mode 100644 index 0000000000..21884cb50a --- /dev/null +++ b/docs/api-reference/endpoints/organizations/scim/group-org-role-mappings/update.mdx @@ -0,0 +1,4 @@ +--- +title: "Update" +openapi: "PUT /api/v1/scim/group-org-role-mappings" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/create.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/create.mdx new file mode 100644 index 0000000000..3a5863bb24 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/create.mdx @@ -0,0 +1,4 @@ +--- +title: "Create" +openapi: "POST /api/v1/secret-syncs/octopus-deploy" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/delete.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/delete.mdx new file mode 100644 index 0000000000..40e81eb39a --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/delete.mdx @@ -0,0 +1,4 @@ +--- +title: "Delete" +openapi: "DELETE /api/v1/secret-syncs/octopus-deploy/{syncId}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-id.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-id.mdx new file mode 100644 index 0000000000..15427870ab --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-id.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by ID" +openapi: "GET /api/v1/secret-syncs/octopus-deploy/{syncId}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-name.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-name.mdx new file mode 100644 index 0000000000..6e444a2744 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/get-by-name.mdx @@ -0,0 +1,4 @@ +--- +title: "Get by Name" +openapi: "GET /api/v1/secret-syncs/octopus-deploy/sync-name/{syncName}" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/list.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/list.mdx new file mode 100644 index 0000000000..c04944ea33 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/list.mdx @@ -0,0 +1,4 @@ +--- +title: "List" +openapi: "GET /api/v1/secret-syncs/octopus-deploy" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/remove-secrets.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/remove-secrets.mdx new file mode 100644 index 0000000000..dbcce54f03 --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/remove-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Remove Secrets" +openapi: "POST /api/v1/secret-syncs/octopus-deploy/{syncId}/remove-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/sync-secrets.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/sync-secrets.mdx new file mode 100644 index 0000000000..bcd5bc0cce --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/sync-secrets.mdx @@ -0,0 +1,4 @@ +--- +title: "Sync Secrets" +openapi: "POST /api/v1/secret-syncs/octopus-deploy/{syncId}/sync-secrets" +--- diff --git a/docs/api-reference/endpoints/secret-syncs/octopus-deploy/update.mdx b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/update.mdx new file mode 100644 index 0000000000..78dea1340b --- /dev/null +++ b/docs/api-reference/endpoints/secret-syncs/octopus-deploy/update.mdx @@ -0,0 +1,4 @@ +--- +title: "Update" +openapi: "PATCH /api/v1/secret-syncs/octopus-deploy/{syncId}" +--- diff --git a/docs/contributing/platform/developing.mdx b/docs/contributing/platform/developing.mdx index 5a1af52c4a..bb84d8846b 100644 --- a/docs/contributing/platform/developing.mdx +++ b/docs/contributing/platform/developing.mdx @@ -15,7 +15,7 @@ git checkout -b MY_BRANCH_NAME ## Set up environment variables -Start by creating a `.env` file at the root of the Infisical directory then copy the contents of the file linked [here](https://github.com/Infisical/infisical/blob/main/.env.example). View all available [environment variables](https://infisical.com/docs/self-hosting/configuration/envars) and guidance for each. +Start by creating a `.env` file at the root of the Infisical directory then copy the contents of the file linked [here](https://github.com/Infisical/infisical/blob/main/.env.dev.example). View all available [environment variables](https://infisical.com/docs/self-hosting/configuration/envars) and guidance for each. ## Starting Infisical for development diff --git a/docs/docs.json b/docs/docs.json index 1f587355b9..8e564bad5f 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -33,7 +33,10 @@ }, { "group": "Guides", - "pages": ["documentation/guides/organization-structure"] + "pages": [ + "documentation/guides/governance-models", + "documentation/guides/organization-structure" + ] } ] }, @@ -135,6 +138,7 @@ "integrations/app-connections/netlify", "integrations/app-connections/northflank", "integrations/app-connections/oci", + "integrations/app-connections/octopus-deploy", "integrations/app-connections/okta", "integrations/app-connections/oracledb", "integrations/app-connections/postgres", @@ -563,6 +567,7 @@ "integrations/secret-syncs/netlify", "integrations/secret-syncs/northflank", "integrations/secret-syncs/oci-vault", + "integrations/secret-syncs/octopus-deploy", "integrations/secret-syncs/railway", "integrations/secret-syncs/render", "integrations/secret-syncs/supabase", @@ -662,7 +667,16 @@ "group": "Concepts", "pages": [ "documentation/platform/pki/concepts/certificate-mgmt", - "documentation/platform/pki/concepts/certificate-lifecycle" + "documentation/platform/pki/concepts/certificate-lifecycle", + "documentation/platform/pki/concepts/certificate-components" + ] + }, + { + "group": "Guides", + "pages": [ + "documentation/platform/pki/guides/request-cert-agent", + "documentation/platform/pki/guides/request-cert-api", + "documentation/platform/pki/guides/request-cert-acme" ] } ] @@ -702,6 +716,7 @@ { "group": "Infrastructure Integrations", "pages": [ + "integrations/platforms/certificate-agent", "documentation/platform/pki/k8s-cert-manager", "documentation/platform/pki/integration-guides/gloo-mesh", "documentation/platform/pki/integration-guides/windows-server-acme", @@ -884,7 +899,12 @@ "api-reference/endpoints/groups/get-by-id", "api-reference/endpoints/groups/add-group-user", "api-reference/endpoints/groups/remove-group-user", - "api-reference/endpoints/groups/list-group-users" + "api-reference/endpoints/groups/list-group-users", + "api-reference/endpoints/groups/add-group-machine-identity", + "api-reference/endpoints/groups/remove-group-machine-identity", + "api-reference/endpoints/groups/list-group-machine-identities", + "api-reference/endpoints/groups/list-group-projects", + "api-reference/endpoints/groups/list-group-members" ] }, { @@ -921,6 +941,18 @@ "api-reference/endpoints/organizations/saml-sso/update-saml-config", "api-reference/endpoints/organizations/saml-sso/create-saml-config" ] + }, + { + "group": "SCIM", + "pages": [ + { + "group": " Group to Org Role Mappings", + "pages": [ + "api-reference/endpoints/organizations/scim/group-org-role-mappings/list", + "api-reference/endpoints/organizations/scim/group-org-role-mappings/update" + ] + } + ] } ] }, @@ -1463,6 +1495,18 @@ "api-reference/endpoints/app-connections/oci/delete" ] }, + { + "group": "Octopus Deploy", + "pages": [ + "api-reference/endpoints/app-connections/octopus-deploy/list", + "api-reference/endpoints/app-connections/octopus-deploy/available", + "api-reference/endpoints/app-connections/octopus-deploy/get-by-id", + "api-reference/endpoints/app-connections/octopus-deploy/get-by-name", + "api-reference/endpoints/app-connections/octopus-deploy/create", + "api-reference/endpoints/app-connections/octopus-deploy/update", + "api-reference/endpoints/app-connections/octopus-deploy/delete" + ] + }, { "group": "Okta", "pages": [ @@ -1475,6 +1519,7 @@ "api-reference/endpoints/app-connections/okta/delete" ] }, + { "group": "OracleDB", "pages": [ @@ -2374,6 +2419,19 @@ "api-reference/endpoints/secret-syncs/oci-vault/remove-secrets" ] }, + { + "group": "Octopus Deploy", + "pages": [ + "api-reference/endpoints/secret-syncs/octopus-deploy/list", + "api-reference/endpoints/secret-syncs/octopus-deploy/get-by-id", + "api-reference/endpoints/secret-syncs/octopus-deploy/get-by-name", + "api-reference/endpoints/secret-syncs/octopus-deploy/create", + "api-reference/endpoints/secret-syncs/octopus-deploy/update", + "api-reference/endpoints/secret-syncs/octopus-deploy/delete", + "api-reference/endpoints/secret-syncs/octopus-deploy/sync-secrets", + "api-reference/endpoints/secret-syncs/octopus-deploy/remove-secrets" + ] + }, { "group": "Railway", "pages": [ @@ -2489,7 +2547,7 @@ ] }, { - "group": "Infisical PKI", + "group": "Certificate Management", "pages": [ { "group": "Certificate Authorities", @@ -2528,6 +2586,8 @@ "pages": [ "api-reference/endpoints/certificates/list", "api-reference/endpoints/certificates/read", + "api-reference/endpoints/certificates/certificate-request", + "api-reference/endpoints/certificates/create-certificate", "api-reference/endpoints/certificates/renew", "api-reference/endpoints/certificates/update-config", "api-reference/endpoints/certificates/revoke", @@ -3077,6 +3137,186 @@ { "source": "/documentation/platform/pki/est", "destination": "/documentation/platform/pki/enrollment-methods/est" + }, + { + "source": "/api-reference/endpoints/integrations/create-auth", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/create", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/delete-auth-by-id", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/delete-auth", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/delete", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/find-auth", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/list-auth", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/list-project-integrations", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/endpoints/integrations/update", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/api-reference/overview/examples/integration", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/documentation/platform/integrations", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cicd/circleci", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cicd/codefresh", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cicd/octopus-deploy", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cicd/rundeck", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cicd/travisci", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/aws-parameter-store", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/aws-secret-manager", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/azure-app-configuration", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/azure-devops", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/azure-key-vault", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/checkly", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/cloud-66", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/cloudflare-pages", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/cloudflare-workers", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/databricks", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/digital-ocean-app-platform", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/flyio", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/gcp-secret-manager", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/hashicorp-vault", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/hasura-cloud", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/heroku", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/laravel-forge", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/netlify", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/northflank", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/qovery", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/railway", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/render", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/supabase", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/terraform-cloud", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/vercel", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/windmill", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/overview", + "destination": "/integrations/secret-syncs" + }, + { + "source": "/integrations/cloud/aws-amplify", + "destination": "/integrations/cicd/aws-amplify" + }, + { + "source": "/integrations/cloud/teamcity", + "destination": "/integrations/secret-syncs/teamcity" } ] } diff --git a/docs/documentation/guides/governance-models.mdx b/docs/documentation/guides/governance-models.mdx new file mode 100644 index 0000000000..da0da973c7 --- /dev/null +++ b/docs/documentation/guides/governance-models.mdx @@ -0,0 +1,479 @@ +--- +title: "Centralized vs. Self-Service Governance" +sidebarTitle: "Governance Models" +description: "Learn how to structure Infisical for centralized platform administration or team self-service autonomy" +--- + +Organizations adopt different approaches to secrets management governance based on their security requirements, compliance obligations, and team structures. Infisical supports a spectrum of governance models—from fully centralized platform administration to team-driven self-service. + +This guide covers how to configure Infisical for different governance approaches and what tradeoffs to consider. + +## Understanding the Spectrum + +Most organizations don't operate at the extremes. Instead, they land somewhere on a spectrum between two models: + +**Centralized Administration**: A dedicated platform or security team controls project creation, access policies, integrations, and secret lifecycle management. Application teams consume secrets but don't manage the underlying infrastructure. + +**Self-Service**: Teams have autonomy to create projects, manage their own access, configure integrations, and operate independently. Central teams provide guardrails and standards rather than direct management. + + +The right model depends on your regulatory environment, team maturity, organizational scale, and security posture. Highly regulated industries often lean toward centralized control, while organizations with mature DevOps practices may benefit from self-service with guardrails. + + +## Organizational Structure + +Project and environment structure is where governance decisions start to take shape. + +### Project Ownership + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Project creation** | Platform team creates all projects on behalf of application teams | Teams create their own projects as needed | +| **Naming conventions** | Enforced through process and templates | Documented standards, team-enforced | +| **Folder structure** | Predefined conventions (e.g., `/apps/{app-name}/{component}`) | Teams define hierarchies that fit their needs | + +### Project Templates + +[Project Templates](/documentation/platform/project-templates) allow you to define standard environments, roles, and settings that are applied when creating new projects. This feature supports both governance models: + +- **Centralized**: Require all projects to use approved templates, ensuring consistent environment structures and role definitions across the organization +- **Self-Service**: Provide templates as a starting point that teams can build upon, reducing setup time while allowing customization + + +Project Templates apply at creation time and don't propagate changes to existing projects. Plan your template strategy before widespread adoption. + + +### Environment Strategy + +Environments define the deployment stages where secrets are managed. + +- **Standardized environments** (e.g., `dev`, `staging`, `prod`) provide consistency and simplify cross-team collaboration +- **Custom environments** allow teams to model their specific deployment pipelines (e.g., `qa`, `uat`, `perf-test`, `prod-eu`, `prod-us`) + +With Project Templates, you can enforce a base set of environments while optionally allowing teams to add additional ones. + +## Authentication and Identity + +How you manage identity—both for users and machines—significantly affects your governance strategy. + +### User Authentication + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Login methods** | SSO enforced, local accounts disabled | SSO available, local accounts permitted | +| **MFA** | Required organization-wide | Encouraged or optional | +| **Session duration** | Short sessions enforced | Longer sessions permitted | + +Infisical supports multiple authentication methods that can be configured based on your requirements: + +- [SAML SSO](/documentation/platform/sso/overview) with providers like Okta, Azure AD, Google Workspace, and JumpCloud +- [OIDC SSO](/documentation/platform/sso/general-oidc) for standards-based authentication +- [LDAP](/documentation/platform/ldap/overview) for directory-based authentication + +### User Provisioning + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **User onboarding** | Automatic via SCIM from identity provider | Direct invitations by project admins | +| **Role assignment** | Mapped from IdP groups | Assigned manually per project | +| **Offboarding** | Automatic deprovisioning via SCIM | Manual removal required | + +[SCIM provisioning](/documentation/platform/scim/overview) enables automatic user lifecycle management synced with your identity provider. Combined with [group mappings](/documentation/platform/scim/group-mappings), you can automatically assign organization roles based on IdP group membership. + +For organizations using SAML, [group membership mapping](/documentation/platform/sso/google-saml#saml-group-membership-mapping) synchronizes group memberships when users log in, ensuring access reflects current IdP state. + +### Machine Identity Management + +[Machine identities](/documentation/platform/identities/machine-identities) authenticate applications, services, and automated systems with Infisical. Your governance model shapes how these identities are managed: + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Identity creation** | Platform team creates all identities; teams submit requests | Teams create identities for their own projects | +| **Auth method selection** | Standardized methods enforced (e.g., "Kubernetes Auth only in production") | Teams choose methods appropriate to their infrastructure | +| **Credential management** | Platform team manages and distributes credentials | Teams manage their own identity credentials | + +Infisical supports multiple machine identity authentication methods: + +- [Universal Auth](/documentation/platform/identities/universal-auth) — Client ID/secret authentication for any environment +- [Kubernetes Auth](/documentation/platform/identities/kubernetes-auth) — Native authentication using Kubernetes service accounts +- [AWS Auth](/documentation/platform/identities/aws-auth) — Authentication using AWS IAM roles +- [Azure Auth](/documentation/platform/identities/azure-auth) — Authentication using Azure managed identities +- [GCP Auth](/documentation/platform/identities/gcp-auth) — Authentication using GCP service accounts +- [OIDC Auth](/documentation/platform/identities/oidc-auth) — Authentication using OIDC identity tokens + +Centralized organizations often standardize on platform-native authentication methods (Kubernetes Auth, cloud provider auth) to eliminate static credentials, while self-service models may permit Universal Auth for flexibility. + +## Access Control + +Infisical's [role-based access control](/documentation/platform/access-controls/role-based-access-controls) operates at two levels: organization and project. How you configure these controls determines who can do what across your secrets infrastructure. + +### Organization-Level Roles + +[Organization roles](/documentation/platform/access-controls/role-based-access-controls#organization-level-access-controls) govern access to organization-wide resources like billing, member management, and identity provider configuration. + +| Role | Capabilities | +|------|--------------| +| **Admin** | Full access to all organization settings and all projects | +| **Member** | Basic organization access; project access determined separately | +| **Custom roles** | Tailored permissions for specific administrative functions | + + +The Admin role grants access to all projects in the organization. In both governance models, this role should be assigned sparingly to prevent unintended access to sensitive secrets. + + +### Project-Level Roles + +[Project roles](/documentation/platform/access-controls/role-based-access-controls#project-level-access-controls) control what users and machine identities can do within a specific project. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Role definition** | Custom roles defined by platform team; teams assigned predefined roles | Teams create project-level custom roles as needed | +| **Production access** | Restricted to specific roles; requires approval | Teams determine their own access patterns | +| **Role assignment** | Managed through groups synced from IdP | Project admins assign roles directly | + +Built-in project roles include: +- **Admin**: Full access to all environments, folders, secrets, and project settings +- **Developer**: Standard access with restrictions on project administration and policy management +- **Viewer**: Read-only access to secrets and project resources + +[Custom roles](/documentation/platform/access-controls/role-based-access-controls#creating-custom-roles) let you define granular permissions for specific environments, folder paths, and actions—useful for implementing least-privilege access. + +### Groups + +[Groups](/documentation/platform/groups) simplify access management by allowing you to assign roles to collections of users rather than individuals. + +Key behaviors: +- Adding a group to a project grants all group members access with the assigned role(s) +- Users inherit composite permissions from all groups they belong to +- Group membership can be managed locally or synced from your identity provider via SCIM + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Group management** | Groups defined in IdP, synced via SCIM | Project admins create and manage local groups | +| **Project membership** | Controlled through IdP group assignments | Direct group/user additions by project admins | + +### Temporary and Just-in-Time Access + +For sensitive environments, both governance models benefit from time-limited access: + +- [Temporary access](/documentation/platform/access-controls/temporary-access) grants permissions that automatically expire after a defined period +- [Additional privileges](/documentation/platform/access-controls/additional-privileges) allow temporary elevation beyond a user's base role + +Centralized organizations typically require temporary access for production environments, while self-service models may use it selectively for high-risk operations. + +## Approval Workflows + +[Approval workflows](/documentation/platform/pr-workflows) add oversight to sensitive operations, supporting compliance requirements and change management practices. + +### Change Policies + +Change policies require approval before secrets can be modified in specific environments or folder paths. When a policy applies, proposed changes enter a review queue where designated approvers can approve and merge—or reject—the changes. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Policy scope** | Required for all production environments | Teams define policies for their sensitive environments | +| **Approvers** | Security team members or designated reviewers | Team leads or senior engineers | +| **Bypass permissions** | Strictly limited | May allow emergency bypass for on-call | + +### Access Requests + +[Access requests](/documentation/platform/access-controls/access-requests) formalize the process of granting access to sensitive resources. Combined with temporary access, this enables just-in-time access patterns where users request and receive time-limited permissions. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Request requirement** | Mandatory for production access | Optional or environment-specific | +| **Approval workflow** | Formal review by security team | Peer approval or team lead sign-off | +| **Access duration** | Strictly time-limited | Flexible based on need | + +### Notifications + +Approval workflows integrate with [Slack](/documentation/platform/workflow-integrations/slack-integration) and [Microsoft Teams](/documentation/platform/workflow-integrations/microsoft-teams-integration) to notify approvers in real-time, reducing delays in the approval process. + +## Secret Lifecycle + +Who creates, rotates, and retires secrets—and how—depends on your governance model. + +### App Connections + +[App Connections](/integrations/app-connections/overview) are reusable integrations with third-party platforms like AWS, GCP, Azure, databases, and other services. They're required for secret rotation, dynamic secrets, and secret syncs—so how you manage them affects multiple workflows. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Connection creation** | Platform team creates connections at the organization level and distributes access to projects | Teams create their own connections at the project level | +| **Credential management** | Platform team manages service accounts and API keys used by connections | Teams manage credentials for their own connections | +| **Access distribution** | Connections shared across multiple projects as needed | Each team maintains their own set of connections | + +### Secret Creation and Ownership + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Shared secrets** | Platform team provisions infrastructure secrets (databases, APIs) | Teams request or create their own | +| **Application secrets** | Teams manage within their designated paths | Teams have full ownership | +| **Secret standards** | Naming conventions and metadata requirements enforced | Guidelines provided, team-enforced | + +### Secret Rotation + +[Secret rotation](/documentation/platform/secret-rotation/overview) automates credential lifecycle management, reducing the risk of long-lived secrets. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Rotation policies** | Defined and managed by platform team | Teams configure for their services | +| **Rotation schedules** | Standardized intervals based on secret classification | Teams determine appropriate intervals | + +### Dynamic Secrets + +[Dynamic secrets](/documentation/platform/dynamic-secrets/overview) generate short-lived credentials on demand, eliminating standing access to sensitive systems. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Configuration** | Platform team sets up dynamic secret sources | Teams configure for their databases and services | +| **Lease duration** | Standardized TTLs based on use case | Teams determine appropriate durations | +| **Access control** | Restricted to specific roles | Available to authorized team members | + +### Secret Referencing Within Projects + +[Secret referencing](/documentation/platform/secret-references) and [imports](/documentation/platform/secret-references) allow secrets to be shared across environments and folders within the same project. This helps reduce duplication when the same secret is needed in multiple environments. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Reference patterns** | Standardized import structures across projects | Teams define their own reference hierarchies | +| **Base environment** | Platform team designates source environments for imports | Teams choose which environments to reference from | + + +Projects in Infisical are isolated from one another. Secret referencing and imports work within a single project—you cannot reference secrets across different projects. + + +## Integrations and Secret Delivery + +Infisical offers multiple methods for delivering secrets to applications and infrastructure. + +### Secret Syncs + +[Secret Syncs](/integrations/secret-syncs/overview) push secrets to third-party platforms like AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, and others. Syncs keep external secret stores updated when values change in Infisical. + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Sync setup** | Platform team configures syncs to approved destinations | Teams configure syncs for their projects | +| **Target platforms** | Limited to approved platforms | Teams choose appropriate destinations | +| **Sync scope** | Standardized patterns (e.g., sync prod to AWS SM only) | Teams determine what to sync and where | + +### Kubernetes Integration + +For Kubernetes environments, two primary integration patterns are available: + +- [Infisical Kubernetes Operator](/integrations/platforms/kubernetes/infisical-operator) — Syncs secrets to Kubernetes Secrets resources +- [Infisical Secrets Injector](/integrations/platforms/kubernetes-injector) — Injects secrets directly into pods at runtime + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Operator deployment** | Single cluster-wide instance managed by platform team | Teams may deploy namespace-scoped instances | +| **Secret sync patterns** | Standardized CRD configurations | Teams define their own InfisicalSecret resources | + +### Agent and CLI + +The [Infisical Agent](/infisical-agent/overview) and [CLI](/cli/overview) provide flexible secret consumption patterns: + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Agent deployment** | Managed by platform team as infrastructure | Teams deploy and configure their own agents | +| **CLI usage** | Standardized configurations provided | Teams use CLI as needed in their workflows | + +### Gateways + +[Gateways](/documentation/platform/gateways/overview) enable Infisical to securely access private resources—such as databases in isolated VPCs—without exposing them to the public internet. Gateways are lightweight components deployed within your private network that establish secure, outbound-only connections to Infisical. + +Gateways are essential for features that require direct access to private infrastructure: +- [Dynamic secrets](/documentation/platform/dynamic-secrets/overview) for databases in private networks +- [Secret rotation](/documentation/platform/secret-rotation/overview) for credentials stored in isolated systems +- [Kubernetes Auth](/documentation/platform/identities/kubernetes-auth) token review for private clusters + +#### Gateway Architecture + +Gateways operate at two levels within Infisical: + +1. **Organization-level registration**: Gateways are registered and visible in Organization Settings → Access Control → Gateways. This provides central visibility into all gateway infrastructure. + +2. **Project-level linking**: When configuring features like dynamic secrets, teams select from available gateways to route requests through private networks. + +This architecture naturally supports a hybrid governance model where infrastructure teams manage gateway deployment while application teams consume them. + +#### Governance Considerations + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Gateway deployment** | Platform/infrastructure team deploys gateways in shared network zones | Teams deploy gateways in their own VPCs or network segments | +| **Machine identity management** | Platform team creates and manages identities used by gateways | Teams create identities for gateways they deploy | +| **Network configuration** | Central team manages firewall rules and network connectivity | Teams responsible for their own network access | +| **Gateway selection** | Platform team links gateways to projects | Teams select from available gateways when configuring features | + + +Each gateway requires a [machine identity](/documentation/platform/identities/machine-identities) for authentication. Your gateway governance model should align with your broader machine identity strategy. + + +#### Common Patterns + +**Shared Gateway Model** (Centralized) + +A platform team deploys gateways in shared network zones that can reach common infrastructure (e.g., a central database cluster). Multiple projects link to these shared gateways, reducing deployment overhead and centralizing network management. + +This pattern works well when: +- Multiple applications share common database infrastructure +- Network access is controlled by a central team +- You want to minimize the number of gateway deployments to manage + +**Team-Owned Gateway Model** (Self-Service) + +Each team deploys gateways within their own network boundaries (e.g., per-team VPCs or Kubernetes namespaces). Teams manage the full lifecycle of their gateways, including the machine identities that authenticate them. + +This pattern works well when: +- Teams have isolated network environments +- Teams have infrastructure expertise to deploy and maintain gateways +- Strict network segmentation requires dedicated gateways per team + +**Hybrid Model** + +Platform team deploys and registers gateways, but application teams independently select which gateway to use when configuring dynamic secrets or rotation. This provides central oversight of infrastructure while giving teams flexibility in how they use it. + +For Kubernetes environments, gateways can also serve as token reviewers for [Kubernetes Auth](/documentation/platform/identities/kubernetes-auth), eliminating the need for long-lived service account tokens. In this scenario, the gateway deployment often aligns with whoever manages the Kubernetes cluster. + +## Audit and Compliance + +Visibility into secrets access and changes is critical for security and compliance. Infisical provides audit capabilities at both organization and project levels. + +### Audit Logs + +[Audit logs](/documentation/platform/audit-logs) capture all platform activity including secret access, modifications, and administrative actions. + +| Level | Scope | Typical Access | +|-------|-------|----------------| +| **Organization** | All activity across all projects | Security team, compliance officers | +| **Project** | Activity within a specific project | Project admins, team leads | + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Log access** | Security team has organization-wide visibility | Teams access only their project logs | +| **Log retention** | Centrally managed retention policies | Platform-defined retention | +| **Compliance reporting** | Platform team generates reports | Teams may generate their own project reports | + +### Audit Log Streaming + +[Audit log streaming](/documentation/platform/audit-log-streams/audit-log-streams) exports logs to external systems for long-term retention and analysis. + +Supported destinations include: +- SIEM platforms (Splunk, Datadog, Elastic) +- Cloud storage (AWS S3, Azure Blob Storage) +- Log aggregators (Better Stack, generic HTTP endpoints) + +| Approach | Centralized | Self-Service | +|----------|-------------|--------------| +| **Stream configuration** | Platform team manages all log streams | N/A (organization-level feature) | +| **SIEM integration** | Centralized security monitoring | Teams may not have direct SIEM access | + +## Security Controls + +Beyond access control, Infisical offers additional security settings. + +### Security Policies + +Organization-level [security policies](/documentation/platform/organization) allow you to enforce: +- MFA requirements for all users +- Session duration limits +- Login restrictions + +### IP Access Controls + +Restrict API and dashboard access to specific IP ranges, useful for: +- Limiting production access to corporate networks or VPNs +- Restricting machine identity authentication to known infrastructure IPs + +### Encryption and Key Management + +| Feature | Description | Governance Consideration | +|---------|-------------|-------------------------| +| **External KMS** | Integrate with AWS KMS, GCP KMS, or Azure Key Vault | Centralized key management | +| **BYOK** | Bring your own encryption keys | Enterprise key management policies | +| **KMIP** | Connect to KMIP-compatible HSMs | Hardware-backed security requirements | + +These features are typically managed centrally regardless of overall governance model, as encryption infrastructure requires specialized expertise. + +## Choosing Your Model + +A few factors tend to push organizations toward one end of the spectrum or the other: + +### Factors Favoring Centralized Control + +- **Regulatory requirements**: SOC 2, HIPAA, PCI-DSS, and similar frameworks often require demonstrated control over secrets management +- **Limited security expertise**: When application teams lack security experience, central management reduces risk +- **Consistency requirements**: Large organizations benefit from standardized patterns across teams +- **High-risk environments**: Financial services, healthcare, and government contexts often require strict oversight + +### Factors Favoring Self-Service + +- **Mature DevOps culture**: Teams with strong security awareness can manage their own secrets responsibly +- **Speed of delivery**: Self-service reduces bottlenecks and accelerates development cycles +- **Diverse technology stacks**: Teams using different platforms benefit from flexibility in integration choices +- **Distributed organizations**: Global teams may need autonomy to operate across time zones + +### The Hybrid Approach + +Most organizations benefit from a hybrid model that combines central guardrails with team autonomy: + +**Platform team responsibilities:** +- SSO and SCIM configuration +- Project template creation and maintenance +- Organization-wide security policies +- Audit log streaming and compliance reporting +- Approval workflow policies for production environments +- Shared infrastructure secrets (databases, external APIs) + +**Application team responsibilities:** +- Project creation (from approved templates) +- Application-specific secret management +- Integration configuration within their projects +- Team-level access control within policy bounds +- Secret rotation for team-owned credentials + +This balances compliance requirements with team velocity—central teams handle the infrastructure and guardrails, while application teams own their day-to-day secrets operations. + +## Implementation Considerations + +### Starting Centralized, Moving to Self-Service + +Organizations often begin with centralized control and gradually extend autonomy as teams demonstrate security maturity: + +1. **Phase 1**: Platform team manages all aspects; teams consume secrets via provided integrations +2. **Phase 2**: Teams gain ability to manage secrets within their projects; platform team controls project creation and policies +3. **Phase 3**: Teams can create projects from templates and configure integrations; platform team focuses on guardrails and compliance + +### Starting Self-Service, Adding Controls + +Organizations scaling from startup to enterprise may need to add centralization: + +1. **Phase 1**: Establish SSO and basic security policies +2. **Phase 2**: Introduce project templates and approval workflows for production +3. **Phase 3**: Implement SCIM provisioning and comprehensive audit streaming + +### Documentation and Training + +Regardless of model, invest in: +- Clear documentation of secrets management standards and processes +- Training for teams on Infisical features and security best practices +- Runbooks for common operations (secret rotation, access requests, incident response) + +## Summary + +Here's a quick reference for how key Infisical features map to each governance model: + +| Feature | Centralized Use | Self-Service Use | +|---------|-----------------|------------------| +| [Project Templates](/documentation/platform/project-templates) | Enforce standards | Provide starting points | +| [SCIM](/documentation/platform/scim/overview) | Automate user lifecycle | Supplement direct invitations | +| [Groups](/documentation/platform/groups) | IdP-synced membership | Local team management | +| [Custom Roles](/documentation/platform/access-controls/role-based-access-controls) | Define organization-wide | Create project-specific | +| [Approval Workflows](/documentation/platform/pr-workflows) | Require for all changes | Apply selectively | +| [App Connections](/integrations/app-connections/overview) | Org-level connections distributed to projects | Teams create project-level connections | +| [Secret Syncs](/integrations/secret-syncs/overview) | Platform-managed syncs to approved destinations | Teams configure their own syncs | +| [Gateways](/documentation/platform/gateways/overview) | Shared infrastructure for private access | Team-deployed per network zone | +| [Audit Logs](/documentation/platform/audit-logs) | Centralized monitoring | Project-level visibility | + +Most organizations land somewhere in between—central control over identity, policies, and infrastructure with team ownership of secrets and integrations. You can start at either end of the spectrum and adjust as your needs change. diff --git a/docs/documentation/platform/groups.mdx b/docs/documentation/platform/groups.mdx index df4f114366..f7a49ef31c 100644 --- a/docs/documentation/platform/groups.mdx +++ b/docs/documentation/platform/groups.mdx @@ -1,29 +1,29 @@ --- -title: "User Groups" -description: "Manage user groups in Infisical." +title: "Groups" +description: "Manage groups containing users and machine identities in Infisical." --- - User Groups is a paid feature. - - If you're using Infisical Cloud, then it is available under the **Enterprise Tier**. If you're self-hosting Infisical, - then you should contact team@infisical.com to purchase an enterprise license to use it. + Groups is a paid feature. If you're using Infisical Cloud, then it is + available under the **Enterprise Tier**. If you're self-hosting Infisical, + then you should contact team@infisical.com to purchase an enterprise license + to use it. ## Concept -A (user) group is a collection of users that you can create in an Infisical organization to more efficiently manage permissions and access control for multiple users together. For example, you can have a group called `Developers` with the `Developer` role containing all the developers in your organization. +A group is a collection of identities (users and/or machine identities) that you can create in an Infisical organization to more efficiently manage permissions and access control for multiple identities together. For example, you can have a group called `Developers` with the `Developer` role containing all the developers in your organization, or a group called `CI/CD Identities` containing all the machine identities used in your CI/CD pipelines. -User groups have the following properties: +Groups have the following properties: -- If a group is added to a project under specific role(s), all users in the group will be provisioned access to the project with the role(s). Conversely, if a group is removed from a project, all users in the group will lose access to the project. -- If a user is added to a group, they will inherit the access control properties of the group including access to project(s) under the role(s) assigned to the group. Conversely, if a user is removed from a group, they will lose access to project(s) that the group has access to. -- If a user was previously added to a project under a role and is later added to a group that has access to the same project under a different role, then the user will now have access to the project under the composite permissions of the two roles. If the group is subsequently removed from the project, the user will not lose access to the project as they were previously added to the project separately. -- A user can be part of multiple groups. If a user is part of multiple groups, they will inherit the composite permissions of all the groups that they are part of. +- If a group is added to a project under specific role(s), all identities in the group will be provisioned access to the project with the role(s). Conversely, if a group is removed from a project, all identities in the group will lose access to the project. +- If an identity is added to a group, they will inherit the access control properties of the group including access to project(s) under the role(s) assigned to the group. Conversely, if an identity is removed from a group, they will lose access to project(s) that the group has access to. +- If an identity was previously added to a project under a role and is later added to a group that has access to the same project under a different role, then the identity will now have access to the project under the composite permissions of the two roles. If the group is subsequently removed from the project, the identity will not lose access to the project as they were previously added to the project separately. +- An identity can be part of multiple groups. If an identity is part of multiple groups, they will inherit the composite permissions of all the groups that they are part of. ## Workflow -In the following steps, we explore how to create and use user groups to provision user access to projects in Infisical. +In the following steps, we explore how to create and use groups to provision access to projects in Infisical. Groups can contain both users and machine identities, and the workflow is the same for both types of identities. @@ -32,36 +32,38 @@ In the following steps, we explore how to create and use user groups to provisio ![groups org](/images/platform/groups/groups-org.png) When creating a group, you specify an organization level [role](/documentation/platform/access-controls/role-based-access-controls) for it to assume; you can configure roles in Organization Settings > Access Control > Organization Roles. - + ![groups org create](/images/platform/groups/groups-org-create.png) - + Now input a few details for your new group. Here’s some guidance for each field: - Name (required): A friendly name for the group like `Engineering`. - Slug (required): A unique identifier for the group like `engineering`. - Role (required): A role from the Organization Roles tab for the group to assume. The organization role assigned will determine what organization level resources this group can have access to. + - - Next, you'll want to assign users to the group. To do this, press on the users icon on the group and start assigning users to the group. + + Next, you'll want to assign identities (users and/or machine identities) to the group. To do this, click on the group row to open the group details page and click on the **+** button. - ![groups org users](/images/platform/groups/groups-org-users.png) + ![groups org users details](/images/platform/groups/group-details.png) - In this example, we're assigning **Alan Turing** and **Ada Lovelace** to the group **Engineering**. + In this example, we're assigning **Alan Turing** and **Ada Lovelace** (users) to the group **Engineering**. You can similarly add machine identities to the group by selecting them from the **Machine Identities** tab in the modal. ![groups org assign users](/images/platform/groups/groups-org-users-assign.png) To enable the group to access project-level resources such as secrets within a specific project, you should add it to that project. - To do this, head over to the project you want to add the group to and go to Project Settings > Access Control > Groups and press **Add group**. - + To do this, head over to the project you want to add the group to and go to Project Settings > Access Control > Groups and press **Add Group to Project**. + ![groups project](/images/platform/groups/groups-project.png) - + Next, select the group you want to add to the project and the project level role you want to allow it to assume. The project role assigned will determine what project level resources this group can have access to. - + ![groups project add](/images/platform/groups/groups-project-create.png) - + That's it! - - The users of the group now have access to the project under the role you assigned to the group. + + All identities of the group now have access to the project under the role you assigned to the group. + - \ No newline at end of file + diff --git a/docs/documentation/platform/pki/certificates.mdx b/docs/documentation/platform/pki/certificates.mdx deleted file mode 100644 index da73de37df..0000000000 --- a/docs/documentation/platform/pki/certificates.mdx +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "Certificates" -sidebarTitle: "Certificates" -description: "Learn how to issue X.509 certificates with Infisical." ---- - -## Concept - -Assuming that you've created a Private CA hierarchy with a root CA and an intermediate CA, you can now issue/revoke X.509 certificates using the intermediate CA. - -
- -```mermaid -graph TD - A[Root CA] - A --> B[Intermediate CA] - A --> C[Intermediate CA] - B --> D[Leaf Certificate] - C --> E[Leaf Certificate] -``` - -
- -## Workflow - -The typical workflow for managing certificates consists of the following steps: - -1. Issuing a certificate under an intermediate CA with details like name and validity period. As part of certificate issuance, you can either issue a certificate directly from a CA or do it via a certificate template. -2. Managing certificate lifecycle events such as certificate renewal and revocation. As part of the certificate revocation flow, - you can also query for a Certificate Revocation List [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list), a time-stamped, signed - data structure issued by a CA containing a list of revoked certificates to check if a certificate has been revoked. - - - Note that this workflow can be executed via the Infisical UI or manually such - as via API. - - -## Guide to Issuing Certificates - -In the following steps, we explore how to issue a X.509 certificate under a CA. - - - - - - - A certificate template is a set of policies for certificates issued under that template; each template is bound to a specific CA and can also be bound to a certificate collection for alerting such that any certificate issued under the template is automatically added to the collection. - - With certificate templates, you can specify, for example, that issued certificates must have a common name (CN) adhering to a specific format like `.*.acme.com` or perhaps that the max TTL cannot be more than 1 year. - - Head to your Project > Certificate Authorities > Your Issuing CA and create a certificate template. - - ![pki certificate template modal](/images/platform/pki/certificate/cert-template-modal.png) - - Here's some guidance on each field: - - - Template Name: A name for the certificate template. - - Issuing CA: The Certificate Authority (CA) that will issue certificates based on this template. - - Certificate Collection (Optional): The certificate collection that certificates should be added to when issued under the template. - - Common Name (CN): A regular expression used to validate the common name in certificate requests. - - Alternative Names (SANs): A regular expression used to validate subject alternative names in certificate requests. - - TTL: The maximum Time-to-Live (TTL) for certificates issued using this template. - - Key Usage: The key usage constraint or default value for certificates issued using this template. - - Extended Key Usage: The extended key usage constraint or default value for certificates issued using this template. - - - To create a certificate, head to your Project > Internal PKI > Certificates and press **Issue** under the Certificates section. - - ![pki issue certificate](/images/platform/pki/certificate/cert-issue.png) - - Here, set the **Certificate Template** to the template from step 1 and fill out the rest of the details for the certificate to be issued. - - ![pki issue certificate modal](/images/platform/pki/certificate/cert-issue-modal.png) - - Here's some guidance on each field: - - - Friendly Name: A friendly name for the certificate; this is only for display and defaults to the common name of the certificate if left empty. - - Common Name (CN): The common name for the certificate like `service.acme.com`. - - Alternative Names (SANs): A comma-delimited list of Subject Alternative Names (SANs) for the certificate; these can be hostnames or email addresses like `app1.acme.com, app2.acme.com`. - - TTL: The lifetime of the certificate in seconds. - - Key Usage: The key usage extension of the certificate. - - Extended Key Usage: The extended key usage extension of the certificate. - - - Note that Infisical PKI supports issuing certificates without certificate templates as well. If this is desired, then you can set the **Certificate Template** field to **None** - and specify the **Issuing CA** and optional **Certificate Collection** fields; the rest of the fields for the issued certificate remain the same. - - That said, we recommend using certificate templates to enforce policies and attach expiration monitoring on issued certificates. - - - - - Once you have created the certificate from step 1, you'll be presented with the certificate details including the **Certificate Body**, **Certificate Chain**, and **Private Key**. - - ![pki certificate body](/images/platform/pki/certificate/cert-body.png) - - - Make sure to download and store the **Private Key** in a secure location as it will only be displayed once at the time of certificate issuance. - The **Certificate Body** and **Certificate Chain** will remain accessible and can be copied at any time. - - - - - - - - - A certificate template is a set of policies for certificates issued under that template; each template is bound to a specific CA and can also be bound to a certificate collection for alerting such that any certificate issued under the template is automatically added to the collection. - - With certificate templates, you can specify, for example, that issued certificates must have a common name (CN) adhering to a specific format like .*.acme.com or perhaps that the max TTL cannot be more than 1 year. - - To create a certificate template, make an API request to the [Create Certificate Template](/api-reference/endpoints/certificate-templates-v2/create) API endpoint, specifying the issuing CA. - - ### Sample request - - ```bash Request - curl --request POST \ - --url https://us.infisical.com/api/v2/certificate-templates \ - --header 'Content-Type: application/json' \ - --data '{ - "projectId": "", - "name": "", - "description": "", - "subject": [ - { - "type": "common_name", - "allowed": [ - "*.infisical.com" - ] - } - ], - "sans": [ - { - "type": "dns_name", - "allowed": [ - "*.sample.com" - ] - } - ], - "keyUsages": { - "allowed": [ - "digital_signature" - ] - }, - "extendedKeyUsages": { - "allowed": [ - "client_auth" - ] - }, - "algorithms": { - "signature": [ - "SHA256-RSA" - ], - "keyAlgorithm": [ - "RSA-2048" - ] - }, - "validity": { - "max": "365d" - } - }' - ``` - - ### Sample response - - ```bash Response - { - "certificateTemplate": { - "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", - "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", - "name": "", - "description": "", - "subject": [ - { - "type": "common_name", - "allowed": [ - "*.infisical.com" - ] - } - ], - "sans": [ - { - "type": "dns_name", - "allowed": [ - "*.sample.com" - ] - } - ], - "keyUsages": { - "allowed": [ - "digital_signature" - ] - }, - "extendedKeyUsages": { - "allowed": [ - "client_auth" - ] - }, - "algorithms": { - "signature": [ - "SHA256-RSA" - ], - "keyAlgorithm": [ - "RSA-2048" - ] - }, - "validity": { - "max": "365d" - }, - "createdAt": "2023-11-07T05:31:56Z", - "updatedAt": "2023-11-07T05:31:56Z" - } - } - ``` - - - - To create a certificate under the certificate template, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/issue-certificate) API endpoint, - specifying the issuing CA. - - ### Sample request - - ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/issue-certificate' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "profileId": "", - "commonName": "service.acme.com", - "ttl": "1y", - "signatureAlgorithm": "RSA-SHA256", - "keyAlgorithm": "RSA_2048" - }' - ``` - - ### Sample response - - ```bash Response - { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." - } - ``` - - - Note that Infisical PKI supports issuing certificates without certificate templates as well. If this is desired, then you can set the **Certificate Template** field to **None** - and specify the **Issuing CA** and optional **Certificate Collection** fields; the rest of the fields for the issued certificate remain the same. - - That said, we recommend using certificate templates to enforce policies and attach expiration monitoring on issued certificates. - - - - Make sure to store the `privateKey` as it is only returned once here at the time of certificate issuance. The `certificate` and `certificateChain` will remain accessible and can be retrieved at any time. - - - If you have an external private key, you can also create a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the [Sign Certificate](/api-reference/endpoints/certificates/sign-certificate) API endpoint, specifying the issuing CA. - - ### Sample request - - ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/sign-certificate' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "certificateTemplateId": "", - "csr": "...", - "ttl": "1y", - }' - ``` - - ### Sample response - - ```bash Response - { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." - } - ``` - - - - - - -## Guide to Revoking Certificates - -In the following steps, we explore how to revoke a X.509 certificate under a CA and obtain a Certificate Revocation List (CRL) for a CA. - - - - - - Assuming that you've issued a certificate under a CA, you can revoke it by - selecting the **Revoke Certificate** option for it and specifying the reason - for revocation. - - ![pki revoke certificate](/images/platform/pki/certificate/cert-revoke.png) - - ![pki revoke certificate modal](/images/platform/pki/certificate/cert-revoke-modal.png) - - - - In order to check the revocation status of a certificate, you can check it - against the CRL of a CA by heading to its Issuing CA and downloading the CRL. - - ![pki view crl](/images/platform/pki/ca/ca-crl.png) - - To verify a certificate against the - downloaded CRL with OpenSSL, you can use the following command: - -```bash -openssl verify -crl_check -CAfile chain.pem -CRLfile crl.pem cert.pem -``` - -Note that you can also obtain the CRL from the certificate itself by -referencing the CRL distribution point extension on the certificate. - -To check a certificate against the CRL distribution point specified within it with OpenSSL, you can use the following command: - -```bash -openssl verify -verbose -crl_check -crl_download -CAfile chain.pem cert.pem -``` - - - - - - - - Assuming that you've issued a certificate under a CA, you can revoke it by making an API request to the [Revoke Certificate](/api-reference/endpoints/certificates/revoke) API endpoint, - specifying the serial number of the certificate and the reason for revocation. - - ### Sample request - - ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates//revoke' \ - --header 'Authorization: Bearer ' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "revocationReason": "UNSPECIFIED" - }' - ``` - - ### Sample response - - ```bash Response - { - message: "Successfully revoked certificate", - serialNumber: "...", - revokedAt: "..." - } - ``` - - - In order to check the revocation status of a certificate, you can check it against the CRL of the issuing CA. - To obtain the CRLs of the CA, make an API request to the [List CRLs](/api-reference/endpoints/certificate-authorities/crl) API endpoint. - - ### Sample request - - ```bash Request - curl --location --request GET 'https://app.infisical.com/api/v1/cert-manager/ca/internal//crls' \ - --header 'Authorization: Bearer ' - ``` - - ### Sample response - - ```bash Response - [ - { - id: "...", - crl: "..." - }, - ... - ] - ``` - - To verify a certificate against the CRL with OpenSSL, you can use the following command: - - ```bash - openssl verify -crl_check -CAfile chain.pem -CRLfile crl.pem cert.pem - ``` - - - - - - -## FAQ - - - - To renew a certificate, you have to issue a new certificate from the same CA - with the same common name as the old certificate. The original certificate - will continue to be valid through its original TTL unless explicitly - revoked. - - diff --git a/docs/documentation/platform/pki/certificates/certificates.mdx b/docs/documentation/platform/pki/certificates/certificates.mdx index eab06fe435..1f2a5b7f2b 100644 --- a/docs/documentation/platform/pki/certificates/certificates.mdx +++ b/docs/documentation/platform/pki/certificates/certificates.mdx @@ -29,13 +29,13 @@ Refer to the documentation for each [enrollment method](/documentation/platform/ ## Guide to Renewing Certificates To [renew a certificate](/documentation/platform/pki/concepts/certificate-lifecycle#renewal), you can either request a new certificate from a certificate profile or have the platform -automatically request a new one for you. Whether you pursue a client-driven or server-driven approach is totally dependent on the enrollment method configured on your certificate +automatically request a new one for you to be delivered downstream to a target destination. Whether you pursue a client-driven or server-driven approach is totally dependent on the enrollment method configured on your certificate profile as well as your infrastructure use-case. ### Client-Driven Certificate Renewal Client-driven certificate renewal is when renewal is initiated client-side by the end-entity consuming the certificate. -This is the most common approach to certificate renewal and is suitable for most use-cases. +More specifically, the client (e.g. [Infisical Agent](/integrations/platforms/certificate-agent), [ACME client](https://letsencrypt.org/docs/client-options/), etc.) monitors the certificate and makes a request for Infisical to issue a new certificate back to it when the existing certificate is nearing expiration. This is the most common approach to certificate renewal and is suitable for most use-cases. ### Server-Driven Certificate Renewal diff --git a/docs/documentation/platform/pki/concepts/certificate-components.mdx b/docs/documentation/platform/pki/concepts/certificate-components.mdx new file mode 100644 index 0000000000..cfda3813c1 --- /dev/null +++ b/docs/documentation/platform/pki/concepts/certificate-components.mdx @@ -0,0 +1,30 @@ +--- +title: "Certificate Components" +description: "Learn the main components for managing certificates with Infisical." +--- + +## Core Components + +The following resources define how certificates are issued, shaped, and governed in Infisical: + +- [Certificate Authority (CA)](/documentation/platform/pki/ca/overview): The trusted entity that issues X.509 certificates. This can be an [Internal CA](/documentation/platform/pki/ca/private-ca) or an [External CA](/documentation/platform/pki/ca/external-ca) in Infisical. + The former represents a fully managed CA hierarchy within Infisical, while the latter represents an external CA (e.g. [DigiCert](/documentation/platform/pki/ca/digicert), [Let's Encrypt](/documentation/platform/pki/ca/lets-encrypt), [Microsoft AD CS](/documentation/platform/pki/ca/azure-adcs), etc.) that can be integrated with Infisical. + +- [Certificate Template](/documentation/platform/pki/certificates/templates): A policy structure specifying permitted attributes for requested certificates. This includes constraints around subject naming conventions, SAN fields, key usages, and extended key usages. + +- [Certificate Profile](/documentation/platform/pki/certificates/profiles): A configuration set specifying how leaf certificates should be issued for a group of end-entities including the issuing CA, a certificate template, and the enrollment method (e.g. [ACME](/documentation/platform/pki/enrollment-methods/acme), [EST](/documentation/platform/pki/enrollment-methods/est), [API](/documentation/platform/pki/enrollment-methods/api), etc.) used to enroll certificates. + +- [Certificate](/documentation/platform/pki/certificates/certificates): The actual X.509 certificate issued for a profile. Once created, it is tracked in Infisical’s certificate inventory for management, renewal, and lifecycle operations. + +## Access Control + +Access control defines who (or what) can manage certificate resources and who can issue certificates within a project. Without clear boundaries, [certificate authorities](/documentation/platform/pki/ca/overview) and issuance workflows can be misconfigured or misused. + +To manage access to certificates, you assign role-based permissions at the project level. These permissions determine which certificate authorities, certificate templates, certificate profiles, and other related resources a user or machine identity can act on. For example, +you may want to: + +- Have specific teams(s) manage your internal CA hierarchy or external CA integration configuration and have separate team(s) configure certificate profiles for requested certificates. +- Limit which teams can manage policies defined on certificate templates. +- Have specific end-entities (e.g. servers, devices, users) request certificates from specific certificate profiles. + +This model follows the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege) so that each user or machine identity can manage or issue only the certificate resources it is responsible for and nothing more. diff --git a/docs/documentation/platform/pki/concepts/certificate-mgmt.mdx b/docs/documentation/platform/pki/concepts/certificate-mgmt.mdx index efdb8a072c..05c70a7805 100644 --- a/docs/documentation/platform/pki/concepts/certificate-mgmt.mdx +++ b/docs/documentation/platform/pki/concepts/certificate-mgmt.mdx @@ -9,7 +9,7 @@ A (digital) _certificate_ is a file that is tied to a cryptographic key pair and For example, when you visit a website over HTTPS, your browser checks the TLS certificate deployed on the web server or load balancer to make sure it’s really the site it claims to be. If the certificate is valid, your browser establishes an encrypted connection with the server. -Certificates contain information about the subject (who it identifies), the public key, and a digital signature from the CA that issued the certificate. They also include additional fields such as key usages, validity periods, and extensions that define how and where the certificate can be used. When a certificate expires, the service presenting it is no longer trusted, and clients won't be able to establish a secure connection to the service. +Certificates contain information about the subject (who it identifies), the public key, and a digital signature from the Certificate Authority (CA) that issued the certificate. They also include additional fields such as key usages, validity periods, and extensions that define how and where the certificate can be used. When a certificate expires, the service presenting it is no longer trusted, and clients won't be able to establish a secure connection to the service. ## What is Certificate Management? diff --git a/docs/documentation/platform/pki/enrollment-methods/acme.mdx b/docs/documentation/platform/pki/enrollment-methods/acme.mdx index 3c12a5040d..8567e48a74 100644 --- a/docs/documentation/platform/pki/enrollment-methods/acme.mdx +++ b/docs/documentation/platform/pki/enrollment-methods/acme.mdx @@ -6,7 +6,9 @@ sidebarTitle: "ACME" ## Concept The ACME enrollment method allows Infisical to act as an ACME server. It lets you request and manage certificates against a specific [certificate profile](/documentation/platform/pki/certificates/profiles) using the [ACME protocol](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment). -This method is suitable for web servers, load balancers, and other general-purpose servers that can run an [ACME client](https://letsencrypt.org/docs/client-options/) for automated certificate management. + +This method is suitable for web servers, load balancers, and other general-purpose servers that can run an [ACME client](https://letsencrypt.org/docs/client-options/) for automated certificate management; +it can also be used with [cert-manager](https://cert-manager.io/) to issue and renew certificates for Kubernetes workloads through the [ACME issuer type](https://cert-manager.io/docs/configuration/acme/). Infisical's ACME enrollment method is based on [RFC 8555](https://datatracker.ietf.org/doc/html/rfc8555/). @@ -26,6 +28,17 @@ In the following steps, we explore how to issue a X.509 certificate using the AC ![pki acme config](/images/platform/pki/enrollment-methods/acme/acme-config.png) + + + By default, when the ACME client requests a certificate against the certificate profile for a particular domain, Infisical will verify domain ownership using the [HTTP-01 challenge](https://letsencrypt.org/docs/challenge-types/#http-01-challenge) method prior to issuing a certificate back to the client. + + If you want Infisical to skip domain ownership validation entirely, you can enable the **Skip DNS Ownership Validation** checkbox. + + Note that skipping domain ownership validation for the ACME enrollment method is **not the same** as skipping validation for an [External ACME CA integration](/documentation/platform/pki/ca/acme-ca). + + When using the ACME enrollment, the domain ownership check occurring between the ACME client and Infisical can be skipped. In contrast, External ACME CA integrations always require domain ownership validation, as Infisical must complete a DNS-01 challenge with the upstream ACME-compatible CA. + + Once you've created the certificate profile, you can obtain its ACME configuration details by clicking the **Reveal ACME EAB** option on the profile. diff --git a/docs/documentation/platform/pki/enrollment-methods/api.mdx b/docs/documentation/platform/pki/enrollment-methods/api.mdx index bfbac7f2e1..c7dff2a271 100644 --- a/docs/documentation/platform/pki/enrollment-methods/api.mdx +++ b/docs/documentation/platform/pki/enrollment-methods/api.mdx @@ -100,32 +100,34 @@ Here, select the certificate profile from step 1 that will be used to issue the - To issue a certificate against the certificate profile, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/issue-certificate) API endpoint. + To issue a certificate against the certificate profile, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/issue-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ "profileId": "", - "commonName": "service.acme.com", - "ttl": "1y", - "signatureAlgorithm": "RSA-SHA256", - "keyAlgorithm": "RSA_2048", - "keyUsages": ["digital_signature", "key_encipherment"], - "extendedKeyUsages": ["server_auth"], - "altNames": [ - { - "type": "DNS", - "value": "service.acme.com" - }, - { - "type": "DNS", - "value": "www.service.acme.com" - } - ] + "attributes": { + "commonName": "service.acme.com", + "ttl": "1y", + "signatureAlgorithm": "RSA-SHA256", + "keyAlgorithm": "RSA_2048", + "keyUsages": ["digital_signature", "key_encipherment"], + "extendedKeyUsages": ["server_auth"], + "altNames": [ + { + "type": "DNS", + "value": "service.acme.com" + }, + { + "type": "DNS", + "value": "www.service.acme.com" + } + ] + } }' ``` @@ -133,31 +135,36 @@ Here, select the certificate profile from step 1 that will be used to issue the ```bash Response { - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\n-----END PRIVATE KEY-----", - "serialNumber": "123456789012345678", - "certificateId": "880h3456-e29b-41d4-a716-446655440003" + "certificate": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\n-----END PRIVATE KEY-----", + "serialNumber": "123456789012345678", + "certificateId": "880h3456-e29b-41d4-a716-446655440003" + }, + "certificateRequestId": "..." } ``` - Make sure to store the `privateKey` as it is only returned once here at the time of certificate issuance. The `certificate` and `certificateChain` will remain accessible and can be retrieved at any time. + Note: If the certificate is available to be issued immediately, the `certificate` field in the response will contain the certificate data. If issuance is delayed (for example, due to pending approval or additional processing), the `certificate` field will be `null` and you can use the `certificateRequestId` to poll for status or retrieve the certificate when it is ready using the [Get Certificate Request](/api-reference/endpoints/certificates/certificate-request) API endpoint. - If you have an external private key, you can also issue a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the [Sign Certificate](/api-reference/endpoints/certificates/sign-certificate) API endpoint. + If you have an external private key, you can also issue a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the same [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/sign-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ "profileId": "", "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBE9oaW8...\n-----END CERTIFICATE REQUEST-----", - "ttl": "1y" + "attributes": { + "ttl": "1y" + } }' ``` @@ -165,11 +172,14 @@ Here, select the certificate profile from step 1 that will be used to issue the ```bash Response { - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "serialNumber": "123456789012345679", - "certificateId": "990i4567-e29b-41d4-a716-446655440004" + "certificate": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "serialNumber": "123456789012345679", + "certificateId": "990i4567-e29b-41d4-a716-446655440004" + }, + "certificateRequestId": "..." } ``` diff --git a/docs/documentation/platform/pki/guides/request-cert-acme.mdx b/docs/documentation/platform/pki/guides/request-cert-acme.mdx new file mode 100644 index 0000000000..f0b545ba23 --- /dev/null +++ b/docs/documentation/platform/pki/guides/request-cert-acme.mdx @@ -0,0 +1,108 @@ +--- +title: "Obtain a Certificate via ACME" +--- + +import RequestCertSetup from "/snippets/documentation/platform/pki/guides/request-cert-setup.mdx"; + +The [ACME enrollment method](/documentation/platform/pki/enrollment-methods/acme) lets any [ACME client](https://letsencrypt.org/docs/client-options/) obtain TLS certificates from Infisical using the [ACME protocol](https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment). +This includes ACME clients like [Certbot](https://certbot.eff.org/), [cert-manager](https://cert-manager.io/) in Kubernetes using the [ACME issuer type](https://cert-manager.io/docs/configuration/acme/), and more. + +Infisical currently supports the [HTTP-01 challenge type](https://letsencrypt.org/docs/challenge-types/#http-01-challenge) for domain validation as part of the ACME enrollment method. + +## Diagram + +The following sequence diagram illustrates the certificate enrollment workflow for requesting a certificate via ACME from Infisical. + +```mermaid +sequenceDiagram + autonumber + participant ACME as ACME Client + participant Infis as Infisical ACME Server + participant Authz as HTTP-01 Challenge
Validation Endpoint + participant CA as CA
(Internal or External) + + Note over ACME: ACME Client discovers
Infisical ACME Directory URL + + ACME->>Infis: GET /directory + Infis-->>ACME: Directory + nonce + endpoints + + ACME->>Infis: HEAD /new-nonce + Infis-->>ACME: Return nonce in Replay-Nonce header + + ACME->>Infis: POST /new-account
(contact, ToS agreed) + Infis-->>ACME: Return account object + + Note over ACME,Infis: Requesting a certificate + + ACME->>Infis: POST /new-order
(identifiers: DNS names) + Infis-->>ACME: Return order
with authorization URLs + + loop For each authorization (one per DNS name) + ACME->>Infis: POST /authorizations/:authzId + Infis-->>ACME: Return HTTP-01 challenge
(URL + token + keyAuth) + + Note over ACME: Client must prove control
over the domain via HTTP + + ACME->>Authz: Provision challenge response
at
/.well-known/acme-challenge/ + + ACME->>Infis: POST /authorizations/:authzId/challenges/:challengeId
(trigger validation) + + Infis->>Authz: HTTP GET /.well-known/acme-challenge/ + Authz-->>Infis: Return keyAuth + + Infis-->>ACME: Authorization = valid + end + + Note over Infis: All authorizations valid → ready to finalize + + ACME->>ACME: Generate keypair locally
and create CSR + ACME->>Infis: POST /orders/:orderId/finalize
(CSR) + + Infis->>CA: Request certificate issuance
(CSR) + CA-->>Infis: Signed certificate (+ chain) + + Infis-->>ACME: Return order with certificate URL
(status: valid) + + ACME->>Infis: POST /orders/:orderId/certificate + Infis-->>ACME: Return certificate
and certificate chain +``` + +## Guide + +In the following steps, we explore an end-to-end workflow for obtaining a certificate via ACME with Infisical. + + + + + Next, follow the guide [here](/documentation/platform/pki/certificates/profiles#guide-to-creating-a-certificate-profile) to create a [certificate profile](/documentation/platform/pki/certificates/profiles) + that will be referenced when requesting a certificate. + + The certificate profile specifies which certificate template and issuing CA should be used to validate an incoming certificate request and issue a certificate; + it also specifies the [enrollment method](/documentation/platform/pki/enrollment-methods/overview) for how certificates can be requested against this profile + to begin with. + + You should specify the certificate template from Step 2, the issuing CA from Step 1, and the **ACME** option in the **Enrollment Method** dropdown when creating the certificate profile. + + + + Finally, follow the guide [here](/documentation/platform/pki/enrollment-methods/acme#guide-to-certificate-enrollment-via-acme) to request a certificate against the certificate profile + using an [ACME client](https://letsencrypt.org/docs/client-options/). + + The ACME client will connect to Infisical's ACME server at the **ACME Directory URL** and authenticate using the **EAB Key Identifier (KID)** and **EAB Secret** credentials as part of the ACME protocol. + + The typical ACME workflow looks likes this: + + - The ACME client creates (or reuses) an ACME account with Infisical using EAB credentials. + - The ACME client creates an order for one or more DNS names. + - For each DNS name, the ACME client receives an `HTTP-01` challenge and provisions the corresponding token response at `/.well-known/acme-challenge/<token>`. + - Once all authorizations are valid, the ACME client finalizes the order by sending a CSR to Infisical. + - Infisical issues the certificate from the issuing CA on the certificate profile and returns it (plus the chain) back to the ACME client. + + ACME clients typically handle renewal by tracking certificate expiration and completing the lifecycle once again to request a new certificate. + + + We recommend reading more about the ACME protocol [here](https://letsencrypt.org/how-it-works/). + + + + diff --git a/docs/documentation/platform/pki/guides/request-cert-agent.mdx b/docs/documentation/platform/pki/guides/request-cert-agent.mdx new file mode 100644 index 0000000000..698ea25471 --- /dev/null +++ b/docs/documentation/platform/pki/guides/request-cert-agent.mdx @@ -0,0 +1,95 @@ +--- +title: "Request a Certificate via the Infisical Agent" +--- + +import RequestCertSetup from "/snippets/documentation/platform/pki/guides/request-cert-setup.mdx"; + +The [Infisical Agent](/integrations/platforms/certificate-agent) is an installable client daemon that can request TLS and other X.509 certificates from Infisical using the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) configured on a [certificate profile](/documentation/platform/pki/certificates/profiles), persist it to a specified path on the filesystem, and automatically monitor and renew it before expiration. + +Instead of [manually requesting](/documentation/platform/pki/guides/request-cert-api) and renewing a certificate via the [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint, you can install and launch the Infisical Agent to have it perform these steps for you automatically. + +## Diagram + +The following sequence diagram illustrates the certificate enrollment workflow for requesting a certificate using the Infisical Agent from Infisical. + +```mermaid +sequenceDiagram + autonumber + participant Agent as Infisical Agent + participant Infis as Infisical + participant CA as CA
(Internal or External) + + Agent->>Infis: Request certificate
(profileId, conditional subject/SANs, ttl,
key usages, conditional CSR, etc.) + + Infis->>Infis: Look up certificate profile
(by profileId) + Infis->>Infis: Validate request
against profile constraints
(CN/SAN rules, key usages, max TTL, etc.) + + alt Issuer Type = Self-Signed + Infis->>Infis: Generate keypair
and self-sign certificate + else Issuer Type = Internal CA + Infis->>CA: Request certificate issuance + CA-->>Infis: Signed certificate
(+ chain) + end + + Infis-->>Agent: Return certificate, certificate chain,
(and private key if server-generated) + + Note over Agent: Persist certificate and begin lifecycle monitoring + + loop Periodic certificate status check + Agent->>Agent: Check certificate expiration
against renew-before-expiry threshold + + alt Renewal not required + Agent-->>Agent: Continue monitoring + else Renewal required + Agent->>Infis: Request new certificate
(same profile and constraints) + + Infis->>Infis: Validate renewal request
against profile constraints + + alt Issuer Type = Self-Signed + Infis->>Infis: Generate keypair
and self-sign certificate + else Issuer Type = Internal CA + Infis->>CA: Request certificate issuance + CA-->>Infis: Signed certificate
(+ chain) + end + + Infis-->>Agent: Return renewed certificate, certificate chain, and private key + end + end +``` + +## Guide + +In the following steps, we explore an end-to-end workflow for requesting and continuously renewing a certificate using the Infisical Agent. + + + + + Next, follow the guide [here](/documentation/platform/pki/certificates/profiles#guide-to-creating-a-certificate-profile) to create a [certificate profile](/documentation/platform/pki/certificates/profiles) + that will be referenced when requesting a certificate. + + The certificate profile specifies which certificate template and issuing CA should be used to validate an incoming certificate request and issue a certificate; + it also specifies the [enrollment method](/documentation/platform/pki/enrollment-methods/overview) for how certificates can be requested against this profile + to begin with. + + You should specify the certificate template from Step 2, the issuing CA from Step 1, and the **API** option in the **Enrollment Method** dropdown when creating the certificate profile. + + + Note that if you're looking to issue self-signed certificates, you should select the **Self-Signed** option in the **Issuer Type** dropdown when creating the certificate profile. + + + + + Next, [install the Infisical CLI](/cli/overview) on the target machine you wish to request the certificate on and follow the documentation [here](/integrations/platforms/certificate-agent#operating-the-agent) to set up the Infisical Agent on it. + + As part of the setup, you must create an [agent configuration file](/integrations/platforms/certificate-agent#agent-configuration) that specifies how the agent should authenticate with Infisical using a [machine identity](/documentation/platform/identities/machine-identities), the certificate profile it should request against (from Step 3), what kind of certificate to request, where to persist the certificate, and how it should be managed in terms of auto-renewal. + + Finally, start the agent with that configuration file so it can start requesting and continuously renewing the certificate on your behalf using the command below: + + ```bash + infisical cert-manager agent --config /path/to/your/agent-config.yaml + ``` + + The certificate, certificate chain, and private key will be persisted to the filesystem at the paths specified in the `file-output` section of the agent configuration file. + + + diff --git a/docs/documentation/platform/pki/guides/request-cert-api.mdx b/docs/documentation/platform/pki/guides/request-cert-api.mdx new file mode 100644 index 0000000000..e44771d73d --- /dev/null +++ b/docs/documentation/platform/pki/guides/request-cert-api.mdx @@ -0,0 +1,79 @@ +--- +title: "Request a Certificate via API" +--- + +import RequestCertSetup from "/snippets/documentation/platform/pki/guides/request-cert-setup.mdx"; + +The [API enrollment method](/documentation/platform/pki/enrollment-methods/api) lets you programmatically request TLS and other X.509 certificates from Infisical. + +This is the most flexible way to request certificates from Infisical but requires you to implement certificate request and renewal logic on your own. +For a more automated way to request certificates, we highly recommend you check out the guide for requesting certificates using the [Infisical Agent](/integrations/platforms/certificate-agent) [here](/documentation/platform/pki/guides/request-cert-agent). + +## Diagram + +The following sequence diagram illustrates the certificate issuance workflow for requesting a certificate via API from Infisical. + +```mermaid +sequenceDiagram + autonumber + participant Client as Client + participant Infis as Infisical + participant CA as CA
(Internal or External) + + Client->>Infis: POST /certificate
(profileId, conditional subject/SANs, ttl,
key usages, conditional CSR, etc.) + + Infis->>Infis: Look up certificate profile
(by profileId) + Infis->>Infis: Validate request or CSR
against profile constraints
(CN/SAN rules, key usages, max TTL, etc.) + + alt Issuer Type = Self-Signed + Infis->>Infis: Generate keypair
and self-sign certificate + else Issuer Type = CA + Infis->>CA: Request certificate issuance
(CSR) + CA-->>Infis: Signed certificate
(+ chain) + end + + Infis-->>Client: Return certificate, certificate chain,
issuing CA certificate, serial number,
certificate ID
(and private key if server-generated)
OR certificate request ID if async +``` + +## Guide + +In the following steps, we explore an end-to-end workflow for requesting a certificate via API from Infisical. + + + + + Next, follow the guide [here](/documentation/platform/pki/certificates/profiles#guide-to-creating-a-certificate-profile) to create a [certificate profile](/documentation/platform/pki/certificates/profiles) + that will be referenced when requesting a certificate. + + The certificate profile specifies which certificate template and issuing CA should be used to validate an incoming certificate request and issue a certificate; + it also specifies the [enrollment method](/documentation/platform/pki/enrollment-methods/overview) for how certificates can be requested against this profile + to begin with. + + You should specify the certificate template from Step 2, the issuing CA from Step 1, and the **API** option in the **Enrollment Method** dropdown when creating the certificate profile. + + + Note that if you're looking to issue self-signed certificates, you should select the **Self-Signed** option in the **Issuer Type** dropdown when creating the certificate profile. + + + + + Finally, follow the guide [here](/documentation/platform/pki/enrollment-methods/api#guide-to-certificate-enrollment-via-api) to request a certificate against the certificate profile + over the Web UI or by making an API request the [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint with or without a certificate signing request (CSR). + + To renew a certificate on the client-side, you have two options: + + - Make a request to issue a new certificate against the same [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. + - Make a request to the [Renew Certificate](/api-reference/endpoints/certificates/renew) API endpoint with the ID of the certificate you wish to renew. Note that this endpoint only works if the original certificate was issued through the [Issue Certificate](/api-reference/endpoints/certificates/issue-certificate) API endpoint without a CSR. + + + We recommend reading the guide [here](/documentation/platform/pki/certificates/certificates#guide-to-renewing-certificates) to learn more about all the ways to renew a certificate + with Infisical including [server-driven certificate renewal](/documentation/platform/pki/certificates/certificates#server-driven-certificate-renewal). + + + + + +Note that depending on your environment and infrastructure use-case, you may wish to use a different [enrollment method](/documentation/platform/pki/enrollment-methods/overview) to request certificates. + +For more automated certificate management, you may wish to request certificates using a client that can monitor expiring certificates and request renewals for you. +For example, you can install the Infisical Agent on a VM and have it request and renew certificates for you or use an [ACME client](https://letsencrypt.org/docs/client-options/) paired with Infisical's [ACME enrollment method](/documentation/platform/pki/enrollment-methods/acme). diff --git a/docs/documentation/platform/pki/k8s-cert-manager.mdx b/docs/documentation/platform/pki/k8s-cert-manager.mdx index b0f696ba96..2479a72c9c 100644 --- a/docs/documentation/platform/pki/k8s-cert-manager.mdx +++ b/docs/documentation/platform/pki/k8s-cert-manager.mdx @@ -139,7 +139,7 @@ The following steps show how to install cert-manager (using `kubectl`) and obtai ``` - - Currently, the Infisical ACME server only supports the HTTP-01 challenge and requires successful challenge completion before issuing certificates. Support for optional challenges and DNS-01 is planned for a future release. + - Currently, the [ACME enrollment method](/documentation/platform/pki/enrollment-methods/acme) only supports the [HTTP-01 challenge](https://letsencrypt.org/docs/challenge-types/#http-01-challenge) method. Support for the [DNS-01 challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) method is planned for a future release. If domain ownership validation is not desired, you can disable it by enabling the **Skip DNS ownership validation** option in your ACME certificate profile configuration. - An `Issuer` is namespace-scoped. Certificates can only be issued using an `Issuer` that exists in the same namespace as the `Certificate` resource. - If you need to issue certificates across multiple namespaces with a single resource, create a `ClusterIssuer` instead. The configuration is identical except `kind: ClusterIssuer` and no `metadata.namespace`. - More details: https://cert-manager.io/docs/configuration/acme/ diff --git a/docs/images/app-connections/octopus-deploy/add-team.png b/docs/images/app-connections/octopus-deploy/add-team.png new file mode 100644 index 0000000000..84cb1005c9 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/add-team.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-api-keys.png b/docs/images/app-connections/octopus-deploy/app-connection-api-keys.png new file mode 100644 index 0000000000..dbfa576bf6 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-api-keys.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-create-key.png b/docs/images/app-connections/octopus-deploy/app-connection-create-key.png new file mode 100644 index 0000000000..8922e6b9f3 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-create-key.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-form.png b/docs/images/app-connections/octopus-deploy/app-connection-form.png new file mode 100644 index 0000000000..f38bf27461 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-form.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-generated.png b/docs/images/app-connections/octopus-deploy/app-connection-generated.png new file mode 100644 index 0000000000..9010878b4c Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-generated.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-key-generated.png b/docs/images/app-connections/octopus-deploy/app-connection-key-generated.png new file mode 100644 index 0000000000..06f26d17f8 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-key-generated.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-option.png b/docs/images/app-connections/octopus-deploy/app-connection-option.png new file mode 100644 index 0000000000..5841c83e37 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-option.png differ diff --git a/docs/images/app-connections/octopus-deploy/app-connection-profile.png b/docs/images/app-connections/octopus-deploy/app-connection-profile.png new file mode 100644 index 0000000000..97403f6e52 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/app-connection-profile.png differ diff --git a/docs/images/app-connections/octopus-deploy/create-team.png b/docs/images/app-connections/octopus-deploy/create-team.png new file mode 100644 index 0000000000..68772f64d8 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/create-team.png differ diff --git a/docs/images/app-connections/octopus-deploy/save-team-settings.png b/docs/images/app-connections/octopus-deploy/save-team-settings.png new file mode 100644 index 0000000000..4e0eb906bf Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/save-team-settings.png differ diff --git a/docs/images/app-connections/octopus-deploy/service-account-api-key-generate.png b/docs/images/app-connections/octopus-deploy/service-account-api-key-generate.png new file mode 100644 index 0000000000..14d518c49e Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/service-account-api-key-generate.png differ diff --git a/docs/images/app-connections/octopus-deploy/service-account-api-key.png b/docs/images/app-connections/octopus-deploy/service-account-api-key.png new file mode 100644 index 0000000000..166652559c Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/service-account-api-key.png differ diff --git a/docs/images/app-connections/octopus-deploy/service-account-create.png b/docs/images/app-connections/octopus-deploy/service-account-create.png new file mode 100644 index 0000000000..98f7407ae1 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/service-account-create.png differ diff --git a/docs/images/app-connections/octopus-deploy/service-account-key-generated.png b/docs/images/app-connections/octopus-deploy/service-account-key-generated.png new file mode 100644 index 0000000000..eaa30d9b1b Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/service-account-key-generated.png differ diff --git a/docs/images/app-connections/octopus-deploy/service-account-nav.png b/docs/images/app-connections/octopus-deploy/service-account-nav.png new file mode 100644 index 0000000000..456e01a431 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/service-account-nav.png differ diff --git a/docs/images/app-connections/octopus-deploy/team-add-member-select.png b/docs/images/app-connections/octopus-deploy/team-add-member-select.png new file mode 100644 index 0000000000..9a47408b22 Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/team-add-member-select.png differ diff --git a/docs/images/app-connections/octopus-deploy/team-add-member.png b/docs/images/app-connections/octopus-deploy/team-add-member.png new file mode 100644 index 0000000000..6c23e070dc Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/team-add-member.png differ diff --git a/docs/images/app-connections/octopus-deploy/team-apply-user-role.png b/docs/images/app-connections/octopus-deploy/team-apply-user-role.png new file mode 100644 index 0000000000..f743c210ee Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/team-apply-user-role.png differ diff --git a/docs/images/app-connections/octopus-deploy/team-user-role.png b/docs/images/app-connections/octopus-deploy/team-user-role.png new file mode 100644 index 0000000000..35120b0a1e Binary files /dev/null and b/docs/images/app-connections/octopus-deploy/team-user-role.png differ diff --git a/docs/images/platform/groups/group-details.png b/docs/images/platform/groups/group-details.png new file mode 100644 index 0000000000..3cd94241db Binary files /dev/null and b/docs/images/platform/groups/group-details.png differ diff --git a/docs/images/platform/groups/groups-org-create.png b/docs/images/platform/groups/groups-org-create.png index a8a1e677cb..25af815e1b 100644 Binary files a/docs/images/platform/groups/groups-org-create.png and b/docs/images/platform/groups/groups-org-create.png differ diff --git a/docs/images/platform/groups/groups-org-users-assign.png b/docs/images/platform/groups/groups-org-users-assign.png index b5f629c2ec..b1e6cbf87a 100644 Binary files a/docs/images/platform/groups/groups-org-users-assign.png and b/docs/images/platform/groups/groups-org-users-assign.png differ diff --git a/docs/images/platform/groups/groups-org-users.png b/docs/images/platform/groups/groups-org-users.png deleted file mode 100644 index 383425e776..0000000000 Binary files a/docs/images/platform/groups/groups-org-users.png and /dev/null differ diff --git a/docs/images/platform/groups/groups-org.png b/docs/images/platform/groups/groups-org.png index 13b2edc445..db9ddb2d1b 100644 Binary files a/docs/images/platform/groups/groups-org.png and b/docs/images/platform/groups/groups-org.png differ diff --git a/docs/images/platform/groups/groups-project-create.png b/docs/images/platform/groups/groups-project-create.png index 9232aa042f..87e4fdf6b4 100644 Binary files a/docs/images/platform/groups/groups-project-create.png and b/docs/images/platform/groups/groups-project-create.png differ diff --git a/docs/images/platform/groups/groups-project.png b/docs/images/platform/groups/groups-project.png index 83e384861a..cd5ec63bc6 100644 Binary files a/docs/images/platform/groups/groups-project.png and b/docs/images/platform/groups/groups-project.png differ diff --git a/docs/images/platform/pki/enrollment-methods/acme/acme-config.png b/docs/images/platform/pki/enrollment-methods/acme/acme-config.png index 11ea8b075b..0b5581fe0f 100644 Binary files a/docs/images/platform/pki/enrollment-methods/acme/acme-config.png and b/docs/images/platform/pki/enrollment-methods/acme/acme-config.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/select-option.png b/docs/images/secret-syncs/octopus-deploy/select-option.png new file mode 100644 index 0000000000..9bcc37abaa Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/select-option.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-created.png b/docs/images/secret-syncs/octopus-deploy/sync-created.png new file mode 100644 index 0000000000..77eea8fff7 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-created.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-destination-advanced.png b/docs/images/secret-syncs/octopus-deploy/sync-destination-advanced.png new file mode 100644 index 0000000000..3e4e7ee7c6 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-destination-advanced.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-destination.png b/docs/images/secret-syncs/octopus-deploy/sync-destination.png new file mode 100644 index 0000000000..fde047b3d7 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-destination.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-details.png b/docs/images/secret-syncs/octopus-deploy/sync-details.png new file mode 100644 index 0000000000..a16d6a1d23 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-details.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-options.png b/docs/images/secret-syncs/octopus-deploy/sync-options.png new file mode 100644 index 0000000000..73ec52941a Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-options.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-review.png b/docs/images/secret-syncs/octopus-deploy/sync-review.png new file mode 100644 index 0000000000..9735209b57 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-review.png differ diff --git a/docs/images/secret-syncs/octopus-deploy/sync-source.png b/docs/images/secret-syncs/octopus-deploy/sync-source.png new file mode 100644 index 0000000000..ae66a01d38 Binary files /dev/null and b/docs/images/secret-syncs/octopus-deploy/sync-source.png differ diff --git a/docs/integrations/app-connections/octopus-deploy.mdx b/docs/integrations/app-connections/octopus-deploy.mdx new file mode 100644 index 0000000000..2cfdfe4463 --- /dev/null +++ b/docs/integrations/app-connections/octopus-deploy.mdx @@ -0,0 +1,183 @@ +--- +title: "Octopus Deploy Connection" +description: "Learn how to configure an Octopus Deploy Connection for Infisical." +--- + +Infisical supports the use of [API Keys](https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key) to connect with Octopus Deploy. + +## Create Octopus Deploy API Key + +Octopus Deploy supports two methods for creating API keys: via a user profile or via a service account. + + + + + + + + From your Octopus Deploy dashboard, go to **Configuration** > **Users** and click on the **Create Service Accounts** button. + ![Service Accounts](/images/app-connections/octopus-deploy/service-account-nav.png) + + + Provide: + - Username: A name for the service account + - Display Name: A display name for the service account + + Then click **Save**. + ![Create Service Account](/images/app-connections/octopus-deploy/service-account-create.png) + + + Navigate to **Configuration** > **Teams** and click **Add Team**. + + ![Add Team](/images/app-connections/octopus-deploy/add-team.png) + + Provide: + - New Team Name: A name for the team + - Team Description(optional): A description for the team + - Select the team access type: + - Accessible in the `current` space only + - Accessible in all spaces(system team) + + ![Create Team](/images/app-connections/octopus-deploy/create-team.png) + Then click **Save**. + + + After creating the team, you will be redirected to the team details page. Click on the **Add Members** button. + + ![Add Service Account to Team](/images/app-connections/octopus-deploy/team-add-member.png) + + Select the service account you created in the previous step and click **Add**. + ![Add Service Account to Team](/images/app-connections/octopus-deploy/team-add-member-select.png) + + + + After adding the service account to the team, Click on the **User Roles** tab and click **Include User Role** button. + + ![Add User Role to Team](/images/app-connections/octopus-deploy/team-user-role.png) + + Search for the **Project Contributor** role and click on the **Apply** button. + ![Apply User Role to Team](/images/app-connections/octopus-deploy/team-apply-user-role.png) + + Click on the **Save** button. + ![Save User Role to Team](/images/app-connections/octopus-deploy/save-team-settings.png) + + + After saving the team settings, we have to create an API key for the service account. Go back to **Configuration** > **Users** and find your service account. Click on the service account to view its details. + + Click on the **API Keys** section and click **New API Key**. + ![Create Service Account API Key](/images/app-connections/octopus-deploy/service-account-api-key.png) + + + Provide a purpose for the key and set an expiry date, then click **Generate New**. + ![Generate API Key](/images/app-connections/octopus-deploy/service-account-api-key-generate.png) + + + Make sure to copy the API key now, you won't be able to access it again. + ![Service Account API Key Generated](/images/app-connections/octopus-deploy/service-account-key-generated.png) + + + + + + + + + Infisical recommends using a service account for production integrations as they provide better security and are not tied to individual user accounts. + + + + From your Octopus Deploy dashboard, click on your profile in the bottom left corner and select **My profile**. + ![Octopus Deploy User Profile](/images/app-connections/octopus-deploy/app-connection-profile.png) + + + In your profile settings, go to the **My API Keys** tab and click **New API Key**. + ![API Keys Tab](/images/app-connections/octopus-deploy/app-connection-api-keys.png) + + + Provide a purpose for the key. Set an expiry date, then click **Generate New**. + ![Create API Key](/images/app-connections/octopus-deploy/app-connection-create-key.png) + + + Make sure to copy the API key now, you won't be able to access it again. + ![API Key Generated](/images/app-connections/octopus-deploy/app-connection-key-generated.png) + + + + + + +## Create an Octopus Deploy Connection in Infisical + + + + + + In your Infisical dashboard, navigate to the **App Connections** page in the desired project. + ![App Connections Tab](/images/app-connections/general/add-connection.png) + + + Click **+ Add Connection** and choose **Octopus Deploy** Connection from the list of integrations. + ![Select Octopus Deploy Connection](/images/app-connections/octopus-deploy/app-connection-option.png) + + + Complete the form by providing: + - A descriptive name for the connection + - An optional description + - The Instance URL (e.g., https://your-instance.octopus.app) + - The API Key from the previous step + ![Octopus Deploy Connection Modal](/images/app-connections/octopus-deploy/app-connection-form.png) + + + After submitting the form, your **Octopus Deploy Connection** will be successfully created and ready to use with your Infisical project. + ![Octopus Deploy Connection Created](/images/app-connections/octopus-deploy/app-connection-generated.png) + + + + + + + To create an Octopus Deploy Connection via API, send a request to the [Create Octopus Deploy Connection](/api-reference/endpoints/app-connections/octopus-deploy/create) endpoint. + + ### Sample request + + ```bash Request + curl --request POST \ + --url https://app.infisical.com/api/v1/app-connections/octopus-deploy \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "my-octopus-deploy-connection", + "method": "api-key", + "projectId": "abcdef12-3456-7890-abcd-ef1234567890", + "credentials": { + "instanceUrl": "https://your-instance.octopus.app", + "apiKey": "[API KEY]" + } + }' + ``` + + ### Sample response + + ```json Response + { + "appConnection": { + "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab", + "name": "my-octopus-deploy-connection", + "description": null, + "projectId": "abcdef12-3456-7890-abcd-ef1234567890", + "version": 1, + "orgId": "abcdef12-3456-7890-abcd-ef1234567890", + "createdAt": "2025-10-13T10:15:00.000Z", + "updatedAt": "2025-10-13T10:15:00.000Z", + "isPlatformManagedCredentials": false, + "credentialsHash": "d41d8cd98f00b204e9800998ecf8427e", + "app": "octopus-deploy", + "method": "api-key", + "credentials": { + "instanceUrl": "https://your-instance.octopus.app", + } + } + } + ``` + + + diff --git a/docs/integrations/cicd/teamcity.mdx b/docs/integrations/cicd/teamcity.mdx deleted file mode 100644 index 0b58f1b807..0000000000 --- a/docs/integrations/cicd/teamcity.mdx +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "TeamCity" -description: "How to sync secrets from Infisical to TeamCity" ---- - - - The TeamCity Native Integration will be deprecated in 2026. Please migrate to our new [TeamCity Sync](../secret-syncs/teamcity). - diff --git a/docs/integrations/platforms/certificate-agent.mdx b/docs/integrations/platforms/certificate-agent.mdx new file mode 100644 index 0000000000..90bddeacb2 --- /dev/null +++ b/docs/integrations/platforms/certificate-agent.mdx @@ -0,0 +1,552 @@ +--- +title: "Infisical Agent" +sidebarTitle: "Infisical Agent" +description: "Learn how to use Infisical CLI Agent to manage certificates automatically." +--- + +## Concept + +The Infisical Agent is a client daemon that is packaged into the [Infisical CLI](/cli/overview). +It can be used to request a certificate from Infisical using the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) configured on a [certificate profile](/documentation/platform/pki/certificates/profiles), persist it to a specified path on the filesystem, and automatically monitor and renew it before expiration. + +The Infisical Agent is notable: + +- Automating certificate management: The agent can request, persist, monitor, and renew certificates from Infisical automatically without manual intervention. It also supports post-event hooks to execute custom commands after certificate issuance, renewal, or failure events. +- Leveraging workload identity: The agent can authenticate with Infisical as a [machine identity](/documentation/platform/identities/machine-identities) using an infrastructure-native authentication method such as [AWS Auth](/docs/documentation/platform/identities/aws-auth), [Azure Auth](/docs/documentation/platform/identities/azure-auth), [GCP Auth](/docs/documentation/platform/identities/gcp-auth), [Kubernetes Auth](/docs/documentation/platform/identities/kubernetes-auth), etc. + +The typical workflow for using the agent involves installing the Infisical CLI on the target machine, creating a configuration file defining the certificate to request and how it should be managed, and then starting the agent with that configuration so it can request, persist, monitor, and renew the certificate before it expires. +This follows a [client-driven approach](/documentation/platform/pki/certificates/certificates#client-driven-certificate-renewal) to certificate renewal. + +## Workflow + +A typical workflow for using the Infisical Agent to request certificates from Infisical consists of the following steps: + +1. Create a [certificate profile](/documentation/platform/pki/certificates/profiles) in Infisical with the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) configured on it. +2. Install the [Infisical CLI](/cli/overview) on the target machine. +3. Create an agent [configuration file](/integrations/platforms/certificate-agent#agent-configuration) containing details about the certificate to request and how it should be managed such as renewal thresholds, post-event hooks, etc. +4. Start the agent with that configuration so it can request, persist, monitor, and going forward automatically renew the certificate before it expires on the target machine. + +## Operating the Agent + +This section describes how to use the Infisical Agent to request certificates from Infisical. It covers how the agent authenticates with Infisical, +and how to configure it to start requesting certificates from Infisical. + +### Authentication + +The Infisical Agent can authenticate with Infisical as a [machine identity](/documentation/platform/identities/machine-identities) using one of its supported authentication methods. + +Upon successful authentication, the agent receives a short-lived access token that it uses to make subsequent authenticated requests to obtain and renew certificates from Infisical; +the agent automatically handles token renewal as documented [here](/integrations/platforms/infisical-agent#token-renewal). + + + + The Universal Auth method uses a client ID and secret for authentication. + + + + To create a universal auth machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/universal-auth). + + + Update the agent configuration file with the auth method and credentials: + + ```yaml + auth: + type: "universal-auth" + config: + client-id: "./client-id" # Path to file containing client ID + client-secret: "./client-secret" # Path to file containing client secret + remove-client-secret-on-read: false # Optional: remove secret file after reading + ``` + + You can also provide credentials directly: + + ```yaml + auth: + type: "universal-auth" + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + ``` + + + + + + The Kubernetes Auth method is used when running the agent in a Kubernetes environment. + + + + To create a Kubernetes machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/kubernetes-auth). + + + Configure the agent to use Kubernetes service account authentication: + + ```yaml + auth: + type: "kubernetes-auth" + config: + identity-id: "your-kubernetes-identity-id" + service-account-token-path: "/var/run/secrets/kubernetes.io/serviceaccount/token" + ``` + + + + + + The Azure Auth method is used when running the agent in an Azure environment. + + + + To create an Azure machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/azure-auth). + + + Configure the agent to use Azure managed identity authentication: + + ```yaml + auth: + type: "azure-auth" + config: + identity-id: "your-azure-identity-id" + ``` + + + + + + The Native GCP ID Token method is used to authenticate with Infisical when running in a GCP environment. + + + + To create a GCP machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/gcp-auth). + + + Update the agent configuration file with the specified auth method and identity ID: + + ```yaml + auth: + type: "gcp-id-token" + config: + identity-id: "your-gcp-identity-id" + ``` + + + + + + The GCP IAM method is used to authenticate with Infisical with a GCP service account key. + + + + To create a GCP machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/gcp-auth). + + + Update the agent configuration file with the specified auth method, identity ID, and service account key: + + ```yaml + auth: + type: "gcp-iam" + config: + identity-id: "your-gcp-identity-id" + service-account-key: "/path/to/service-account-key.json" + ``` + + + + + + The AWS IAM method is used to authenticate with Infisical with an AWS IAM role while running in an AWS environment. + + + + To create an AWS machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/aws-auth). + + + Update the agent configuration file with the specified auth method and identity ID: + + ```yaml + auth: + type: "aws-iam" + config: + identity-id: "your-aws-identity-id" + ``` + + + + + + +### Agent Configuration + +The Infisical Agent relies on a YAML configuration file to define its behavior, including how it should authenticate with Infisical, the certificate it should request, and how that certificate should be managed including auto-renewal. + +The code snippet below shows an example configuration file that instructs the agent to request and continuously renew a certificate from Infisical. + +Note that not all configuration options in this file are required but this example includes all of the available options. + +```yaml example-cert-agent-config.yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: ["api.example.com", "api-v2.example.com"] + ttl: "90d" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + + # Enable automatic certificate renewal + lifecycle: + renew-before-expiry: "30d" + status-check-interval: "6h" + + # Configure where to store the issued certificate and its associated private key and certificate chain + file-output: + private-key: + path: "/etc/ssl/private/web.key" + permission: "0600" # Read/write for owner only + certificate: + path: "/etc/ssl/certs/web.crt" + permission: "0644" # Read for all, write for owner + chain: + path: "/etc/ssl/certs/web-chain.crt" + permission: "0644" # Read for all, write for owner + omit-root: true # Exclude the root CA certificate in chain + + # Configure custom commands to execute after certificate issuance, renewal, or failure events + post-hooks: + on-issuance: + command: | + echo "Certificate issued for ${CERT_COMMON_NAME}" + systemctl reload nginx + timeout: 30 + + on-renewal: + command: | + echo "Certificate renewed for ${CERT_COMMON_NAME}" + systemctl reload nginx + timeout: 30 + + on-failure: + command: | + echo "Certificate operation failed: ${ERROR_MESSAGE}" + mail -s "Certificate Alert" admin@company.com < /dev/null + timeout: 30 +``` + +To be more specific, the configuration file instructs the agent to: + +- Authenticate with Infisical using the [Universal Auth](/integrations/platforms/certificate-agent#universal-auth) authentication method. +- Request a 90-day certificate against the [certificate profile](/documentation/platform/pki/certificates/profiles) named `prof-web-server-12345` with the common name `web.company.com` and the subject alternative names `web.company.com` and `www.company.com`. +- Automatically renew the certificate 30 days before expiration by checking the certificate status every 6 hours and retrying up to 3 times with a base delay of 200ms and a maximum delay of 5s if the certificate status check fails. +- Store the certificate and its associated private key and certificate chain (excluding the root CA certificate) in the filesystem at the specified paths with the specified permissions. +- Execute custom commands after certificate issuance, renewal, or failure events such as reloading an `nginx` service or sending an email notification. + +### Agent Execution + +After creating the configuration file, you can run the command below with the `--config` flag pointing to the path where the agent configuration file is located. + +```bash +infisical cert-manager agent --config /path/to/your/agent-config.yaml +``` + +This will start the agent as a daemon process, continuously monitoring and managing certificates according to your configuration. You can also run it in the foreground for debugging: + +```bash +infisical cert-manager agent --config /path/to/your/agent-config.yaml --verbose +``` + +For production deployments, you may consider running the agent as a system service to ensure it starts automatically and runs continuously. + +### Agent Certificate Configuration Parameters + +The table below provides a complete list of parameters that can be configured in the **certificate configuration** section of the agent configuration file: + +| Parameter | Required | Description | +| ------------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `profile-name` | Yes | The name of the [certificate profile](/documentation/platform/pki/certificates/profiles) to request a certificate against (e.g., `web-server-12345`) | +| `project-slug` | Yes | The slug of the project to request a certificate against (e.g., `my-project-slug`) | +| `common-name` | Optional | The common name for the certificate (e.g. `www.example.com`) | +| `alt-names` | Optional | The list of subject alternative names for the certificate (e.g., `["www.example.com", "api.example.com"]`) | +| `ttl` | Optional (uses profile default if not specified) | The time-to-live duration for the certificate, specified as a duration string (e.g. `72h`, `90d`, `1y`, etc.) | +| `key-algorithm` | Optional | The algorithm for the certificate key pair. One of: `RSA_2048`, `RSA_3072`, `RSA_4096`, `EC_prime256v1`, `EC_secp384r1`, `EC_secp521r1`. | +| `signature-algorithm` | Optional | The algorithm used to sign the certificate. One of: `RSA-SHA256`, `RSA-SHA384`, `RSA-SHA512`, `ECDSA-SHA256`, `ECDSA-SHA384`, `ECDSA-SHA512`. | +| `key-usages` | Optional | The list of key usage values for the certificate. One or more of: `digital_signature`, `key_encipherment`, `non_repudiation`, `data_encipherment`, `key_agreement`, `key_cert_sign`, `crl_sign`, `encipher_only`, `decipher_only`. | +| `extended-key-usages` | Optional | The list of extended key usage values for the certificate. One or more of: `server_auth`, `client_auth`, `code_signing`, `email_protection`, `timestamping`, `ocsp_signing`. | +| `csr-path` | Conditional | The path to a certificate signing request (CSR) file (e.g., `./csr/webserver.csr`, `/etc/ssl/csr.pem`). This is required if using a pre-generated CSR. | +| `file-output.private-key.path` | Optional (required if the `csr-path` is not specified) | The path to store the private key (required if not using a CSR) | +| `file-output.private-key.permission` | Optional (defaults to `0600`) | The octal file permissions for the private key file (e.g. `0600`) | +| `file-output.certificate.path` | Yes | The path to store the issued certificate in the filesystem | +| `file-output.certificate.permission` | Optional (defaults to `0600`) | The octal file permissions for the certificate file (e.g. `0644`) | +| `file-output.chain.path` | Optional | The path to store the certificate chain in the filesystem. | +| `file-output.chain.permission` | Optional (defaults to `0600`) | The octal permissions for the chain file (e.g. `0644`) | +| `file-output.chain.omit-root` | Optional (defaults to `true`) | Whether to exclude the root CA certificate from the returned certificate chain | +| `lifecycle.renew-before-expiry` | Optional (auto-renewal is disabled if not set) | Duration before certificate expiration when renewal checks should begin, specified as a duration string (e.g. `72h`, `90d`, `1y`, etc.) | +| `lifecycle.status-check-interval` | Optional (defaults to `10s`) | How frequently the agent checks certificate status and renewal needs, specified as a duration string (e.g. `10s`, `30m`, `1d`, etc.) | +| `post-hooks.on-issuance.command` | Optional | The shell command to execute after a certificate is successfully issued for the first time (e.g., `systemctl reload nginx`, `/usr/local/bin/reload-service.sh`) | +| `post-hooks.on-issuance.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-issuance post-hook command before it is terminated (e.g., `30`, `60`, `120`) | +| `post-hooks.on-renewal.command` | Optional | The shell command to execute after a certificate is successfully renewed (e.g., `systemctl reload nginx`, `docker restart web-server`) | +| `post-hooks.on-renewal.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-renewal post-hook command before it is terminated (e.g., `30`, `60`, `120`) | +| `post-hooks.on-failure.command` | Optional | The shell command to execute when certificate issuance or renewal fails (e.g., `logger 'Certificate renewal failed'`, `/usr/local/bin/alert.sh`) | +| `post-hooks.on-failure.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-failure post-hook command before it is terminated (e.g., `10`, `30`, `60`) | + +### Post-Event Hooks + +The Infisical Agent supports running custom commands in response to certificate lifecycle events such as issuance, renewal, and failure through the `post-hooks` configuration +in the agent configuration file. + + + + Runs when a new certificate is successfully issued: + + ```yaml + post-hooks: + on-issuance: + command: | + echo "New certificate issued for ${CERT_COMMON_NAME}" + chown nginx:nginx ${CERT_FILE_PATH} + chmod 644 ${CERT_FILE_PATH} + systemctl reload nginx + timeout: 30 + ``` + + + + + Runs when a certificate is successfully renewed: + + ```yaml + post-hooks: + on-renewal: + command: | + echo "Certificate renewed for ${CERT_COMMON_NAME}" + # Reload services that use the certificate + systemctl reload nginx + systemctl reload haproxy + + # Send notification + curl -X POST https://hooks.slack.com/... \ + -d "{'text': 'Certificate for ${CERT_COMMON_NAME} renewed successfully'}" + timeout: 60 + ``` + + + + + Runs when certificate operations fail: + + ```yaml + post-hooks: + on-failure: + command: | + echo "Certificate operation failed for ${CERT_COMMON_NAME}: ${ERROR_MESSAGE}" + # Send alert + mail -s "Certificate Failure Alert" admin@company.com < /dev/null + # Log to syslog + logger -p daemon.error "Certificate agent failure: ${ERROR_MESSAGE}" + timeout: 30 + ``` + + + + +### Retrying mechanism + +The Infisical Agent will automatically attempt to retry any failed API requests including authentication, certificate issuance, and renewal operations. +By default, the agent will retry up to 3 times with a base delay of 200ms and a maximum delay of 5s. + +You can configure the retrying mechanism through the agent configuration file: + +```yaml +infisical: + address: "https://app.infisical.com" + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" +# ... rest of the agent configuration file +``` + +## Example Agent Configuration Files + +Since there are several ways you might want to use the Infisical Agent to request certificates from Infisical, +we provide a few example configuration files for common use cases below to help you get started. + +### One-Time Certificate Issuance + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical +once without performing any subsequent auto-renewal. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: + - "api.example.com" + - "api-v2.example.com" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + ttl: "30d" + file-output: + private-key: + path: "/etc/ssl/private/api.example.com.key" + permission: "0600" + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + omit-root: true +``` + +### One-Time Certificate Issuance using a Pre-Generated CSR + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical +once using a pre-generated CSR. + +Note that when `csr-path` is specified: + +- The `private-key` is omitted from the configuration file because we assume that it is pre-generated and managed externally, with only the CSR being submitted to Infisical for signing. +- The agent will not be able to perform any auto-renewal operations, as it is assumed to not have access to the private key required to generate a new CSR. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + csr-path: "/etc/ssl/requests/api.csr" + file-output: + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + omit-root: true +``` + +### Certificate Issuance with Automatic Renewal + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical and continuously renew it 14 days before expiration, checking the certificate status every 6 hours. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: + - "api.example.com" + - "api-v2.example.com" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + ttl: "30d" + lifecycle: + renew-before-expiry: "14d" # Renew 14 days before expiration + status-check-interval: "6h" # Check certificate status every 6 hours + file-output: + private-key: + path: "/etc/ssl/private/api.example.com.key" + permission: "0600" + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + post-hooks: + on-issuance: + command: "systemctl reload nginx" + timeout: 30 + on-renewal: + command: "systemctl reload nginx && logger 'Certificate renewed'" + timeout: 30 +``` diff --git a/docs/integrations/platforms/kubernetes-injector.mdx b/docs/integrations/platforms/kubernetes-injector.mdx index f51a96ab29..8afccae00e 100644 --- a/docs/integrations/platforms/kubernetes-injector.mdx +++ b/docs/integrations/platforms/kubernetes-injector.mdx @@ -140,6 +140,11 @@ The Infisical Agent Injector supports the following annotations: This will ensure that no new leases are created except those initially created in the init container. The sidecar container will register the leases created in the init container and start managing them from that point onwards. + + Specify a custom agent image to use for the agent sidecar / init container(s). Example: `infisical/cli:0.43.32`. + If not specified, the most recent stable version of the Infisical Agent will be used. + + Whether to revoke all managed dynamic secret leases and machine identity access tokens on shutdown. Defaults to `false`. diff --git a/docs/integrations/platforms/kubernetes/overview.mdx b/docs/integrations/platforms/kubernetes/overview.mdx index 71ae05c46f..b9dcccf801 100644 --- a/docs/integrations/platforms/kubernetes/overview.mdx +++ b/docs/integrations/platforms/kubernetes/overview.mdx @@ -142,6 +142,134 @@ Currently the operator supports the following CRD's. We are constantly expanding 2. [InfisicalPushSecret](/integrations/platforms/kubernetes/infisical-push-secret-crd): Push secrets from a Kubernetes secret to Infisical. 3. [InfisicalDynamicSecret](/integrations/platforms/kubernetes/infisical-dynamic-secret-crd): Sync dynamic secrets and create leases automatically in Kubernetes. +## Metrics and Prometheus + +The operator exposes Prometheus metrics on `/metrics` for monitoring reconciliation performance, errors, and resource utilization. + +### Configuration + +Enable the ServiceMonitor during installation. This will create a prometheus `ServiceMonitor` resource in the same namespace as the operator. + +```yaml values.yaml +telemetry: + serviceMonitor: + enabled: true + # ... other telemetry configuration (optional) ... +``` + + + + Enable ServiceMonitor for Prometheus Operator. Defaults to `false`. + + + + Additional labels for ServiceMonitor. Defaults to `{}`. + + + + Scheme to use for the ServiceMonitor. Defaults to `https`. + + + + Port to use for the ServiceMonitor. Defaults to `https`. + + + + Path to use for the ServiceMonitor. Defaults to `/metrics`. + + + + Scrape interval. Defaults to `30s`. + + + + Scrape timeout. Defaults to `10s`. + + + + Bearer token file. Defaults to `/var/run/secrets/kubernetes.io/serviceaccount/token`. + + + + +```yaml full-example-values.yaml +telemetry: + serviceMonitor: + enabled: true + + selectors: {} + scheme: https + port: https + path: /metrics + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + interval: 30s + scrapeTimeout: 10s +``` + +### Available Metrics + +The operator exposes standard controller-runtime metrics. For a complete list of available metrics, see the [Kubebuilder metrics reference](https://book.kubebuilder.io/reference/metrics.html). + +**Key metrics to monitor:** +- `controller_runtime_reconcile_total` - Reconciliation count +- `controller_runtime_reconcile_errors_total` - Error count +- `controller_runtime_reconcile_time_seconds` - Reconciliation duration + +**Controllers:** `InfisicalSecret`, `InfisicalPushSecret`, `InfisicalDynamicSecret` + +### Example Prometheus Setup + + + + ```bash + helm repo add prometheus-community https://prometheus-community.github.io/helm-charts + helm repo update + + helm install prometheus prometheus-community/kube-prometheus-stack \ + --namespace monitoring \ + --create-namespace + ``` + + + + ```bash + helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/' + + helm install infisical-secrets-operator infisical-helm-charts/secrets-operator \ + --set telemetry.serviceMonitor.enabled=true + ``` + + + + ```bash + kubectl get servicemonitor + ``` + + Check that the ServiceMonitor appears in your operator's namespace. + + + + ```bash + kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090 + ``` + + Open [http://localhost:9090/targets](http://localhost:9090/targets) and verify the operator target shows **UP**. + + + +### Example Queries + +```promql +# Total reconciliations +controller_runtime_reconcile_total + +# P99 latency +histogram_quantile(0.99, rate(controller_runtime_reconcile_time_seconds_bucket[5m])) + +# Memory usage (MB) +process_resident_memory_bytes / 1024 / 1024 +``` + ## General Configuration ### Private/self-signed certificate To connect to Infisical instances behind a private/self-signed certificate, you can configure the TLS settings in the CRD diff --git a/docs/integrations/secret-syncs/octopus-deploy.mdx b/docs/integrations/secret-syncs/octopus-deploy.mdx new file mode 100644 index 0000000000..fd9f22ca17 --- /dev/null +++ b/docs/integrations/secret-syncs/octopus-deploy.mdx @@ -0,0 +1,209 @@ +--- +title: "Octopus Deploy Sync" +description: "Learn how to configure an Octopus Deploy Sync for Infisical." +--- + +**Prerequisites:** + +- Create an [Octopus Deploy Connection](/integrations/app-connections/octopus-deploy) + + + + + + Navigate to **Project** > **Integrations** and select the **Secret Syncs** tab. Click on the **Add Sync** button. + + ![Secret Syncs Tab](/images/secret-syncs/general/secret-sync-tab.png) + + + ![Select Octopus Deploy](/images/secret-syncs/octopus-deploy/select-option.png) + + + Configure the **Source** from where secrets should be retrieved, then click **Next**. + + ![Configure Source](/images/secret-syncs/octopus-deploy/sync-source.png) + + - **Environment**: The project environment to retrieve secrets from. + - **Secret Path**: The folder path to retrieve secrets from. + + + If you need to sync secrets from multiple folder locations, check out [secret imports](/documentation/platform/secret-reference#secret-imports). + + + + Configure the **Destination** to where secrets should be deployed, then click **Next**. + + + The destination configuration is organized into two tabs: + + **General Tab:** + ![Configure Destination](/images/secret-syncs/octopus-deploy/sync-destination.png) + - **Octopus Deploy Connection**: The Octopus Deploy Connection to authenticate with. + - **Space**: The Octopus Deploy Space to sync secrets to. + - **Project**: The Octopus Deploy Project within the Space to sync secrets to. + + **Advanced Tab:** + ![Configure Destination Advanced](/images/secret-syncs/octopus-deploy/sync-destination-advanced.png) + The Advanced tab allows you to specify optional scope values to restrict where the synced variables are available within your Octopus Deploy project: + - **Environments**: Restrict variables to specific environments (e.g., Development, Staging, Production). + - **Target Tags**: Restrict variables to specific target tags (e.g., web-server, database). + - **Targets**: Restrict variables to specific deployment targets. + - **Processes**: Restrict variables to specific deployment processes. + - **Deployment Steps**: Restrict variables to specific deployment steps. + - **Channels**: Restrict variables to specific release channels. + + + + Configure the **Sync Options** to specify how secrets should be synced, then click **Next**. + + ![Configure Options](/images/secret-syncs/octopus-deploy/sync-options.png) + + - **Initial Sync Behavior**: Determines how Infisical should resolve the initial sync. + - **Overwrite Destination Secrets**: Removes any secrets at the destination endpoint not present in Infisical. + + Octopus Deploy does not support importing secrets. + + - **Key Schema**: Template that determines how secret names are transformed when syncing, using `{{secretKey}}` as a placeholder for the original secret name and `{{environment}}` for the environment. + + We highly recommend using a Key Schema to ensure that Infisical only manages the specific keys you intend, keeping everything else untouched. + + - **Auto-Sync Enabled**: If enabled, secrets will automatically be synced from the source location when changes occur. Disable to enforce manual syncing only. + - **Disable Secret Deletion**: If enabled, Infisical will not remove secrets from the sync destination. Enable this option if you intend to manage some secrets manually outside of Infisical. + + + Configure the **Details** of your Octopus Deploy Sync, then click **Next**. + + ![Configure Details](/images/secret-syncs/octopus-deploy/sync-details.png) + + - **Name**: The name of your sync. Must be slug-friendly. + - **Description**: An optional description for your sync. + + + Review your Octopus Deploy Sync configuration, then click **Create Sync**. + + ![Review Configuration](/images/secret-syncs/octopus-deploy/sync-review.png) + + + If enabled, your Octopus Deploy Sync will begin syncing your secrets to the destination endpoint. + + ![Sync Created](/images/secret-syncs/octopus-deploy/sync-created.png) + + + + + + + To create an **Octopus Deploy Sync**, make an API request to the [Create Octopus Deploy Sync](/api-reference/endpoints/secret-syncs/octopus-deploy/create) API endpoint. + + ### Sample request + + ```bash Request + curl --request POST \ + --url https://app.infisical.com/api/v1/secret-syncs/octopus-deploy \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "my-octopus-deploy-sync", + "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "description": "sync to octopus deploy project", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "environment": "dev", + "secretPath": "/", + "isEnabled": true, + "isAutoSyncEnabled": true, + "syncOptions": { + "initialSyncBehavior": "overwrite-destination", + "disableSecretDeletion": false + }, + "destinationConfig": { + "spaceId": "Spaces-1", + "scope": "project", + "projectId": "Projects-123", + "scopeValues": { + "environments": ["Environments-1", "Environments-2"], + "roles": ["web-server"], + "channels": ["Channels-1"] + } + } + }' + ``` + + ### Sample response + + ```json Response + { + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "name": "my-octopus-deploy-secret-sync", + "description": null, + "isAutoSyncEnabled": true, + "version": 1, + "projectId": "1e812ad3-e5df-4f1b-839d-13b4ef201840", + "folderId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "connectionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "createdAt": "2025-12-12T09:44:59.023Z", + "updatedAt": "2025-12-12T09:44:59.023Z", + "syncStatus": "succeeded", + "lastSyncJobId": null, + "lastSyncMessage": null, + "lastSyncedAt": null, + "importStatus": null, + "lastImportJobId": null, + "lastImportMessage": null, + "lastImportedAt": null, + "removeStatus": null, + "lastRemoveJobId": null, + "lastRemoveMessage": null, + "lastRemovedAt": null, + "syncOptions": { + "initialSyncBehavior": "overwrite-destination", + "disableSecretDeletion": false + }, + "connection": { + "app": "octopus-deploy", + "name": "my-octopus-deploy-connection", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "environment": { + "slug": "dev", + "name": "Development", + "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" + }, + "folder": { + "id": "ad9c26ed-a7ee-41f4-b883-8dd25736052a", + "path": "/" + }, + "destination": "octopus-deploy", + "destinationConfig": { + "spaceId": "Spaces-1", + "scope": "project", + "projectId": "Projects-1", + "scopeValues": { + "environments": [ + "Environments-1", + "Environments-2" + ], + "roles": [ + "sample-app-server" + ], + "machines": [ + "Machines-1", + "Machines-2" + ], + "processes": [ + "Runbooks-1", + "Runbooks-2" + ], + "actions": [ + "3c90c3cc-0d44-4b50-8888-8dd25736052a", + "3c90c3cc-0d44-4b50-8888-8dd25736052a" + ], + "channels": [ + "Channels-2", + "Channels-1" + ] + } + } + } + ``` + + + diff --git a/docs/self-hosting/guides/automated-bootstrapping.mdx b/docs/self-hosting/guides/automated-bootstrapping.mdx index 3c2186eb9e..6c3671df90 100644 --- a/docs/self-hosting/guides/automated-bootstrapping.mdx +++ b/docs/self-hosting/guides/automated-bootstrapping.mdx @@ -247,9 +247,9 @@ curl -X POST \ "projectDescription": "A project created via API", "slug": "new-project-slug", "template": "default", - "type": "SECRET_MANAGER" + "type": "secret-manager" }' \ - https://your-infisical-instance.com/api/v2/projects + https://your-infisical-instance.com/api/v1/projects ``` ## Important Notes diff --git a/docs/snippets/AppConnectionsBrowser.jsx b/docs/snippets/AppConnectionsBrowser.jsx index c79ef366ba..ca811b8c36 100644 --- a/docs/snippets/AppConnectionsBrowser.jsx +++ b/docs/snippets/AppConnectionsBrowser.jsx @@ -368,6 +368,13 @@ export const AppConnectionsBrowser = () => { path: "/integrations/app-connections/mongodb", description: "Learn how to connect your MongoDB to pull secrets from Infisical.", category: "Databases" + }, + { + name: "Octopus Deploy", + slug: "octopus-deploy", + path: "/integrations/app-connections/octopus-deploy", + description: "Learn how to connect your Octopus Deploy to pull secrets from Infisical.", + category: "DevOps Tools", } ].sort(function (a, b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); diff --git a/docs/snippets/SecretSyncsBrowser.jsx b/docs/snippets/SecretSyncsBrowser.jsx index 17ff9e97b9..0f433c4caa 100644 --- a/docs/snippets/SecretSyncsBrowser.jsx +++ b/docs/snippets/SecretSyncsBrowser.jsx @@ -39,7 +39,8 @@ export const SecretSyncsBrowser = () => { {"name": "Zabbix", "slug": "zabbix", "path": "/integrations/secret-syncs/zabbix", "description": "Learn how to sync secrets from Infisical to Zabbix.", "category": "Monitoring"}, {"name": "Laravel Forge", "slug": "laravel-forge", "path": "/integrations/secret-syncs/laravel-forge", "description": "Learn how to sync secrets from Infisical to Laravel Forge.", "category": "Hosting"}, {"name": "Chef", "slug": "chef", "path": "/integrations/secret-syncs/chef", "description": "Learn how to sync secrets from Infisical to Chef.", "category": "DevOps Tools"}, - {"name": "Northflank", "slug": "northflank", "path": "/integrations/secret-syncs/northflank", "description": "Learn how to sync secrets from Infisical to Northflank projects.", "category": "Hosting"} + {"name": "Northflank", "slug": "northflank", "path": "/integrations/secret-syncs/northflank", "description": "Learn how to sync secrets from Infisical to Northflank projects.", "category": "Hosting"}, + {"name": "Octopus Deploy", "slug": "octopus-deploy", "path": "/integrations/secret-syncs/octopus-deploy", "description": "Learn how to sync secrets from Infisical to Octopus Deploy.", "category": "DevOps Tools"} ].sort(function(a, b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); }); diff --git a/docs/snippets/documentation/platform/pki/guides/request-cert-setup.mdx b/docs/snippets/documentation/platform/pki/guides/request-cert-setup.mdx new file mode 100644 index 0000000000..c703fd63d2 --- /dev/null +++ b/docs/snippets/documentation/platform/pki/guides/request-cert-setup.mdx @@ -0,0 +1,27 @@ + + Before you can issue any certificate, you must first configure a [Certificate Authority (CA)](/documentation/platform/pki/ca/overview). + + The CA you configure will be used to issue the certificate back to your client; it can be either Internal or External: + + - [Internal CA](/documentation/platform/pki/ca/private-ca): If you're building your own PKI and wish to issue certificates for internal use, you should + follow the guide [here](/documentation/platform/pki/ca/private-ca#guide-to-creating-a-ca-hierarchy) to create at minimum a root CA and an intermediate/issuing CA + within Infisical. + + - [External CA](/documentation/platform/pki/ca/external-ca): If you have existing PKI infrastructure or wish to connect to a public CA (e.g. [Let's Encrypt](/documentation/platform/pki/ca/lets-encrypt), [DigiCert](/documentation/platform/pki/ca/digicert), etc.) to issue TLS certificates, + you should follow the documentation [here](/documentation/platform/pki/ca/external-ca) to configure an External CA. + + + Note that if you're looking to issue self-signed certificates, you can skip this step and proceed to Step 3. + + + + + Next, follow the guide [here](/documentation/platform/pki/certificates/templates#guide-to-creating-a-certificate-template) to create a [certificate template](/documentation/platform/pki/certificates/templates). + + The certificate template will constrain what attributes may or may not be allowed in the request to issue a certificate. + For example, you can specify that the requested common name must adhere to a specific format like `*.acme.com` and + that the maximum TTL cannot exceed 1 year. + + If you're looking to issue TLS server certificates, you should select the **TLS Server Certificate** option under the **Template Preset** dropdown. + + diff --git a/frontend/index.html b/frontend/index.html index b1dca0a761..79c64b7dbd 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -8,15 +8,15 @@ http-equiv="Content-Security-Policy" content=" default-src 'self'; - connect-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net https://*.posthog.com http://127.0.0.1:* https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@0.38.2/dist/dotlottie-player.wasm; - script-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net https://*.posthog.com https://js.stripe.com https://api.stripe.com https://widget.intercom.io https://js.intercomcdn.com https://hcaptcha.com https://*.hcaptcha.com 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@0.38.2/dist/dotlottie-player.wasm; - style-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net 'unsafe-inline' https://hcaptcha.com https://*.hcaptcha.com; + connect-src 'self' https://*.posthog.com http://127.0.0.1:* https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@0.38.2/dist/dotlottie-player.wasm; + script-src 'self' https://*.posthog.com https://js.stripe.com https://api.stripe.com https://widget.intercom.io https://js.intercomcdn.com https://hcaptcha.com https://*.hcaptcha.com 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@0.38.2/dist/dotlottie-player.wasm; + style-src 'self' 'unsafe-inline' https://hcaptcha.com https://*.hcaptcha.com; child-src https://api.stripe.com; frame-src https://js.stripe.com/ https://api.stripe.com https://www.youtube.com/ https://hcaptcha.com https://*.hcaptcha.com; - connect-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net wss://nexus-websocket-a.intercom.io https://api-iam.intercom.io https://api.heroku.com/ https://id.heroku.com/oauth/authorize https://id.heroku.com/oauth/token https://checkout.stripe.com https://app.posthog.com https://api.stripe.com https://api.pwnedpasswords.com http://127.0.0.1:* https://hcaptcha.com https://*.hcaptcha.com; - img-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net https://static.intercomassets.com https://js.intercomcdn.com https://downloads.intercomcdn.com https://*.stripe.com https://i.ytimg.com/ data:; - media-src https://d1zwf0dwl0k2ky.cloudfront.net https://js.intercomcdn.com; - font-src 'self' https://d1zwf0dwl0k2ky.cloudfront.net https://fonts.intercomcdn.com/ https://fonts.gstatic.com; + connect-src 'self' wss://nexus-websocket-a.intercom.io https://api-iam.intercom.io https://api.heroku.com/ https://id.heroku.com/oauth/authorize https://id.heroku.com/oauth/token https://checkout.stripe.com https://app.posthog.com https://api.stripe.com https://api.pwnedpasswords.com http://127.0.0.1:* https://hcaptcha.com https://*.hcaptcha.com; + img-src 'self' https://static.intercomassets.com https://js.intercomcdn.com https://downloads.intercomcdn.com https://*.stripe.com https://i.ytimg.com/ data:; + media-src 'self' https://js.intercomcdn.com; + font-src 'self' https://fonts.intercomcdn.com/ https://fonts.gstatic.com; " /> Infisical diff --git a/frontend/package-lock.json b/frontend/package-lock.json index bbb72bfa7c..84755ab94f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -152,8 +152,7 @@ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", @@ -198,6 +197,7 @@ "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", @@ -490,6 +490,7 @@ "resolved": "https://registry.npmjs.org/@casl/ability/-/ability-6.7.2.tgz", "integrity": "sha512-KjKXlcjKbUz8dKw7PY56F7qlfOFgxTU6tnlJ8YrbDyWkJMIlHa6VRWzCD8RU20zbJUC1hExhOFggZjm6tf1mUw==", "license": "MIT", + "peer": true, "dependencies": { "@ucast/mongo2js": "^1.3.0" }, @@ -548,6 +549,7 @@ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", "license": "MIT", + "peer": true, "dependencies": { "@dnd-kit/accessibility": "^3.1.1", "@dnd-kit/utilities": "^3.2.2", @@ -1325,6 +1327,7 @@ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.1.tgz", "integrity": "sha512-8dBIHbfsKlCk2jHQ9PoRBg2Z+4TwyE3vZICSnoDlnsHA6SiMlTwfmW6yX0lHsRmWJugkeb92sA0hZdkXJhuz+g==", "license": "MIT", + "peer": true, "dependencies": { "@fortawesome/fontawesome-common-types": "6.7.1" }, @@ -2015,6 +2018,7 @@ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.2.tgz", "integrity": "sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==", "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.0.0", @@ -4489,6 +4493,7 @@ "integrity": "sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/utils": "^8.13.0", "eslint-visitor-keys": "^4.2.0", @@ -5114,6 +5119,7 @@ "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.95.1.tgz", "integrity": "sha512-P5x4yNhcdkYsCEoYeGZP8Q9Jlxf0WXJa4G/xvbmM905seZc9FqJqvCSRvX3dWTPOXRABhl4g+8DHqfft0c/AvQ==", "license": "MIT", + "peer": true, "dependencies": { "@tanstack/history": "1.95.0", "@tanstack/react-store": "^0.7.0", @@ -5325,7 +5331,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -5346,7 +5351,6 @@ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -5357,7 +5361,6 @@ "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", @@ -5377,8 +5380,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@testing-library/user-event": { "version": "14.6.1", @@ -5386,7 +5388,6 @@ "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12", "npm": ">=6" @@ -5407,8 +5408,7 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5461,7 +5461,6 @@ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" @@ -5535,8 +5534,7 @@ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/doctrine": { "version": "0.0.9", @@ -5672,6 +5670,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.16.tgz", "integrity": "sha512-oh8AMIC4Y2ciKufU8hnKgs+ufgbA/dhPTACaZPM86AbwX9QwnFtSoPWEeRUj8fge+v6kFt78BXcDhAU1SrrAsw==", "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5683,6 +5682,7 @@ "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^18.0.0" } @@ -5730,6 +5730,7 @@ "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.34.0", @@ -5770,6 +5771,7 @@ "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", @@ -6041,7 +6043,6 @@ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", @@ -6059,7 +6060,6 @@ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", @@ -6087,7 +6087,6 @@ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -6098,7 +6097,6 @@ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tinyrainbow": "^2.0.0" }, @@ -6112,7 +6110,6 @@ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tinyspy": "^4.0.3" }, @@ -6126,7 +6123,6 @@ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", @@ -6200,6 +6196,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6316,7 +6313,6 @@ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">= 0.4" } @@ -6365,7 +6361,6 @@ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -6446,7 +6441,6 @@ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -6534,7 +6528,6 @@ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" } @@ -6545,7 +6538,6 @@ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -6558,8 +6550,7 @@ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", @@ -6609,7 +6600,6 @@ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": ">= 0.4" } @@ -6711,7 +6701,6 @@ "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "open": "^8.0.4" }, @@ -6948,6 +6937,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -7129,7 +7119,6 @@ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", @@ -7200,7 +7189,6 @@ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 16" } @@ -7586,8 +7574,7 @@ "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/cssesc": { "version": "3.0.0", @@ -7606,7 +7593,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/cva": { "name": "class-variance-authority", @@ -7678,6 +7666,7 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", + "peer": true, "engines": { "node": ">=12" } @@ -7731,8 +7720,7 @@ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", "dev": true, - "license": "BSD-2-Clause", - "peer": true + "license": "BSD-2-Clause" }, "node_modules/data-view-buffer": { "version": "1.0.1", @@ -7842,7 +7830,6 @@ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -7877,7 +7864,6 @@ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -7999,8 +7985,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/dom-helpers": { "version": "5.2.1", @@ -8210,7 +8195,6 @@ "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -8294,6 +8278,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -8335,7 +8320,6 @@ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -8372,6 +8356,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -8428,6 +8413,7 @@ "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "eslint-config-airbnb-base": "^15.0.0", "object.assign": "^4.1.2", @@ -8450,6 +8436,7 @@ "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "confusing-browser-globals": "^1.0.10", "object.assign": "^4.1.2", @@ -8480,6 +8467,7 @@ "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -8579,6 +8567,7 @@ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", @@ -8708,7 +8697,6 @@ "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -8742,6 +8730,7 @@ "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -8765,7 +8754,6 @@ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "esutils": "^2.0.2" }, @@ -8779,7 +8767,6 @@ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -8798,7 +8785,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -8960,7 +8946,6 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -9991,6 +9976,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.2" }, @@ -10084,7 +10070,6 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -10361,7 +10346,6 @@ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "is-docker": "cli.js" }, @@ -10683,7 +10667,6 @@ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-docker": "^2.0.0" }, @@ -10719,7 +10702,6 @@ "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", "license": "MIT", - "peer": true, "funding": { "type": "GitHub Sponsors ❤", "url": "https://github.com/sponsors/dmonad" @@ -10731,7 +10713,6 @@ "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", @@ -10881,7 +10862,6 @@ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -10916,8 +10896,7 @@ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", "dev": true, - "license": "CC0-1.0", - "peer": true + "license": "CC0-1.0" }, "node_modules/language-tags": { "version": "1.0.9", @@ -10925,7 +10904,6 @@ "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "language-subtag-registry": "^0.3.20" }, @@ -10958,7 +10936,6 @@ "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.102.tgz", "integrity": "sha512-g70kydI0I1sZU0ChO8mBbhw0oUW/8U0GHzygpvEIx8k+jgOpqnTSb/E+70toYVqHxBhrERD21TwD5QcZJQ40ZQ==", "license": "MIT", - "peer": true, "dependencies": { "isomorphic.js": "^0.2.4" }, @@ -11283,8 +11260,7 @@ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -11311,7 +11287,6 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -12003,7 +11978,6 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=4" } @@ -12352,7 +12326,6 @@ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -12622,7 +12595,6 @@ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 14.16" } @@ -12774,6 +12746,7 @@ "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -12890,7 +12863,6 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -12906,7 +12878,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -12919,8 +12890,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/prismjs": { "version": "1.30.0", @@ -13121,6 +13091,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -13148,6 +13119,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -13239,6 +13211,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -13289,6 +13262,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.3.tgz", "integrity": "sha512-IK18V6GVbab4TAo1/cz3kqajxbDPGofdF0w7VHdCo0Nt8PrPlOZcuuDq9YYIV1BtjcX78x0XsldbQRQnQXWXmw==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -13539,7 +13513,6 @@ "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", @@ -13557,7 +13530,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13574,7 +13546,6 @@ "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -13589,7 +13560,6 @@ "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "min-indent": "^1.0.0" }, @@ -13804,6 +13774,7 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -14314,7 +14285,6 @@ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -14330,7 +14300,6 @@ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -14358,7 +14327,6 @@ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" @@ -14579,7 +14547,8 @@ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tapable": { "version": "2.2.1", @@ -14683,7 +14652,6 @@ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=14.0.0" } @@ -14694,7 +14662,6 @@ "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=14.0.0" } @@ -14989,6 +14956,7 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15374,6 +15342,7 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -15791,7 +15760,6 @@ "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, @@ -15836,6 +15804,7 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -15986,6 +15955,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/frontend/src/components/projects/NewProjectModal.tsx b/frontend/src/components/projects/NewProjectModal.tsx index d9887a929e..bfd4a19346 100644 --- a/frontend/src/components/projects/NewProjectModal.tsx +++ b/frontend/src/components/projects/NewProjectModal.tsx @@ -66,7 +66,7 @@ const PROJECT_TYPE_MENU_ITEMS = [ value: ProjectType.SecretManager }, { - label: "Certificates Management", + label: "Certificate Manager", value: ProjectType.CertificateManager }, { diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/OctopusDeploySyncFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/OctopusDeploySyncFields.tsx new file mode 100644 index 0000000000..a8e1ce41fd --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/OctopusDeploySyncFields.tsx @@ -0,0 +1,460 @@ +import { Controller, useFormContext, useWatch } from "react-hook-form"; +import { MultiValue, SingleValue } from "react-select"; +import { faCircleInfo } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { SecretSyncConnectionField } from "@app/components/secret-syncs/forms/SecretSyncConnectionField"; +import { + FilterableSelect, + FormControl, + Select, + SelectItem, + Tab, + TabList, + TabPanel, + Tabs, + Tooltip +} from "@app/components/v2"; +import { + useOctopusDeployConnectionGetScopeValues, + useOctopusDeployConnectionListProjects, + useOctopusDeployConnectionListSpaces +} from "@app/hooks/api/appConnections/octopus-deploy/queries"; +import { + TOctopusDeployProject, + TOctopusDeploySpace, + TScopeValueOption +} from "@app/hooks/api/appConnections/octopus-deploy/types"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { OctopusDeploySyncScope } from "@app/hooks/api/secretSyncs/types/octopus-deploy-sync"; + +import { TSecretSyncForm } from "../schemas"; + +const EMPTY_SCOPE_VALUES = { + environments: [], + roles: [], + processes: [], + actions: [], + machines: [], + channels: [] +}; + +export const OctopusDeploySyncFields = () => { + const { control, setValue } = useFormContext< + TSecretSyncForm & { destination: SecretSync.OctopusDeploy } + >(); + + const connectionId = useWatch({ name: "connection.id", control }); + const spaceId = useWatch({ name: "destinationConfig.spaceId", control }); + const scope = useWatch({ name: "destinationConfig.scope", control }); + const projectId = useWatch({ name: "destinationConfig.projectId", control }); + + const { data: spaces = [], isLoading: isSpacesLoading } = useOctopusDeployConnectionListSpaces( + connectionId, + { + enabled: Boolean(connectionId) + } + ); + + const { data: projects = [], isLoading: isProjectsLoading } = + useOctopusDeployConnectionListProjects(connectionId, spaceId, { + enabled: Boolean(connectionId && spaceId && scope) + }); + + const { data: scopeValuesData, isLoading: isScopeValuesLoading } = + useOctopusDeployConnectionGetScopeValues(connectionId, spaceId, projectId, { + enabled: Boolean(connectionId && spaceId && projectId && scope) + }); + + return ( + <> + { + setValue("destinationConfig.spaceId", ""); + setValue("destinationConfig.spaceName", ""); + setValue("destinationConfig.projectId", ""); + setValue("destinationConfig.projectName", ""); + setValue("destinationConfig.scopeValues", EMPTY_SCOPE_VALUES); + }} + /> + + + + General + Advanced + + + +
+ ( + +
+ Don't see the space you're looking for?{" "} + +
+ + } + > + space.id === value) ?? null} + onChange={(option) => { + const selectedSpace = option as SingleValue; + onChange(selectedSpace?.id ?? null); + setValue("destinationConfig.spaceName", selectedSpace?.name ?? ""); + setValue("destinationConfig.projectId", ""); + setValue("destinationConfig.projectName", ""); + setValue("destinationConfig.scopeValues", EMPTY_SCOPE_VALUES); + }} + options={spaces} + placeholder={spaces?.length ? "Select a space..." : "No spaces found..."} + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> +
+ )} + /> + + ( + + + + )} + /> + + {scope === OctopusDeploySyncScope.Project && ( + ( + +
+ Don't see the project you're looking for?{" "} + +
+ + } + > + project.id === value) ?? null} + onChange={(option) => { + const selectedProject = option as SingleValue; + onChange(selectedProject?.id ?? null); + setValue("destinationConfig.projectName", selectedProject?.name ?? ""); + setValue("destinationConfig.scopeValues", EMPTY_SCOPE_VALUES); + }} + options={projects} + placeholder={ + spaceId && projects?.length ? "Select a project..." : "No projects found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> +
+ )} + /> + )} +
+
+ + + {scope === OctopusDeploySyncScope.Project && projectId ? ( +
+ {/* Environments */} + ( + + + (value || []).includes(opt.id) + ) || [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.environments || []} + placeholder={ + scopeValuesData?.environments?.length + ? "Select environments..." + : "No environments found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> + + {/* Target Tags */} + ( + + (value || []).includes(opt.id)) || + [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.roles || []} + placeholder={ + scopeValuesData?.roles?.length + ? "Select target tags..." + : "No target tags found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> + + {/* Targets */} + ( + + + (value || []).includes(opt.id) + ) || [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.machines || []} + placeholder={ + scopeValuesData?.machines?.length + ? "Select targets..." + : "No targets found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> + {/* Processes */} + ( + + + (value || []).includes(opt.id) + ) || [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.processes || []} + placeholder={ + scopeValuesData?.processes?.length + ? "Select processes..." + : "No processes found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> + + {/* Deployment Steps */} + ( + + (value || []).includes(opt.id)) || + [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.actions || []} + placeholder={ + scopeValuesData?.actions?.length + ? "Select deployment steps..." + : "No deployment steps found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> + + {/* Channels */} + ( + + + (value || []).includes(opt.id) + ) || [] + } + onChange={(options) => { + const selectedIds = (options as MultiValue).map( + (opt) => opt.id + ); + onChange(selectedIds); + }} + options={scopeValuesData?.channels || []} + placeholder={ + scopeValuesData?.channels?.length + ? "Select channels..." + : "No channels found..." + } + getOptionLabel={(option) => option.name} + getOptionValue={(option) => option.id} + /> + + )} + /> +
+ ) : ( +
+ Please select a project in the Config tab to configure scope values. +
+ )} +
+
+ + ); +}; diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx index 50fee8b9b1..8de021a99e 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/SecretSyncDestinationFields.tsx @@ -28,6 +28,7 @@ import { LaravelForgeSyncFields } from "./LaravelForgeSyncFields"; import { NetlifySyncFields } from "./NetlifySyncFields"; import { NorthflankSyncFields } from "./NorthflankSyncFields"; import { OCIVaultSyncFields } from "./OCIVaultSyncFields"; +import { OctopusDeploySyncFields } from "./OctopusDeploySyncFields"; import { RailwaySyncFields } from "./RailwaySyncFields"; import { RenderSyncFields } from "./RenderSyncFields"; import { SupabaseSyncFields } from "./SupabaseSyncFields"; @@ -109,6 +110,8 @@ export const SecretSyncDestinationFields = () => { return ; case SecretSync.Northflank: return ; + case SecretSync.OctopusDeploy: + return ; default: throw new Error(`Unhandled Destination Config Field: ${destination}`); } diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx index 506c81a212..743f45a5ec 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncOptionsFields/SecretSyncOptionsFields.tsx @@ -9,7 +9,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FormControl, Input, Select, SelectItem, Switch, Tooltip } from "@app/components/v2"; import { SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP, SECRET_SYNC_MAP } from "@app/helpers/secretSyncs"; -import { SecretSync, useSecretSyncOption } from "@app/hooks/api/secretSyncs"; +import { + SecretSync, + SecretSyncInitialSyncBehavior, + useSecretSyncOption +} from "@app/hooks/api/secretSyncs"; import { TSecretSyncForm } from "../schemas"; import { AwsParameterStoreSyncOptionsFields } from "./AwsParameterStoreSyncOptionsFields"; @@ -72,6 +76,7 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => { case SecretSync.Bitbucket: case SecretSync.LaravelForge: case SecretSync.Chef: + case SecretSync.OctopusDeploy: AdditionalSyncOptionsFieldsComponent = null; break; default: @@ -139,13 +144,25 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => { )} /> - {!syncOption?.canImportSecrets && ( + {!syncOption?.canImportSecrets ? (

{destinationName} only supports overwriting destination secrets.{" "} {!currentSyncOption.disableSecretDeletion && - "Secrets not present in Infisical will be removed from the destination."} + `Secrets not present in Infisical will be removed from the destination. Consider adding a key schema or disabling secret deletion if you do not want existing secrets to be removed from ${destinationName}.`}

+ ) : ( + currentSyncOption.initialSyncBehavior === + SecretSyncInitialSyncBehavior.OverwriteDestination && + !currentSyncOption.disableSecretDeletion && ( +

+ + Secrets not present in Infisical will be removed from the destination. If you have + secrets in {destinationName} that you do not want deleted, consider setting initial + sync behavior to import destination secrets. Alternatively, configure a key schema + or disable secret deletion below to have Infisical ignore these secrets. +

+ ) )} )} @@ -183,26 +200,26 @@ export const SecretSyncOptionsFields = ({ hideInitialSync }: Props) => { className="max-w-md" content={ - We highly recommend using a{" "} + We highly recommend configuring a{" "} - Key Schema + key schema {" "} - to ensure that Infisical only manages the specific keys you intend, keeping - everything else untouched. + to ensure that Infisical only manages secrets in {destinationName} that match + the key pattern.

Destination secrets that do not match the schema will not be deleted or updated.
} > -
- Infisical strongly advises setting a Key Schema{" "} - +
+ Infisical strongly advises configuring a key schema{" "} +
} diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/OctopusDeploySyncReviewFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/OctopusDeploySyncReviewFields.tsx new file mode 100644 index 0000000000..a7dae3ceb7 --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/OctopusDeploySyncReviewFields.tsx @@ -0,0 +1,92 @@ +import { useFormContext } from "react-hook-form"; + +import { GenericFieldLabel } from "@app/components/secret-syncs"; +import { TSecretSyncForm } from "@app/components/secret-syncs/forms/schemas"; +import { useOctopusDeployConnectionGetScopeValues } from "@app/hooks/api/appConnections/octopus-deploy"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { OctopusDeploySyncScope } from "@app/hooks/api/secretSyncs/types/octopus-deploy-sync"; + +export const OctopusDeploySyncReviewFields = () => { + const { watch } = useFormContext(); + const { spaceName, spaceId, projectId, projectName, scopeValues, scope } = + watch("destinationConfig"); + const connectionId = watch("connection.id"); + + const { data: scopeValuesData } = useOctopusDeployConnectionGetScopeValues( + connectionId, + spaceId, + projectId, + { + enabled: Boolean(connectionId && spaceId && projectId && scope) + } + ); + + const { + environments = [], + channels = [], + processes = [], + roles = [], + actions = [], + machines = [] + } = scopeValues ?? {}; + + return ( + <> + {spaceName || spaceId} + + {scope} + + {scope === OctopusDeploySyncScope.Project && ( + {projectName || projectId} + )} + {environments.length > 0 && ( + + {scopeValuesData?.environments + .filter((env) => environments.includes(env.id)) + .map((env) => env.name) + .join(", ") ?? environments.join(", ")} + + )} + {roles.length > 0 && ( + + {scopeValuesData?.roles + .filter((role) => roles.includes(role.id)) + .map((role) => role.name) + .join(", ") ?? roles.join(", ")} + + )} + {machines.length > 0 && ( + + {scopeValuesData?.machines + .filter((machine) => machines.includes(machine.id)) + .map((machine) => machine.name) + .join(", ") ?? machines.join(", ")} + + )} + {processes.length > 0 && ( + + {scopeValuesData?.processes + .filter((process) => processes.includes(process.id)) + .map((process) => process.name) + .join(", ") ?? processes.join(", ")} + + )} + {actions.length > 0 && ( + + {scopeValuesData?.actions + .filter((action) => actions.includes(action.id)) + .map((action) => action.name) + .join(", ") ?? actions.join(", ")} + + )} + {channels.length > 0 && ( + + {scopeValuesData?.channels + .filter((channel) => channels.includes(channel.id)) + .map((channel) => channel.name) + .join(", ") ?? channels.join(", ")} + + )} + + ); +}; diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx index 940b3c173e..080022831f 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncReviewFields/SecretSyncReviewFields.tsx @@ -40,6 +40,7 @@ import { LaravelForgeSyncReviewFields } from "./LaravelForgeSyncReviewFields"; import { NetlifySyncReviewFields } from "./NetlifySyncReviewFields"; import { NorthflankSyncReviewFields } from "./NorthflankSyncReviewFields"; import { OCIVaultSyncReviewFields } from "./OCIVaultSyncReviewFields"; +import { OctopusDeploySyncReviewFields } from "./OctopusDeploySyncReviewFields"; import { OnePassSyncReviewFields } from "./OnePassSyncReviewFields"; import { RailwaySyncReviewFields } from "./RailwaySyncReviewFields"; import { RenderSyncOptionsReviewFields, RenderSyncReviewFields } from "./RenderSyncReviewFields"; @@ -181,6 +182,9 @@ export const SecretSyncReviewFields = () => { case SecretSync.Chef: DestinationFieldsComponent = ; break; + case SecretSync.OctopusDeploy: + DestinationFieldsComponent = ; + break; default: throw new Error(`Unhandled Destination Review Fields: ${destination}`); } diff --git a/frontend/src/components/secret-syncs/forms/schemas/octopus-deploy-sync-destination-schema.ts b/frontend/src/components/secret-syncs/forms/schemas/octopus-deploy-sync-destination-schema.ts new file mode 100644 index 0000000000..4c5daf357b --- /dev/null +++ b/frontend/src/components/secret-syncs/forms/schemas/octopus-deploy-sync-destination-schema.ts @@ -0,0 +1,34 @@ +import { z } from "zod"; + +import { BaseSecretSyncSchema } from "@app/components/secret-syncs/forms/schemas/base-secret-sync-schema"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { OctopusDeploySyncScope } from "@app/hooks/api/secretSyncs/types/octopus-deploy-sync"; + +export const OctopusDeploySyncDestinationSchema = BaseSecretSyncSchema().merge( + z.object({ + destination: z.literal(SecretSync.OctopusDeploy), + destinationConfig: z.intersection( + z.object({ + spaceId: z.string().trim().min(1, { message: "Space ID is required" }), + spaceName: z.string().trim().min(1, { message: "Space Name is required" }) + }), + z.discriminatedUnion("scope", [ + z.object({ + scope: z.literal(OctopusDeploySyncScope.Project), + projectId: z.string().trim().min(1, { message: "Project ID is required" }), + projectName: z.string().trim().min(1, { message: "Project Name is required" }), + scopeValues: z + .object({ + environments: z.array(z.string()).optional(), + roles: z.array(z.string()).optional(), + machines: z.array(z.string()).optional(), + processes: z.array(z.string()).optional(), + actions: z.array(z.string()).optional(), + channels: z.array(z.string()).optional() + }) + .optional() + }) + ]) + ) + }) +); diff --git a/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts b/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts index 561191da0c..d86e3d4738 100644 --- a/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts +++ b/frontend/src/components/secret-syncs/forms/schemas/secret-sync-schema.ts @@ -25,6 +25,7 @@ import { LaravelForgeSyncDestinationSchema } from "./laravel-forge-sync-destinat import { NetlifySyncDestinationSchema } from "./netlify-sync-destination-schema"; import { NorthflankSyncDestinationSchema } from "./northflank-sync-destination-schema"; import { OCIVaultSyncDestinationSchema } from "./oci-vault-sync-destination-schema"; +import { OctopusDeploySyncDestinationSchema } from "./octopus-deploy-sync-destination-schema"; import { RailwaySyncDestinationSchema } from "./railway-sync-destination-schema"; import { RenderSyncDestinationSchema } from "./render-sync-destination-schema"; import { SupabaseSyncDestinationSchema } from "./supabase-sync-destination-schema"; @@ -65,6 +66,7 @@ const SecretSyncUnionSchema = z.discriminatedUnion("destination", [ DigitalOceanAppPlatformSyncDestinationSchema, NetlifySyncDestinationSchema, NorthflankSyncDestinationSchema, + OctopusDeploySyncDestinationSchema, BitbucketSyncDestinationSchema, LaravelForgeSyncDestinationSchema, ChefSyncDestinationSchema diff --git a/frontend/src/components/utilities/serialNumberUtils.tsx b/frontend/src/components/utilities/serialNumberUtils.tsx new file mode 100644 index 0000000000..9dc3d69d91 --- /dev/null +++ b/frontend/src/components/utilities/serialNumberUtils.tsx @@ -0,0 +1,15 @@ +export const truncateSerialNumber = (serialNumber: string | null | undefined): string => { + if (!serialNumber || typeof serialNumber !== "string") { + return "—"; + } + + // If serial number is 8 characters or less, show it in full + if (serialNumber.length <= 8) { + return serialNumber; + } + + // Show first 4 + "..." + last 4 + const first4 = serialNumber.substring(0, 4); + const last4 = serialNumber.substring(serialNumber.length - 4); + return `${first4}...${last4}`; +}; diff --git a/frontend/src/components/v2/PageHeader/PageHeader.tsx b/frontend/src/components/v2/PageHeader/PageHeader.tsx index 05e0c131bf..ffe4c9daee 100644 --- a/frontend/src/components/v2/PageHeader/PageHeader.tsx +++ b/frontend/src/components/v2/PageHeader/PageHeader.tsx @@ -32,7 +32,7 @@ export const PageHeader = ({ title, description, children, className, scope }: P

{ @@ -221,6 +223,8 @@ export const getAppConnectionMethodDetails = (method: TAppConnection["method"]) return { name: "Certificate", icon: faCertificate }; case DNSMadeEasyConnectionMethod.APIKeySecret: return { name: "API Key & Secret", icon: faKey }; + case OctopusDeployConnectionMethod.ApiKey: + return { name: "API Key", icon: faKey }; default: throw new Error(`Unhandled App Connection Method: ${method}`); } diff --git a/frontend/src/helpers/project.ts b/frontend/src/helpers/project.ts index 128dd31cea..554d09655b 100644 --- a/frontend/src/helpers/project.ts +++ b/frontend/src/helpers/project.ts @@ -61,7 +61,7 @@ export const getProjectBaseURL = (type: ProjectType) => { case ProjectType.SecretManager: return "/organizations/$orgId/projects/secret-management/$projectId"; case ProjectType.CertificateManager: - return "/organizations/$orgId/projects/cert-management/$projectId"; + return "/organizations/$orgId/projects/cert-manager/$projectId"; default: return `/organizations/$orgId/projects/${type}/$projectId` as const; } @@ -74,7 +74,7 @@ export const getProjectHomePage = (type: ProjectType, environments: ProjectEnv[] case ProjectType.SecretManager: return "/organizations/$orgId/projects/secret-management/$projectId/overview" as const; case ProjectType.CertificateManager: - return "/organizations/$orgId/projects/cert-management/$projectId/policies" as const; + return "/organizations/$orgId/projects/cert-manager/$projectId/policies" as const; case ProjectType.SecretScanning: return `/organizations/$orgId/projects/${type}/$projectId/data-sources` as const; case ProjectType.PAM: @@ -88,7 +88,7 @@ export const getProjectTitle = (type: ProjectType) => { const titleConvert = { [ProjectType.SecretManager]: "Secrets Management", [ProjectType.KMS]: "Key Management", - [ProjectType.CertificateManager]: "Cert Management", + [ProjectType.CertificateManager]: "Certificate Manager", [ProjectType.SSH]: "SSH", [ProjectType.SecretScanning]: "Secret Scanning", [ProjectType.PAM]: "PAM" diff --git a/frontend/src/helpers/secretSyncs.ts b/frontend/src/helpers/secretSyncs.ts index 393aff6449..d2aefc1064 100644 --- a/frontend/src/helpers/secretSyncs.ts +++ b/frontend/src/helpers/secretSyncs.ts @@ -125,6 +125,10 @@ export const SECRET_SYNC_MAP: Record = { [SecretSync.Northflank]: AppConnection.Northflank, [SecretSync.Bitbucket]: AppConnection.Bitbucket, [SecretSync.LaravelForge]: AppConnection.LaravelForge, - [SecretSync.Chef]: AppConnection.Chef + [SecretSync.Chef]: AppConnection.Chef, + [SecretSync.OctopusDeploy]: AppConnection.OctopusDeploy }; export const SECRET_SYNC_INITIAL_SYNC_BEHAVIOR_MAP: Record< diff --git a/frontend/src/hooks/api/appConnections/enums.ts b/frontend/src/hooks/api/appConnections/enums.ts index dbe6c73675..37f85d51ca 100644 --- a/frontend/src/hooks/api/appConnections/enums.ts +++ b/frontend/src/hooks/api/appConnections/enums.ts @@ -42,5 +42,6 @@ export enum AppConnection { Redis = "redis", MongoDB = "mongodb", LaravelForge = "laravel-forge", - Chef = "chef" + Chef = "chef", + OctopusDeploy = "octopus-deploy" } diff --git a/frontend/src/hooks/api/appConnections/octopus-deploy/index.ts b/frontend/src/hooks/api/appConnections/octopus-deploy/index.ts new file mode 100644 index 0000000000..2c1906d369 --- /dev/null +++ b/frontend/src/hooks/api/appConnections/octopus-deploy/index.ts @@ -0,0 +1,2 @@ +export * from "./queries"; +export * from "./types"; diff --git a/frontend/src/hooks/api/appConnections/octopus-deploy/queries.tsx b/frontend/src/hooks/api/appConnections/octopus-deploy/queries.tsx new file mode 100644 index 0000000000..d2654d522d --- /dev/null +++ b/frontend/src/hooks/api/appConnections/octopus-deploy/queries.tsx @@ -0,0 +1,98 @@ +import { useQuery, UseQueryOptions } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; +import { appConnectionKeys } from "@app/hooks/api/appConnections"; + +import { TOctopusDeployProject, TOctopusDeployScopeValues, TOctopusDeploySpace } from "./types"; + +const octopusDeployConnectionKeys = { + all: [...appConnectionKeys.all, "octopus-deploy"] as const, + listSpaces: (connectionId: string) => + [...octopusDeployConnectionKeys.all, "spaces", connectionId] as const, + listProjects: (connectionId: string, spaceId: string) => + [...octopusDeployConnectionKeys.all, "projects", connectionId, spaceId] as const, + getScopeValues: (connectionId: string, spaceId: string, projectId: string) => + [...octopusDeployConnectionKeys.all, "scope-values", connectionId, spaceId, projectId] as const +}; + +export const useOctopusDeployConnectionListSpaces = ( + connectionId: string, + options?: Omit< + UseQueryOptions< + TOctopusDeploySpace[], + unknown, + TOctopusDeploySpace[], + ReturnType + >, + "queryKey" | "queryFn" + > +) => { + return useQuery({ + queryKey: octopusDeployConnectionKeys.listSpaces(connectionId), + queryFn: async () => { + const { data } = await apiRequest.get( + `/api/v1/app-connections/octopus-deploy/${connectionId}/spaces` + ); + + return data; + }, + ...options + }); +}; + +export const useOctopusDeployConnectionListProjects = ( + connectionId: string, + spaceId: string, + options?: Omit< + UseQueryOptions< + TOctopusDeployProject[], + unknown, + TOctopusDeployProject[], + ReturnType + >, + "queryKey" | "queryFn" + > +) => { + return useQuery({ + queryKey: octopusDeployConnectionKeys.listProjects(connectionId, spaceId), + queryFn: async () => { + const { data } = await apiRequest.get( + `/api/v1/app-connections/octopus-deploy/${connectionId}/projects`, + { + params: { spaceId } + } + ); + + return data; + }, + ...options + }); +}; + +export const useOctopusDeployConnectionGetScopeValues = ( + connectionId: string, + spaceId: string, + projectId: string, + options?: Omit< + UseQueryOptions< + TOctopusDeployScopeValues, + unknown, + TOctopusDeployScopeValues, + ReturnType + >, + "queryKey" | "queryFn" + > +) => { + return useQuery({ + queryKey: octopusDeployConnectionKeys.getScopeValues(connectionId, spaceId, projectId), + queryFn: async () => { + const { data } = await apiRequest.get( + `/api/v1/app-connections/octopus-deploy/${connectionId}/scope-values`, + { params: { spaceId, projectId } } + ); + + return data; + }, + ...options + }); +}; diff --git a/frontend/src/hooks/api/appConnections/octopus-deploy/types.ts b/frontend/src/hooks/api/appConnections/octopus-deploy/types.ts new file mode 100644 index 0000000000..45681ad24b --- /dev/null +++ b/frontend/src/hooks/api/appConnections/octopus-deploy/types.ts @@ -0,0 +1,26 @@ +export type TOctopusDeploySpace = { + id: string; + name: string; + slug: string; + isDefault: boolean; +}; + +export type TOctopusDeployProject = { + id: string; + name: string; + slug: string; +}; + +export type TOctopusDeployScopeValues = { + environments: { id: string; name: string }[]; + roles: { id: string; name: string }[]; + machines: { id: string; name: string }[]; + processes: { id: string; name: string }[]; + actions: { id: string; name: string }[]; + channels: { id: string; name: string }[]; +}; + +export type TScopeValueOption = { + id: string; + name: string; +}; diff --git a/frontend/src/hooks/api/appConnections/types/app-options.ts b/frontend/src/hooks/api/appConnections/types/app-options.ts index 9c0f78a0c0..1f7df908b3 100644 --- a/frontend/src/hooks/api/appConnections/types/app-options.ts +++ b/frontend/src/hooks/api/appConnections/types/app-options.ts @@ -94,6 +94,10 @@ export type THCVaultConnectionOption = TAppConnectionOptionBase & { app: AppConnection.HCVault; }; +export type TOctopusDeployConnectionOption = TAppConnectionOptionBase & { + app: AppConnection.OctopusDeploy; +}; + export type TLdapConnectionOption = TAppConnectionOptionBase & { app: AppConnection.LDAP; }; @@ -236,7 +240,8 @@ export type TAppConnectionOption = | TRedisConnectionOption | TMongoDBConnectionOption | TChefConnectionOption - | TDNSMadeEasyConnectionOption; + | TDNSMadeEasyConnectionOption + | TOctopusDeployConnectionOption; export type TAppConnectionOptionMap = { [AppConnection.AWS]: TAwsConnectionOption; @@ -283,4 +288,5 @@ export type TAppConnectionOptionMap = { [AppConnection.MongoDB]: TMongoDBConnectionOption; [AppConnection.LaravelForge]: TLaravelForgeConnectionOption; [AppConnection.Chef]: TChefConnectionOption; + [AppConnection.OctopusDeploy]: TOctopusDeployConnectionOption; }; diff --git a/frontend/src/hooks/api/appConnections/types/index.ts b/frontend/src/hooks/api/appConnections/types/index.ts index c78d2aed2c..2644282393 100644 --- a/frontend/src/hooks/api/appConnections/types/index.ts +++ b/frontend/src/hooks/api/appConnections/types/index.ts @@ -32,6 +32,7 @@ import { TMySqlConnection } from "./mysql-connection"; import { TNetlifyConnection } from "./netlify-connection"; import { TNorthflankConnection } from "./northflank-connection"; import { TOCIConnection } from "./oci-connection"; +import { TOctopusDeployConnection } from "./octopus-deploy-connection"; import { TOktaConnection } from "./okta-connection"; import { TOracleDBConnection } from "./oracledb-connection"; import { TPostgresConnection } from "./postgres-connection"; @@ -76,6 +77,7 @@ export * from "./mysql-connection"; export * from "./netlify-connection"; export * from "./northflank-connection"; export * from "./oci-connection"; +export * from "./octopus-deploy-connection"; export * from "./okta-connection"; export * from "./oracledb-connection"; export * from "./postgres-connection"; @@ -117,6 +119,7 @@ export type TAppConnection = | TOnePassConnection | THerokuConnection | TLaravelForgeConnection + | TOctopusDeployConnection | TRenderConnection | TFlyioConnection | TGitLabConnection diff --git a/frontend/src/hooks/api/appConnections/types/octopus-deploy-connection.ts b/frontend/src/hooks/api/appConnections/types/octopus-deploy-connection.ts new file mode 100644 index 0000000000..15e0835c00 --- /dev/null +++ b/frontend/src/hooks/api/appConnections/types/octopus-deploy-connection.ts @@ -0,0 +1,14 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { TRootAppConnection } from "@app/hooks/api/appConnections/types/root-connection"; + +export enum OctopusDeployConnectionMethod { + ApiKey = "api-key" +} + +export type TOctopusDeployConnection = TRootAppConnection & { app: AppConnection.OctopusDeploy } & { + method: OctopusDeployConnectionMethod.ApiKey; + credentials: { + instanceUrl: string; + apiKey: string; + }; +}; diff --git a/frontend/src/hooks/api/approvalPolicies/index.tsx b/frontend/src/hooks/api/approvalPolicies/index.tsx index 303a09844c..cbd709b18e 100644 --- a/frontend/src/hooks/api/approvalPolicies/index.tsx +++ b/frontend/src/hooks/api/approvalPolicies/index.tsx @@ -1,4 +1,5 @@ export { + useCheckPolicyMatch, useCreateApprovalPolicy, useDeleteApprovalPolicy, useUpdateApprovalPolicy @@ -11,6 +12,8 @@ export { type PamAccessPolicyConditions, type PamAccessPolicyConstraints, type TApprovalPolicy, + type TCheckPolicyMatchDTO, + type TCheckPolicyMatchResult, type TCreateApprovalPolicyDTO, type TDeleteApprovalPolicyDTO, type TGetApprovalPolicyByIdDTO, diff --git a/frontend/src/hooks/api/approvalPolicies/mutations.tsx b/frontend/src/hooks/api/approvalPolicies/mutations.tsx index ca9aae0fcf..5d8cf03a7a 100644 --- a/frontend/src/hooks/api/approvalPolicies/mutations.tsx +++ b/frontend/src/hooks/api/approvalPolicies/mutations.tsx @@ -5,6 +5,8 @@ import { apiRequest } from "@app/config/request"; import { approvalPolicyQuery } from "./queries"; import { TApprovalPolicy, + TCheckPolicyMatchDTO, + TCheckPolicyMatchResult, TCreateApprovalPolicyDTO, TDeleteApprovalPolicyDTO, TUpdateApprovalPolicyDTO @@ -56,3 +58,15 @@ export const useDeleteApprovalPolicy = () => { } }); }; + +export const useCheckPolicyMatch = () => { + return useMutation({ + mutationFn: async ({ policyType, projectId, inputs }: TCheckPolicyMatchDTO) => { + const { data } = await apiRequest.post( + `/api/v1/approval-policies/${policyType}/check-policy-match`, + { projectId, inputs } + ); + return data; + } + }); +}; diff --git a/frontend/src/hooks/api/approvalPolicies/types.ts b/frontend/src/hooks/api/approvalPolicies/types.ts index 8fb461814e..1f389f0175 100644 --- a/frontend/src/hooks/api/approvalPolicies/types.ts +++ b/frontend/src/hooks/api/approvalPolicies/types.ts @@ -81,3 +81,14 @@ export type TDeleteApprovalPolicyDTO = { policyType: ApprovalPolicyType; policyId: string; }; + +export type TCheckPolicyMatchDTO = { + policyType: ApprovalPolicyType; + projectId: string; + inputs: { accountPath: string }; +}; + +export type TCheckPolicyMatchResult = { + requiresApproval: boolean; + hasActiveGrant: boolean; +}; diff --git a/frontend/src/hooks/api/auditLogs/constants.tsx b/frontend/src/hooks/api/auditLogs/constants.tsx index 3ace3f841b..888bb05f30 100644 --- a/frontend/src/hooks/api/auditLogs/constants.tsx +++ b/frontend/src/hooks/api/auditLogs/constants.tsx @@ -122,8 +122,8 @@ export const eventToNameMap: { [K in EventType]: string } = { [EventType.CMEK_LIST_SIGNING_ALGORITHMS]: "List signing algorithms for KMS key", [EventType.CMEK_GET_PUBLIC_KEY]: "Get public key for KMS key", [EventType.UPDATE_EXTERNAL_GROUP_ORG_ROLE_MAPPINGS]: - "Update SSO group to organization role mapping", - [EventType.GET_EXTERNAL_GROUP_ORG_ROLE_MAPPINGS]: "List SSO group to organization role mapping", + "Update SCIM group to organization role mapping", + [EventType.GET_EXTERNAL_GROUP_ORG_ROLE_MAPPINGS]: "List SCIM group to organization role mapping", [EventType.GET_PROJECT_TEMPLATES]: "List project templates", [EventType.GET_PROJECT_TEMPLATE]: "Get project template", [EventType.CREATE_PROJECT_TEMPLATE]: "Create project template", @@ -306,7 +306,19 @@ export const eventToNameMap: { [K in EventType]: string } = { [EventType.APPROVAL_REQUEST_CANCEL]: "Cancel Approval Request", [EventType.APPROVAL_REQUEST_GRANT_LIST]: "List Approval Request Grants", [EventType.APPROVAL_REQUEST_GRANT_GET]: "Get Approval Request Grant", - [EventType.APPROVAL_REQUEST_GRANT_REVOKE]: "Revoke Approval Request Grant" + [EventType.APPROVAL_REQUEST_GRANT_REVOKE]: "Revoke Approval Request Grant", + + [EventType.CREATE_DYNAMIC_SECRET]: "Create Dynamic Secret", + [EventType.UPDATE_DYNAMIC_SECRET]: "Update Dynamic Secret", + [EventType.DELETE_DYNAMIC_SECRET]: "Delete Dynamic Secret", + [EventType.GET_DYNAMIC_SECRET]: "Get Dynamic Secret", + [EventType.LIST_DYNAMIC_SECRETS]: "List Dynamic Secrets", + + [EventType.CREATE_DYNAMIC_SECRET_LEASE]: "Create Dynamic Secret Lease", + [EventType.DELETE_DYNAMIC_SECRET_LEASE]: "Delete Dynamic Secret Lease", + [EventType.RENEW_DYNAMIC_SECRET_LEASE]: "Renew Dynamic Secret Lease", + [EventType.LIST_DYNAMIC_SECRET_LEASES]: "List Dynamic Secret Leases", + [EventType.GET_DYNAMIC_SECRET_LEASE]: "Get Dynamic Secret Lease" }; export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = { diff --git a/frontend/src/hooks/api/auditLogs/enums.tsx b/frontend/src/hooks/api/auditLogs/enums.tsx index b3be5a6fdd..d83fc5e28b 100644 --- a/frontend/src/hooks/api/auditLogs/enums.tsx +++ b/frontend/src/hooks/api/auditLogs/enums.tsx @@ -4,6 +4,8 @@ export enum ActorType { USER = "user", SERVICE = "service", IDENTITY = "identity", + ACME_PROFILE = "acmeProfile", + ACME_ACCOUNT = "acmeAccount", UNKNOWN_USER = "unknownUser" } @@ -297,5 +299,19 @@ export enum EventType { APPROVAL_REQUEST_CANCEL = "approval-request-cancel", APPROVAL_REQUEST_GRANT_LIST = "approval-request-grant-list", APPROVAL_REQUEST_GRANT_GET = "approval-request-grant-get", - APPROVAL_REQUEST_GRANT_REVOKE = "approval-request-grant-revoke" + APPROVAL_REQUEST_GRANT_REVOKE = "approval-request-grant-revoke", + + // Dynamic Secrets + CREATE_DYNAMIC_SECRET = "create-dynamic-secret", + UPDATE_DYNAMIC_SECRET = "update-dynamic-secret", + DELETE_DYNAMIC_SECRET = "delete-dynamic-secret", + GET_DYNAMIC_SECRET = "get-dynamic-secret", + LIST_DYNAMIC_SECRETS = "list-dynamic-secrets", + + // Dynamic Secret Leases + CREATE_DYNAMIC_SECRET_LEASE = "create-dynamic-secret-lease", + DELETE_DYNAMIC_SECRET_LEASE = "delete-dynamic-secret-lease", + RENEW_DYNAMIC_SECRET_LEASE = "renew-dynamic-secret-lease", + LIST_DYNAMIC_SECRET_LEASES = "list-dynamic-secret-leases", + GET_DYNAMIC_SECRET_LEASE = "get-dynamic-secret-lease" } diff --git a/frontend/src/hooks/api/auditLogs/types.tsx b/frontend/src/hooks/api/auditLogs/types.tsx index fc15b5064a..6e0eb22f3e 100644 --- a/frontend/src/hooks/api/auditLogs/types.tsx +++ b/frontend/src/hooks/api/auditLogs/types.tsx @@ -38,6 +38,13 @@ interface KmipClientActorMetadata { name: string; } +interface AcmeAccountActorMetadata { + profileId: string; + accountId: string; +} +interface AcmeProfileActorMetadata { + profileId: string; +} interface UserActor { type: ActorType.USER; metadata: UserActorMetadata; @@ -67,13 +74,25 @@ export interface UnknownUserActor { type: ActorType.UNKNOWN_USER; } +export interface AcmeProfileActor { + type: ActorType.ACME_PROFILE; + metadata: AcmeProfileActorMetadata; +} + +export interface AcmeAccountActor { + type: ActorType.ACME_ACCOUNT; + metadata: AcmeAccountActorMetadata; +} + export type Actor = | UserActor | ServiceActor | IdentityActor | PlatformActor | UnknownUserActor - | KmipClientActor; + | KmipClientActor + | AcmeProfileActor + | AcmeAccountActor; interface GetSecretsEvent { type: EventType.GET_SECRETS; diff --git a/frontend/src/hooks/api/certificateProfiles/types.ts b/frontend/src/hooks/api/certificateProfiles/types.ts index a4f6236595..e79c384d31 100644 --- a/frontend/src/hooks/api/certificateProfiles/types.ts +++ b/frontend/src/hooks/api/certificateProfiles/types.ts @@ -62,6 +62,7 @@ export type TCertificateProfileWithDetails = TCertificateProfile & { acmeConfig?: { id: string; directoryUrl: string; + skipDnsOwnershipVerification?: boolean; }; }; diff --git a/frontend/src/hooks/api/certificates/index.tsx b/frontend/src/hooks/api/certificates/index.tsx index bc7f80d2cb..d4b271683f 100644 --- a/frontend/src/hooks/api/certificates/index.tsx +++ b/frontend/src/hooks/api/certificates/index.tsx @@ -7,4 +7,16 @@ export { useRevokeCert, useUpdateRenewalConfig } from "./mutations"; -export { useGetCert, useGetCertBody } from "./queries"; +export { + useGetCert, + useGetCertBody, + useGetCertBundle, + useGetCertificateRequest, + useListCertificateRequests +} from "./queries"; +export type { + TCertificateRequestDetails, + TCertificateRequestListItem, + TListCertificateRequestsParams, + TListCertificateRequestsResponse +} from "./types"; diff --git a/frontend/src/hooks/api/certificates/mutations.tsx b/frontend/src/hooks/api/certificates/mutations.tsx index 03605ac90e..b5ba39ccfe 100644 --- a/frontend/src/hooks/api/certificates/mutations.tsx +++ b/frontend/src/hooks/api/certificates/mutations.tsx @@ -212,6 +212,9 @@ export const useUnifiedCertificateIssuance = () => { queryClient.invalidateQueries({ queryKey: projectKeys.forProjectCertificates(projectSlug) }); + queryClient.invalidateQueries({ + queryKey: ["certificateRequests", "list", projectSlug] + }); } }); }; diff --git a/frontend/src/hooks/api/certificates/queries.tsx b/frontend/src/hooks/api/certificates/queries.tsx index 13245894b5..123bbb7c1d 100644 --- a/frontend/src/hooks/api/certificates/queries.tsx +++ b/frontend/src/hooks/api/certificates/queries.tsx @@ -2,7 +2,12 @@ import { useQuery } from "@tanstack/react-query"; import { apiRequest } from "@app/config/request"; -import { TCertificate } from "./types"; +import { + TCertificate, + TCertificateRequestDetails, + TListCertificateRequestsParams, + TListCertificateRequestsResponse +} from "./types"; export const certKeys = { getCertById: (serialNumber: string) => [{ serialNumber }, "cert"], @@ -11,6 +16,20 @@ export const certKeys = { getCertificateRequest: (requestId: string, projectSlug: string) => [ { requestId, projectSlug }, "certificateRequest" + ], + listCertificateRequests: (params: TListCertificateRequestsParams) => [ + "certificateRequests", + "list", + params.projectSlug, + params.offset, + params.limit, + params.search, + params.status, + params.fromDate, + params.toDate, + params.profileIds, + params.sortBy, + params.sortOrder ] }; @@ -59,3 +78,49 @@ export const useGetCertBundle = (serialNumber: string) => { enabled: Boolean(serialNumber) }); }; + +const DATE_RANGE_DAYS = 90; + +export const useListCertificateRequests = (params: TListCertificateRequestsParams) => { + return useQuery({ + queryKey: certKeys.listCertificateRequests(params), + queryFn: async () => { + const now = Date.now(); + const daysInMs = DATE_RANGE_DAYS * 24 * 60 * 60 * 1000; + + const { data } = await apiRequest.get( + "/api/v1/cert-manager/certificates/certificate-requests", + { + params: { + projectSlug: params.projectSlug, + offset: params.offset, + limit: params.limit, + search: params.search, + status: params.status, + fromDate: (params.fromDate || new Date(now - daysInMs)).toISOString(), + toDate: (params.toDate || new Date(now)).toISOString(), + profileIds: params.profileIds?.join(","), + sortBy: params.sortBy, + sortOrder: params.sortOrder + } + } + ); + return data; + }, + enabled: Boolean(params.projectSlug), + placeholderData: (previousData) => previousData + }); +}; + +export const useGetCertificateRequest = (requestId: string, projectSlug: string) => { + return useQuery({ + queryKey: certKeys.getCertificateRequest(requestId, projectSlug), + queryFn: async () => { + const { data } = await apiRequest.get( + `/api/v1/cert-manager/certificates/certificate-requests/${requestId}?projectSlug=${projectSlug}` + ); + return data; + }, + enabled: Boolean(requestId) && Boolean(projectSlug) + }); +}; diff --git a/frontend/src/hooks/api/certificates/types.ts b/frontend/src/hooks/api/certificates/types.ts index 4d34822b32..97c0725334 100644 --- a/frontend/src/hooks/api/certificates/types.ts +++ b/frontend/src/hooks/api/certificates/types.ts @@ -136,3 +136,40 @@ export type TCertificateRequestDetails = { createdAt: string; updatedAt: string; }; + +export type TCertificateRequestListItem = { + id: string; + status: "pending" | "issued" | "failed"; + commonName: string | null; + altNames: string | null; + profileId: string | null; + profileName: string | null; + caId: string | null; + certificateId: string | null; + errorMessage: string | null; + createdAt: string; + updatedAt: string; + certificate: { + id: string; + serialNumber: string; + status: string; + } | null; +}; + +export type TListCertificateRequestsResponse = { + certificateRequests: TCertificateRequestListItem[]; + totalCount: number; +}; + +export type TListCertificateRequestsParams = { + projectSlug: string; + offset?: number; + limit?: number; + search?: string; + status?: "pending" | "issued" | "failed"; + fromDate?: Date; + toDate?: Date; + profileIds?: string[]; + sortBy?: string; + sortOrder?: "asc" | "desc"; +}; diff --git a/frontend/src/hooks/api/externalGroupOrgRoleMappings/mutations.tsx b/frontend/src/hooks/api/externalGroupOrgRoleMappings/mutations.tsx index ccf4f567db..dbb6450490 100644 --- a/frontend/src/hooks/api/externalGroupOrgRoleMappings/mutations.tsx +++ b/frontend/src/hooks/api/externalGroupOrgRoleMappings/mutations.tsx @@ -8,7 +8,7 @@ export const useUpdateExternalGroupOrgRoleMappings = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload: TSyncExternalGroupOrgRoleMappingsDTO) => { - const { data } = await apiRequest.put("/api/v1/external-group-mappings", payload); + const { data } = await apiRequest.put("/api/v1/scim/group-org-role-mappings", payload); return data; }, diff --git a/frontend/src/hooks/api/externalGroupOrgRoleMappings/queries.tsx b/frontend/src/hooks/api/externalGroupOrgRoleMappings/queries.tsx index 620ec0447b..345dc8f16c 100644 --- a/frontend/src/hooks/api/externalGroupOrgRoleMappings/queries.tsx +++ b/frontend/src/hooks/api/externalGroupOrgRoleMappings/queries.tsx @@ -23,7 +23,7 @@ export const useGetExternalGroupOrgRoleMappings = ( queryKey: externalGroupOrgRoleMappingKeys.list(), queryFn: async () => { const { data } = await apiRequest.get( - "/api/v1/external-group-mappings" + "/api/v1/scim/group-org-role-mappings" ); return data; diff --git a/frontend/src/hooks/api/groups/index.tsx b/frontend/src/hooks/api/groups/index.tsx index eebe2ccc3a..b705ec3ade 100644 --- a/frontend/src/hooks/api/groups/index.tsx +++ b/frontend/src/hooks/api/groups/index.tsx @@ -1,8 +1,15 @@ export { + useAddIdentityToGroup, useAddUserToGroup, useCreateGroup, useDeleteGroup, + useRemoveIdentityFromGroup, useRemoveUserFromGroup, useUpdateGroup } from "./mutations"; -export { useGetGroupById, useListGroupProjects, useListGroupUsers } from "./queries"; +export { + useGetGroupById, + useListGroupMachineIdentities, + useListGroupProjects, + useListGroupUsers +} from "./queries"; diff --git a/frontend/src/hooks/api/groups/mutations.tsx b/frontend/src/hooks/api/groups/mutations.tsx index d45971995f..ea5ac22730 100644 --- a/frontend/src/hooks/api/groups/mutations.tsx +++ b/frontend/src/hooks/api/groups/mutations.tsx @@ -5,7 +5,7 @@ import { apiRequest } from "@app/config/request"; import { organizationKeys } from "../organization/queries"; import { userKeys } from "../users/query-keys"; import { groupKeys } from "./queries"; -import { TGroup } from "./types"; +import { TGroup, TGroupMachineIdentity } from "./types"; export const useCreateGroup = () => { const queryClient = useQueryClient(); @@ -95,6 +95,7 @@ export const useAddUserToGroup = () => { }, onSuccess: (_, { slug }) => { queryClient.invalidateQueries({ queryKey: groupKeys.forGroupUserMemberships(slug) }); + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupMembers(slug) }); } }); }; @@ -119,6 +120,55 @@ export const useRemoveUserFromGroup = () => { onSuccess: (_, { slug, username }) => { queryClient.invalidateQueries({ queryKey: groupKeys.forGroupUserMemberships(slug) }); queryClient.invalidateQueries({ queryKey: userKeys.listUserGroupMemberships(username) }); + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupMembers(slug) }); + } + }); +}; + +export const useAddIdentityToGroup = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ + groupId, + identityId + }: { + groupId: string; + identityId: string; + slug: string; + }) => { + const { data } = await apiRequest.post>( + `/api/v1/groups/${groupId}/machine-identities/${identityId}` + ); + + return data; + }, + onSuccess: (_, { slug }) => { + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupIdentitiesMemberships(slug) }); + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupMembers(slug) }); + } + }); +}; + +export const useRemoveIdentityFromGroup = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ + groupId, + identityId + }: { + groupId: string; + identityId: string; + slug: string; + }) => { + const { data } = await apiRequest.delete>( + `/api/v1/groups/${groupId}/machine-identities/${identityId}` + ); + + return data; + }, + onSuccess: (_, { slug }) => { + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupIdentitiesMemberships(slug) }); + queryClient.invalidateQueries({ queryKey: groupKeys.forGroupMembers(slug) }); } }); }; diff --git a/frontend/src/hooks/api/groups/queries.tsx b/frontend/src/hooks/api/groups/queries.tsx index 2e5b9f6841..cd2b9a00cb 100644 --- a/frontend/src/hooks/api/groups/queries.tsx +++ b/frontend/src/hooks/api/groups/queries.tsx @@ -4,9 +4,14 @@ import { apiRequest } from "@app/config/request"; import { OrderByDirection } from "../generic/types"; import { - EFilterReturnedProjects, - EFilterReturnedUsers, + FilterMemberType, + FilterReturnedMachineIdentities, + FilterReturnedProjects, + FilterReturnedUsers, + GroupMembersOrderBy, TGroup, + TGroupMachineIdentity, + TGroupMember, TGroupProject, TGroupUser } from "./types"; @@ -27,10 +32,12 @@ export const groupKeys = { offset: number; limit: number; search: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedUsers; }) => [...groupKeys.forGroupUserMemberships(slug), { offset, limit, search, filter }] as const, - specificProjectGroupUserMemberships: ({ - projectId, + allGroupIdentitiesMemberships: () => ["group-identities-memberships"] as const, + forGroupIdentitiesMemberships: (slug: string) => + [...groupKeys.allGroupIdentitiesMemberships(), slug] as const, + specificGroupIdentitiesMemberships: ({ slug, offset, limit, @@ -38,16 +45,34 @@ export const groupKeys = { filter }: { slug: string; - projectId: string; offset: number; limit: number; search: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedMachineIdentities; + }) => + [...groupKeys.forGroupIdentitiesMemberships(slug), { offset, limit, search, filter }] as const, + allGroupMembers: () => ["group-members"] as const, + forGroupMembers: (slug: string) => [...groupKeys.allGroupMembers(), slug] as const, + specificGroupMembers: ({ + slug, + offset, + limit, + search, + orderBy, + orderDirection, + memberTypeFilter + }: { + slug: string; + offset: number; + limit: number; + search: string; + orderBy?: GroupMembersOrderBy; + orderDirection?: OrderByDirection; + memberTypeFilter?: FilterMemberType[]; }) => [ - ...groupKeys.forGroupUserMemberships(slug), - projectId, - { offset, limit, search, filter } + ...groupKeys.forGroupMembers(slug), + { offset, limit, search, orderBy, orderDirection, memberTypeFilter } ] as const, allGroupProjects: () => ["group-projects"] as const, forGroupProjects: (groupId: string) => [...groupKeys.allGroupProjects(), groupId] as const, @@ -64,7 +89,7 @@ export const groupKeys = { offset: number; limit: number; search: string; - filter?: EFilterReturnedProjects; + filter?: FilterReturnedProjects; orderBy?: string; orderDirection?: OrderByDirection; }) => @@ -99,7 +124,7 @@ export const useListGroupUsers = ({ offset: number; limit: number; search: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedUsers; }) => { return useQuery({ queryKey: groupKeys.specificGroupUserMemberships({ @@ -115,7 +140,7 @@ export const useListGroupUsers = ({ const params = new URLSearchParams({ offset: String(offset), limit: String(limit), - search, + ...(search && { search }), ...(filter && { filter }) }); @@ -131,9 +156,66 @@ export const useListGroupUsers = ({ }); }; -export const useListProjectGroupUsers = ({ +export const useListGroupMembers = ({ + id, + groupSlug, + offset = 0, + limit = 10, + search, + orderBy, + orderDirection, + memberTypeFilter +}: { + id: string; + groupSlug: string; + offset: number; + limit: number; + search: string; + orderBy?: GroupMembersOrderBy; + orderDirection?: OrderByDirection; + memberTypeFilter?: FilterMemberType[]; +}) => { + return useQuery({ + queryKey: groupKeys.specificGroupMembers({ + slug: groupSlug, + offset, + limit, + search, + orderBy, + orderDirection, + memberTypeFilter + }), + enabled: Boolean(groupSlug), + placeholderData: (previousData) => previousData, + queryFn: async () => { + const params = new URLSearchParams({ + offset: String(offset), + limit: String(limit), + ...(search && { search }), + ...(orderBy && { orderBy: orderBy.toString() }), + ...(orderDirection && { orderDirection }) + }); + + if (memberTypeFilter && memberTypeFilter.length > 0) { + memberTypeFilter.forEach((filter) => { + params.append("memberTypeFilter", filter); + }); + } + + const { data } = await apiRequest.get<{ members: TGroupMember[]; totalCount: number }>( + `/api/v1/groups/${id}/members`, + { + params + } + ); + + return data; + } + }); +}; + +export const useListGroupMachineIdentities = ({ id, - projectId, groupSlug, offset = 0, limit = 10, @@ -142,16 +224,14 @@ export const useListProjectGroupUsers = ({ }: { id: string; groupSlug: string; - projectId: string; offset: number; limit: number; search: string; - filter?: EFilterReturnedUsers; + filter?: FilterReturnedMachineIdentities; }) => { return useQuery({ - queryKey: groupKeys.specificProjectGroupUserMemberships({ + queryKey: groupKeys.specificGroupIdentitiesMemberships({ slug: groupSlug, - projectId, offset, limit, search, @@ -163,16 +243,16 @@ export const useListProjectGroupUsers = ({ const params = new URLSearchParams({ offset: String(offset), limit: String(limit), - search, + ...(search && { search }), ...(filter && { filter }) }); - const { data } = await apiRequest.get<{ users: TGroupUser[]; totalCount: number }>( - `/api/v1/projects/${projectId}/groups/${id}/users`, - { - params - } - ); + const { data } = await apiRequest.get<{ + machineIdentities: TGroupMachineIdentity[]; + totalCount: number; + }>(`/api/v1/groups/${id}/machine-identities`, { + params + }); return data; } @@ -194,7 +274,7 @@ export const useListGroupProjects = ({ search: string; orderBy?: string; orderDirection?: OrderByDirection; - filter?: EFilterReturnedProjects; + filter?: FilterReturnedProjects; }) => { return useQuery({ queryKey: groupKeys.specificGroupProjects({ @@ -212,7 +292,7 @@ export const useListGroupProjects = ({ const params = new URLSearchParams({ offset: String(offset), limit: String(limit), - search, + ...(search && { search }), ...(filter && { filter }), ...(orderBy && { orderBy }), ...(orderDirection && { orderDirection }) diff --git a/frontend/src/hooks/api/groups/types.ts b/frontend/src/hooks/api/groups/types.ts index 1c16a331b6..f5549a3c1d 100644 --- a/frontend/src/hooks/api/groups/types.ts +++ b/frontend/src/hooks/api/groups/types.ts @@ -42,16 +42,59 @@ export type TGroupWithProjectMemberships = { orgId: string; }; +export enum GroupMemberType { + USER = "user", + MACHINE_IDENTITY = "machineIdentity" +} + export type TGroupUser = { id: string; email: string; username: string; firstName: string; lastName: string; - isPartOfGroup: boolean; joinedGroupAt: Date; }; +export type TGroupMachineIdentity = { + id: string; + name: string; + joinedGroupAt: Date; +}; + +export type TGroupMemberUser = { + id: string; + joinedGroupAt: Date; + type: GroupMemberType.USER; + user: { + email: string; + username: string; + firstName: string; + lastName: string; + }; +}; + +export type TGroupMemberMachineIdentity = { + id: string; + joinedGroupAt: Date; + type: GroupMemberType.MACHINE_IDENTITY; + machineIdentity: { + id: string; + name: string; + }; +}; + +export type TGroupMember = TGroupMemberUser | TGroupMemberMachineIdentity; + +export enum GroupMembersOrderBy { + Name = "name" +} + +export enum FilterMemberType { + USERS = "users", + MACHINE_IDENTITIES = "machineIdentities" +} + export type TGroupProject = { id: string; name: string; @@ -61,12 +104,17 @@ export type TGroupProject = { joinedGroupAt: Date; }; -export enum EFilterReturnedUsers { +export enum FilterReturnedUsers { EXISTING_MEMBERS = "existingMembers", NON_MEMBERS = "nonMembers" } -export enum EFilterReturnedProjects { +export enum FilterReturnedMachineIdentities { + ASSIGNED_MACHINE_IDENTITIES = "assignedMachineIdentities", + NON_ASSIGNED_MACHINE_IDENTITIES = "nonAssignedMachineIdentities" +} + +export enum FilterReturnedProjects { ASSIGNED_PROJECTS = "assignedProjects", UNASSIGNED_PROJECTS = "unassignedProjects" } diff --git a/frontend/src/hooks/api/projects/queries.tsx b/frontend/src/hooks/api/projects/queries.tsx index b9748950b7..a8dd35bf23 100644 --- a/frontend/src/hooks/api/projects/queries.tsx +++ b/frontend/src/hooks/api/projects/queries.tsx @@ -516,7 +516,12 @@ export const useListWorkspaceCertificates = ({ limit, friendlyName, commonName, - forPkiSync + forPkiSync, + search, + status, + profileIds, + fromDate, + toDate }: { projectId: string; offset: number; @@ -524,6 +529,11 @@ export const useListWorkspaceCertificates = ({ friendlyName?: string; commonName?: string; forPkiSync?: boolean; + search?: string; + status?: string | string[]; + profileIds?: string[]; + fromDate?: Date; + toDate?: Date; }) => { return useQuery({ queryKey: projectKeys.specificProjectCertificates({ @@ -532,7 +542,12 @@ export const useListWorkspaceCertificates = ({ limit, friendlyName, commonName, - forPkiSync + forPkiSync, + search, + status, + profileIds, + fromDate, + toDate }), queryFn: async () => { const params = new URLSearchParams({ @@ -549,6 +564,29 @@ export const useListWorkspaceCertificates = ({ if (forPkiSync) { params.append("forPkiSync", "true"); } + if (search) { + params.append("search", search); + } + if (status) { + if (Array.isArray(status)) { + status.forEach((statusValue) => { + params.append("status", statusValue); + }); + } else { + params.append("status", status); + } + } + if (fromDate) { + params.append("fromDate", fromDate.toISOString()); + } + if (toDate) { + params.append("toDate", toDate.toISOString()); + } + if (profileIds && profileIds.length > 0) { + profileIds.forEach((id) => { + params.append("profileIds", id); + }); + } const { data: { certificates, totalCount } diff --git a/frontend/src/hooks/api/projects/query-keys.tsx b/frontend/src/hooks/api/projects/query-keys.tsx index 6f74bf6f3f..fdbece632b 100644 --- a/frontend/src/hooks/api/projects/query-keys.tsx +++ b/frontend/src/hooks/api/projects/query-keys.tsx @@ -47,7 +47,12 @@ export const projectKeys = { limit, friendlyName, commonName, - forPkiSync + forPkiSync, + search, + status, + profileIds, + fromDate, + toDate }: { projectId: string; offset: number; @@ -55,10 +60,26 @@ export const projectKeys = { friendlyName?: string; commonName?: string; forPkiSync?: boolean; + search?: string; + status?: string | string[]; + profileIds?: string[]; + fromDate?: Date; + toDate?: Date; }) => [ ...projectKeys.forProjectCertificates(projectId), - { offset, limit, friendlyName, commonName, forPkiSync } + { + offset, + limit, + friendlyName, + commonName, + forPkiSync, + search, + status, + profileIds, + fromDate, + toDate + } ] as const, getProjectPkiAlerts: (projectId: string) => [{ projectId }, "project-pki-alerts"] as const, getProjectPkiSubscribers: (projectId: string) => diff --git a/frontend/src/hooks/api/secretSyncs/enums.ts b/frontend/src/hooks/api/secretSyncs/enums.ts index be51805c85..299eeb9e44 100644 --- a/frontend/src/hooks/api/secretSyncs/enums.ts +++ b/frontend/src/hooks/api/secretSyncs/enums.ts @@ -31,7 +31,8 @@ export enum SecretSync { Northflank = "northflank", Bitbucket = "bitbucket", LaravelForge = "laravel-forge", - Chef = "chef" + Chef = "chef", + OctopusDeploy = "octopus-deploy" } export enum SecretSyncStatus { diff --git a/frontend/src/hooks/api/secretSyncs/types/index.ts b/frontend/src/hooks/api/secretSyncs/types/index.ts index b4088728bd..fc2af7bd6a 100644 --- a/frontend/src/hooks/api/secretSyncs/types/index.ts +++ b/frontend/src/hooks/api/secretSyncs/types/index.ts @@ -26,6 +26,7 @@ import { TLaravelForgeSync } from "./laravel-forge-sync"; import { TNetlifySync } from "./netlify-sync"; import { TNorthflankSync } from "./northflank-sync"; import { TOCIVaultSync } from "./oci-vault-sync"; +import { TOctopusDeploySync } from "./octopus-deploy-sync"; import { TRailwaySync } from "./railway-sync"; import { TRenderSync } from "./render-sync"; import { TSupabaseSync } from "./supabase"; @@ -75,7 +76,8 @@ export type TSecretSync = | TNorthflankSync | TBitbucketSync | TLaravelForgeSync - | TChefSync; + | TChefSync + | TOctopusDeploySync; export type TListSecretSyncs = { secretSyncs: TSecretSync[] }; diff --git a/frontend/src/hooks/api/secretSyncs/types/octopus-deploy-sync.ts b/frontend/src/hooks/api/secretSyncs/types/octopus-deploy-sync.ts new file mode 100644 index 0000000000..21a8c2e0f9 --- /dev/null +++ b/frontend/src/hooks/api/secretSyncs/types/octopus-deploy-sync.ts @@ -0,0 +1,37 @@ +import { AppConnection } from "@app/hooks/api/appConnections/enums"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { TRootSecretSync } from "@app/hooks/api/secretSyncs/types/root-sync"; + +export enum OctopusDeploySyncScope { + Project = "project" +} + +type TOctopusDeploySyncDestinationConfigProject = { + scope: OctopusDeploySyncScope.Project; + projectId: string; + projectName: string; + scopeValues?: { + environments?: string[]; + roles?: string[]; + machines?: string[]; + processes?: string[]; + actions?: string[]; + channels?: string[]; + }; +}; + +type TOctopusDeploySyncDestinationConfig = { + spaceId: string; + spaceName: string; +} & TOctopusDeploySyncDestinationConfigProject; + +export type TOctopusDeploySync = TRootSecretSync & { + destination: SecretSync.OctopusDeploy; + destinationConfig: TOctopusDeploySyncDestinationConfig; + + connection: { + app: AppConnection.OctopusDeploy; + name: string; + id: string; + }; +}; diff --git a/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx b/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx index f3f283a355..814667eff3 100644 --- a/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx +++ b/frontend/src/layouts/PkiManagerLayout/PkiManagerLayout.tsx @@ -43,7 +43,7 @@ export const PkiManagerLayout = () => { { {({ isActive }) => Certificates} { )} { {({ isActive }) => Alerting} { {({ isActive }) => Integrations} { <> {(subscription.pkiLegacyTemplates || hasExistingSubscribers) && ( { )} {(subscription.pkiLegacyTemplates || hasExistingTemplates) && ( { )} { )} { {({ isActive }) => Audit Logs} { navigate({ to: "/admin" }); }; - if (config?.initialized) return ; + if (config?.initialized) { + return ( +
+ +
+ ); + } return (
diff --git a/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx b/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx index 6cc0a208a7..695746b23d 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/AlertingPage.tsx @@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next"; import { ProjectPermissionCan } from "@app/components/permissions"; import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionActions, ProjectPermissionSub, useProject } from "@app/context"; import { useListWorkspacePkiAlerts } from "@app/hooks/api"; import { ProjectType } from "@app/hooks/api/projects/types"; @@ -30,7 +31,14 @@ export const AlertingPage = () => {
+ Alerting + + + + + } description="Configure alerts for expiring certificates and CAs to maintain security and compliance." /> { }); navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId", + to: "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId", params: { orgId: currentOrg.id, projectId, diff --git a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx index 71b57796de..601df6fafa 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/components/PkiCollectionTable.tsx @@ -66,7 +66,7 @@ export const PkiCollectionTable = ({ handlePopUpOpen }: Props) => { key={`pki-collection-${pkiCollection.id}`} onClick={() => navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId", + to: "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId", params: { orgId: currentOrg.id, projectId, diff --git a/frontend/src/pages/cert-manager/AlertingPage/route.tsx b/frontend/src/pages/cert-manager/AlertingPage/route.tsx index 5dc2f3de7d..038e5cb9a4 100644 --- a/frontend/src/pages/cert-manager/AlertingPage/route.tsx +++ b/frontend/src/pages/cert-manager/AlertingPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { AlertingPage } from "./AlertingPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting" )({ component: AlertingPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx index 4f12c39501..4df47af75e 100644 --- a/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/CertAuthDetailsByIDPage/CertAuthDetailsByIDPage.tsx @@ -79,7 +79,7 @@ const Page = () => { handlePopUpClose("deleteCa"); navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities", + to: "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities", params: { orgId: currentOrg.id, projectId @@ -100,7 +100,7 @@ const Page = () => { isAllowed ? (
{ @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Authorities", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities", + to: "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaSection.tsx b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaSection.tsx index 2870f390d4..4b5e38bdf8 100644 --- a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaSection.tsx +++ b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/CaSection.tsx @@ -4,6 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionCertificateAuthorityActions, ProjectPermissionSub, @@ -59,7 +60,10 @@ export const CaSection = () => { return (
-

Internal Certificate Authorities

+
+

Internal Certificate Authorities

+ +
{ onClick={() => canReadCa && navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/ca/$caId", + to: "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId", params: { orgId: currentOrg.id, projectId: currentProject.id, diff --git a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/ExternalCaSection.tsx b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/ExternalCaSection.tsx index b0f963206f..ca9e695ba2 100644 --- a/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/ExternalCaSection.tsx +++ b/frontend/src/pages/cert-manager/CertificateAuthoritiesPage/components/ExternalCaSection.tsx @@ -4,6 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionCertificateAuthorityActions, ProjectPermissionSub, @@ -63,7 +64,10 @@ export const ExternalCaSection = () => { return (
-

External Certificate Authorities

+
+

External Certificate Authorities

+ +
{ diff --git a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx new file mode 100644 index 0000000000..eaddf2752d --- /dev/null +++ b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestRow.tsx @@ -0,0 +1,102 @@ +import { faEllipsis } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { format } from "date-fns"; + +import { getCertificateDisplayName } from "@app/components/utilities/certificateDisplayUtils"; +import { truncateSerialNumber } from "@app/components/utilities/serialNumberUtils"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + IconButton, + Td, + Tooltip, + Tr +} from "@app/components/v2"; +import { Badge } from "@app/components/v3"; +import { TCertificateRequestListItem } from "@app/hooks/api/certificates"; + +type Props = { + request: TCertificateRequestListItem; + onViewCertificates?: (certificateId: string) => void; +}; + +export const CertificateRequestRow = ({ request, onViewCertificates }: Props) => { + const getStatusBadge = (status: string) => { + switch (status.toLowerCase()) { + case "pending": + return Pending; + case "issued": + return Issued; + case "failed": + return Failed; + default: + return {status.charAt(0).toUpperCase() + status.slice(1)}; + } + }; + + const { displayName } = getCertificateDisplayName( + { + altNames: request.altNames, + commonName: request.commonName + }, + 64, + "—" + ); + + return ( + + +
+ {displayName} +
+ + +
+ {truncateSerialNumber(request.certificate?.serialNumber)} +
+ + {getStatusBadge(request.status)} + +
{request.profileName || "N/A"}
+ + + + + + + + + + + + + + + + + + + + request.certificateId && onViewCertificates?.(request.certificateId)} + disabled={!request.certificateId} + className="flex items-center gap-2" + > + View Certificate + + + + + + ); +}; diff --git a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx new file mode 100644 index 0000000000..7b7abf9832 --- /dev/null +++ b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/CertificateRequestsSection.tsx @@ -0,0 +1,373 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ +import { useEffect, useMemo, useState } from "react"; +import { faFilter, faMagnifyingGlass, faPlus } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; + +import { ProjectPermissionCan } from "@app/components/permissions"; +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + FilterableSelect, + IconButton, + Input, + Pagination, + Select, + SelectItem, + Table, + TableContainer, + TableSkeleton, + TBody, + Th, + THead, + Tr +} from "@app/components/v2"; +import { + ProjectPermissionCertificateProfileActions, + ProjectPermissionSub, + useProject +} from "@app/context"; +import { useDebounce, usePopUp } from "@app/hooks"; +import { useListCertificateProfiles } from "@app/hooks/api/certificateProfiles"; +import { + TListCertificateRequestsParams, + useListCertificateRequests +} from "@app/hooks/api/certificates"; + +import { CertificateIssuanceModal } from "../../CertificatesPage/components/CertificateIssuanceModal"; +import { CertificateRequestRow } from "./CertificateRequestRow"; + +const PAGE_SIZE = 20; +const SEARCH_DEBOUNCE_DELAY = 500; + +type CertificateRequestStatus = "pending" | "issued" | "failed"; + +type CertificateRequestFilters = { + status?: CertificateRequestStatus; +}; + +type Props = { + onViewCertificateFromRequest?: (certificateId: string) => void; +}; + +export const CertificateRequestsSection = ({ onViewCertificateFromRequest }: Props) => { + const { currentProject } = useProject(); + + const [pendingSearch, setPendingSearch] = useState(""); + const [pendingProfileIds, setPendingProfileIds] = useState([]); + const [pendingFilters, setPendingFilters] = useState({}); + + const [appliedProfileIds, setAppliedProfileIds] = useState([]); + const [appliedFilters, setAppliedFilters] = useState({}); + + const [currentPage, setCurrentPage] = useState(1); + const [perPage, setPerPage] = useState(PAGE_SIZE); + + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["issueCertificate"] as const); + + const [debouncedSearch, setDebouncedSearch] = useDebounce(pendingSearch, SEARCH_DEBOUNCE_DELAY); + + useEffect(() => { + setCurrentPage(1); + }, [debouncedSearch]); + + const { data: profilesData } = useListCertificateProfiles({ + projectId: currentProject?.id ?? "", + limit: 100 + }); + + const profileIds = useMemo(() => { + return appliedProfileIds.length > 0 ? appliedProfileIds : undefined; + }, [appliedProfileIds]); + + const queryParams: TListCertificateRequestsParams = useMemo( + () => ({ + projectSlug: currentProject?.slug || "", + offset: (currentPage - 1) * perPage, + limit: perPage, + sortBy: "createdAt", + sortOrder: "desc", + ...(debouncedSearch && { search: debouncedSearch }), + ...(appliedFilters.status && { status: appliedFilters.status }), + ...(profileIds && { profileIds }) + }), + [currentProject?.slug, currentPage, perPage, debouncedSearch, appliedFilters.status, profileIds] + ); + + const { + data: certificateRequestsData, + isLoading, + isError + } = useListCertificateRequests(queryParams); + + const handleApplyFilters = () => { + setAppliedFilters(pendingFilters); + setAppliedProfileIds(pendingProfileIds); + setCurrentPage(1); + }; + + const handleClearFilters = () => { + setPendingSearch(""); + setPendingFilters({}); + setPendingProfileIds([]); + setAppliedFilters({}); + setAppliedProfileIds([]); + setDebouncedSearch(""); + setCurrentPage(1); + }; + + const handleClearStatus = () => { + setPendingFilters((prev) => ({ ...prev, status: undefined })); + }; + + const handleClearProfiles = () => { + setPendingProfileIds([]); + }; + + const handleViewCertificates = (certificateId: string) => { + onViewCertificateFromRequest?.(certificateId); + }; + + const isTableFiltered = useMemo( + () => Boolean(appliedFilters.status || appliedProfileIds.length), + [appliedFilters.status, appliedProfileIds.length] + ); + + const hasPendingChanges = useMemo(() => { + const pendingStatus = pendingFilters.status ?? undefined; + const appliedStatus = appliedFilters.status ?? undefined; + const statusChanged = pendingStatus !== appliedStatus; + const profileIdsChanged = + JSON.stringify([...pendingProfileIds].sort()) !== + JSON.stringify([...appliedProfileIds].sort()); + return statusChanged || profileIdsChanged; + }, [pendingFilters.status, appliedFilters.status, pendingProfileIds, appliedProfileIds]); + + return ( +
+
+
+
+

Certificate Requests

+
+
+
+ + {(isAllowed) => ( + + )} + +
+
+ +
+ setPendingSearch(e.target.value)} + leftIcon={} + placeholder="Search by SAN or CN" + className="flex-1" + /> + + + + + + + +
+
+

Filters

+ + {isTableFiltered && ( + + )} + +
+ +
+
+ + Certificate Profiles + + {pendingProfileIds.length > 0 && ( + + )} +
+ ({ + value: id, + label: profilesData?.certificateProfiles?.find((p) => p.id === id)?.slug || id + }))} + onChange={(selectedOptions) => { + const ids = Array.isArray(selectedOptions) + ? selectedOptions.map((opt) => opt.value) + : []; + setPendingProfileIds(ids); + }} + options={ + profilesData?.certificateProfiles?.map((profile) => ({ + value: profile.id, + label: profile.slug + })) || [] + } + placeholder="Select certificate profiles..." + className="w-full border-mineshaft-600 bg-mineshaft-700 text-bunker-200" + isMulti + isLoading={!profilesData} + maxMenuHeight={120} + /> +
+ +
+
+ + {pendingFilters.status && ( + + )} +
+ +
+ +
+ +
+
+
+
+
+ +
+ + + + + + + + + + + + + + {isLoading && } + {isError && ( + + + + )} + {!isLoading && + !isError && + certificateRequestsData?.certificateRequests?.length === 0 && ( + + + + )} + {!isLoading && + !isError && + certificateRequestsData?.certificateRequests?.map((request) => ( + + ))} + +
SAN / CNSERIAL NUMBERSTATUSPROFILECREATED ATUPDATED AT +
+ Failed to load certificate requests. Please try again. +
+ {isTableFiltered + ? "No certificate requests found matching your filters" + : "No certificate requests found"} +
+
+ + {certificateRequestsData && certificateRequestsData.totalCount > 0 && ( +
+ setCurrentPage(page)} + onChangePerPage={(newPerPage) => { + setCurrentPage(1); + setPerPage(newPerPage); + }} + /> +
+ )} +
+ + +
+ ); +}; diff --git a/frontend/src/pages/cert-manager/CertificateRequestsPage/components/index.ts b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/index.ts new file mode 100644 index 0000000000..3e08f9a1dc --- /dev/null +++ b/frontend/src/pages/cert-manager/CertificateRequestsPage/components/index.ts @@ -0,0 +1,2 @@ +export { CertificateRequestRow } from "./CertificateRequestRow"; +export { CertificateRequestsSection } from "./CertificateRequestsSection"; diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesSection.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesSection.tsx index 2c3b00bc23..c4e386406c 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesSection.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesSection.tsx @@ -1,12 +1,12 @@ -import { faArrowRight, faPlus } from "@fortawesome/free-solid-svg-icons"; +import { faArrowRight } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionCertificateActions, - ProjectPermissionCertificateProfileActions, ProjectPermissionSub, useProject } from "@app/context"; @@ -16,14 +16,20 @@ import { usePopUp } from "@app/hooks/usePopUp"; import { CertificateCertModal } from "./CertificateCertModal"; import { CertificateExportModal, ExportOptions } from "./CertificateExportModal"; import { CertificateImportModal } from "./CertificateImportModal"; -import { CertificateIssuanceModal } from "./CertificateIssuanceModal"; import { CertificateManagePkiSyncsModal } from "./CertificateManagePkiSyncsModal"; import { CertificateManageRenewalModal } from "./CertificateManageRenewalModal"; import { CertificateRenewalModal } from "./CertificateRenewalModal"; import { CertificateRevocationModal } from "./CertificateRevocationModal"; import { CertificatesTable } from "./CertificatesTable"; -export const CertificatesSection = () => { +type CertificatesSectionProps = { + externalFilter?: { + certificateId?: string; + search?: string; + }; +}; + +export const CertificatesSection = ({ externalFilter }: CertificatesSectionProps) => { const { currentProject } = useProject(); const { mutateAsync: deleteCert } = useDeleteCert(); const { mutateAsync: downloadCertPkcs12 } = useDownloadCertPkcs12(); @@ -104,7 +110,10 @@ export const CertificatesSection = () => { return (
-

Certificates

+
+

Certificates

+ +
{ )} - - {(isAllowed) => ( - - )} -
- - + { const expiryDate = new Date(notAfter); const now = new Date(); @@ -90,20 +111,56 @@ type Props = { renewedByCertificateId?: string; } ) => void; + externalFilter?: { + certificateId?: string; + search?: string; + }; }; const PER_PAGE_INIT = 25; -export const CertificatesTable = ({ handlePopUpOpen }: Props) => { +export const CertificatesTable = ({ handlePopUpOpen, externalFilter }: Props) => { const [page, setPage] = useState(1); const [perPage, setPerPage] = useState(PER_PAGE_INIT); + const [pendingSearch, setPendingSearch] = useState(externalFilter?.search || ""); + const [pendingProfileIds, setPendingProfileIds] = useState([]); + const [pendingFilters, setPendingFilters] = useState({}); + + const [appliedSearch, setAppliedSearch] = useState(externalFilter?.search || ""); + const [appliedProfileIds, setAppliedProfileIds] = useState([]); + const [appliedFilters, setAppliedFilters] = useState({}); + + useEffect(() => { + const timeoutId = setTimeout(() => { + setAppliedSearch(pendingSearch); + setPage(1); + }, 500); + + return () => clearTimeout(timeoutId); + }, [pendingSearch]); const { currentProject } = useProject(); const { permission } = useProjectPermission(); + + const { data: profilesData } = useListCertificateProfiles({ + projectId: currentProject?.id ?? "", + limit: 100 + }); + + const backendStatus = appliedFilters.status ? [appliedFilters.status] : undefined; + + const profileIds = useMemo(() => { + if (!appliedProfileIds.length) return undefined; + return appliedProfileIds; + }, [appliedProfileIds]); + const { data, isPending } = useListWorkspaceCertificates({ projectId: currentProject?.id ?? "", offset: (page - 1) * perPage, - limit: perPage + limit: perPage, + search: appliedSearch.trim() || undefined, + status: backendStatus, + ...(profileIds && { profileIds }) }); const { mutateAsync: updateRenewalConfig } = useUpdateRenewalConfig(); @@ -122,6 +179,8 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => { return map; }, [caData]); + const certificates = data?.certificates || []; + const handleDisableAutoRenewal = async (certificateId: string, commonName: string) => { if (!currentProject?.slug) { createNotification({ @@ -143,178 +202,323 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => { }); }; + const handleClearFilters = () => { + setPendingSearch(""); + setPendingFilters({}); + setPendingProfileIds([]); + setAppliedSearch(""); + setAppliedFilters({}); + setAppliedProfileIds([]); + setPage(1); + }; + + const handleClearStatus = () => { + setPendingFilters((prev) => ({ ...prev, status: undefined })); + }; + + const handleClearProfiles = () => { + setPendingProfileIds([]); + }; + + const isTableFiltered = Boolean(appliedFilters.status || appliedProfileIds.length); + + const hasFilterChanges = useMemo(() => { + const pendingStatus = pendingFilters.status ?? undefined; + const appliedStatus = appliedFilters.status ?? undefined; + const statusChanged = pendingStatus !== appliedStatus; + const profileIdsChanged = + JSON.stringify([...pendingProfileIds].sort()) !== + JSON.stringify([...appliedProfileIds].sort()); + return statusChanged || profileIdsChanged; + }, [pendingFilters.status, appliedFilters.status, pendingProfileIds, appliedProfileIds]); + return ( - - - - - - - - - - - - {isPending && } - {!isPending && - data?.certificates.map((certificate) => { - const { variant, label } = getCertValidUntilBadgeDetails(certificate.notAfter); - - const isRevoked = certificate.status === CertStatus.REVOKED; - const isExpired = new Date(certificate.notAfter) < new Date(); - const isExpiringWithinDay = isExpiringWithinOneDay(certificate.notAfter); - const hasFailed = Boolean(certificate.renewalError); - const isAutoRenewalEnabled = Boolean( - certificate.renewBeforeDays && certificate.renewBeforeDays > 0 - ); - - const canShowAutoRenewalIcon = Boolean( - certificate.profileId && - certificate.hasPrivateKey !== false && - !certificate.renewedByCertificateId && - !isRevoked && - !isExpired && - !isExpiringWithinDay - ); - - // Still need originalDisplayName for other uses in the component - const { originalDisplayName } = getCertificateDisplayName(certificate, 64, "—"); - - return ( - - - - - - + + ); + })} + +
SAN / CNStatusNot BeforeNot After -
- - - {certificate.status === CertStatus.REVOKED ? ( - Revoked - ) : ( - {label} - )} - - {certificate.notBefore - ? format(new Date(certificate.notBefore), "yyyy-MM-dd") - : "-"} - - {certificate.notAfter - ? format(new Date(certificate.notAfter), "yyyy-MM-dd") - : "-"} - -
{ - if (!canShowAutoRenewalIcon) return ""; - if (isAutoRenewalEnabled) return "opacity-100"; - return "opacity-0 group-hover:opacity-100"; - })()}`} +
+
+ setPendingSearch(e.target.value)} + leftIcon={} + placeholder="Search by SAN, CN, ID or Serial Number" + className="flex-1" + /> + + + + + + + +
+
+

Filters

+ + {isTableFiltered && ( + + )} + +
- return ( - { - if (hasFailed && certificate.renewalError) { - return `Auto-renewal failed: ${certificate.renewalError}`; - } - if (isAutoRenewalEnabled) { - const expiryDate = new Date(certificate.notAfter); - const now = new Date(); - const daysUntilExpiry = Math.ceil( - (expiryDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000) - ); - const daysUntilRenewal = Math.max( - 0, - daysUntilExpiry - (certificate.renewBeforeDays || 0) - ); - return `Auto-renews in ${daysUntilRenewal}d`; - } - return "Set auto renewal"; - })()} - > - + )} +
+ ({ + value: id, + label: profilesData?.certificateProfiles?.find((p) => p.id === id)?.slug || id + }))} + onChange={(selectedOptions) => { + const ids = Array.isArray(selectedOptions) + ? selectedOptions.map((opt) => opt.value) + : []; + setPendingProfileIds(ids); + }} + options={ + profilesData?.certificateProfiles?.map((profile) => ({ + value: profile.id, + label: profile.slug + })) || [] + } + placeholder="Select certificate profiles..." + className="w-full border-mineshaft-600 bg-mineshaft-700 text-bunker-200" + isMulti + isLoading={!profilesData} + maxMenuHeight={120} + /> +
+ +
+
+ Status + {pendingFilters.status && ( + + )} +
+ +
+ +
+ +
+
+ + +
+ + + + + + + + + + + + + {isPending && } + {!isPending && + certificates.map((certificate) => { + const { variant, label } = getCertValidUntilBadgeDetails(certificate.notAfter); + + const isRevoked = certificate.status === CertStatus.REVOKED; + const isExpired = new Date(certificate.notAfter) < new Date(); + const isExpiringWithinDay = isExpiringWithinOneDay(certificate.notAfter); + const hasFailed = Boolean(certificate.renewalError); + const isAutoRenewalEnabled = Boolean( + certificate.renewBeforeDays && certificate.renewBeforeDays > 0 + ); + + const canShowAutoRenewalIcon = Boolean( + certificate.profileId && + certificate.hasPrivateKey !== false && + !certificate.renewedByCertificateId && + !isRevoked && + !isExpired && + !isExpiringWithinDay + ); + + const { originalDisplayName } = getCertificateDisplayName(certificate, 64, "—"); + + return ( + + + + + + + - - ); - })} - -
SAN / CNSerial NumberStatusIssued AtExpiring At +
+ + +
+ {truncateSerialNumber(certificate.serialNumber)} +
+
+ {certificate.status === CertStatus.REVOKED ? ( + Revoked + ) : ( + {label} + )} + + {certificate.notBefore + ? format(new Date(certificate.notBefore), "yyyy-MM-dd") + : "-"} + + {certificate.notAfter + ? format(new Date(certificate.notAfter), "yyyy-MM-dd") + : "-"} + +
{ + if (!canShowAutoRenewalIcon) return ""; + if (isAutoRenewalEnabled) return "opacity-100"; + return "opacity-0 group-hover:opacity-100"; + })()}`} + > + {canShowAutoRenewalIcon && + (() => { + const canEditCertificate = permission.can( + ProjectPermissionCertificateActions.Edit, + subject(ProjectPermissionSub.Certificates, { + commonName: certificate.commonName, + altNames: certificate.altNames, + serialNumber: certificate.serialNumber + }) + ); + + return ( + { + if (hasFailed && certificate.renewalError) { + return `Auto-renewal failed: ${certificate.renewalError}`; + } + if (isAutoRenewalEnabled) { + const expiryDate = new Date(certificate.notAfter); + const now = new Date(); + const daysUntilExpiry = Math.ceil( + (expiryDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000) + ); + const daysUntilRenewal = Math.max( + 0, + daysUntilExpiry - (certificate.renewBeforeDays || 0) + ); + return `Auto-renews in ${daysUntilRenewal}d`; + } + return "Set auto renewal"; })()} - aria-label="Certificate auto-renewal" - onClick={(e) => { - e.stopPropagation(); - if (!canEditCertificate) return; - if (hasFailed) return; - - handlePopUpOpen("manageRenewal", { - certificateId: certificate.id, - commonName: originalDisplayName, - profileId: certificate.profileId || "", - renewBeforeDays: certificate.renewBeforeDays || 7, - ttlDays: Math.ceil( - (new Date(certificate.notAfter).getTime() - - new Date(certificate.notBefore).getTime()) / - (24 * 60 * 60 * 1000) - ), - notAfter: certificate.notAfter, - renewalError: certificate.renewalError, - renewedFromCertificateId: certificate.renewedFromCertificateId, - renewedByCertificateId: certificate.renewedByCertificateId - }); - }} > - - - - ); - })()} -
- - -
- + + + ); + })()} +
+ + + - - - - - - {(isAllowed) => ( - - handlePopUpOpen("certificateExport", { - certificateId: certificate.id, - serialNumber: certificate.serialNumber - }) - } - disabled={!isAllowed} - icon={} - > - Export Certificate - - )} - - {isLegacyTemplatesEnabled && ( + +
+ { !isAllowed && "pointer-events-none cursor-not-allowed opacity-50" )} onClick={async () => - handlePopUpOpen("issueCertificate", { + handlePopUpOpen("certificateExport", { + certificateId: certificate.id, serialNumber: certificate.serialNumber }) } disabled={!isAllowed} - icon={} + icon={} > - View Details + Export Certificate )} - )} - {/* Manage auto renewal option - not shown for failed renewals */} - {(() => { - const canManageRenewal = - certificate.profileId && - certificate.hasPrivateKey !== false && - !certificate.renewedByCertificateId && - !isRevoked && - !isExpired && - !hasFailed && - !isExpiringWithinDay; - - if (!canManageRenewal) return null; - - return ( + {isLegacyTemplatesEnabled && ( { friendlyName: certificate.friendlyName })} > - {(isAllowed) => { - return ( + {(isAllowed) => ( + + handlePopUpOpen("issueCertificate", { + serialNumber: certificate.serialNumber + }) + } + disabled={!isAllowed} + icon={} + > + View Details + + )} + + )} + {(() => { + const canManageRenewal = + certificate.profileId && + certificate.hasPrivateKey !== false && + !certificate.renewedByCertificateId && + !isRevoked && + !isExpired && + !hasFailed && + !isExpiringWithinDay; + + if (!canManageRenewal) return null; + + return ( + + {(isAllowed) => { + return ( + { + const notAfterDate = new Date(certificate.notAfter); + const notBeforeDate = certificate.notBefore + ? new Date(certificate.notBefore) + : new Date( + notAfterDate.getTime() - 365 * 24 * 60 * 60 * 1000 + ); + const ttlDays = Math.max( + 1, + Math.ceil( + (notAfterDate.getTime() - notBeforeDate.getTime()) / + (24 * 60 * 60 * 1000) + ) + ); + handlePopUpOpen("manageRenewal", { + certificateId: certificate.id, + commonName: certificate.commonName, + profileId: certificate.profileId, + renewBeforeDays: certificate.renewBeforeDays, + ttlDays, + notAfter: certificate.notAfter, + renewalError: certificate.renewalError, + renewedFromCertificateId: + certificate.renewedFromCertificateId, + renewedByCertificateId: certificate.renewedByCertificateId + }); + }} + disabled={!isAllowed} + icon={} + > + {isAutoRenewalEnabled + ? "Manage auto renewal" + : "Enable auto renewal"} + + ); + }} + + ); + })()} + {(() => { + const canDisableRenewal = + certificate.profileId && + certificate.hasPrivateKey !== false && + !certificate.renewedByCertificateId && + !isRevoked && + !isExpired && + !isExpiringWithinDay && + isAutoRenewalEnabled; + + if (!canDisableRenewal) return null; + + return ( + + {(isAllowed) => ( { - const notAfterDate = new Date(certificate.notAfter); - const notBeforeDate = certificate.notBefore - ? new Date(certificate.notBefore) - : new Date( - notAfterDate.getTime() - 365 * 24 * 60 * 60 * 1000 - ); - const ttlDays = Math.max( - 1, - Math.ceil( - (notAfterDate.getTime() - notBeforeDate.getTime()) / - (24 * 60 * 60 * 1000) - ) + await handleDisableAutoRenewal( + certificate.id, + certificate.commonName ); - handlePopUpOpen("manageRenewal", { + }} + disabled={!isAllowed} + icon={} + > + Disable auto renewal + + )} + + ); + })()} + {(() => { + const canRenew = + (certificate.profileId || certificate.caId) && + certificate.hasPrivateKey !== false && + !certificate.renewedByCertificateId && + !isRevoked && + !isExpired; + + if (!canRenew) return null; + + return ( + + {(isAllowed) => ( + { + handlePopUpOpen("renewCertificate", { certificateId: certificate.id, - commonName: certificate.commonName, - profileId: certificate.profileId, - renewBeforeDays: certificate.renewBeforeDays, - ttlDays, - notAfter: certificate.notAfter, - renewalError: certificate.renewalError, - renewedFromCertificateId: - certificate.renewedFromCertificateId, - renewedByCertificateId: certificate.renewedByCertificateId + commonName: certificate.commonName }); }} disabled={!isAllowed} icon={} > - {isAutoRenewalEnabled - ? "Manage auto renewal" - : "Enable auto renewal"} + Renew Now - ); - }} - - ); - })()} - {/* Disable auto renewal option - only shown when auto renewal is active */} - {(() => { - const canDisableRenewal = - certificate.profileId && - certificate.hasPrivateKey !== false && - !certificate.renewedByCertificateId && - !isRevoked && - !isExpired && - !isExpiringWithinDay && - isAutoRenewalEnabled; + )} + + ); + })()} + {certificate.status === CertStatus.ACTIVE && + !certificate.renewedByCertificateId && ( + + {(isAllowed) => ( + + handlePopUpOpen("managePkiSyncs", { + certificateId: certificate.id, + commonName: certificate.commonName + }) + } + disabled={!isAllowed} + icon={} + > + Manage PKI Syncs + + )} + + )} + {(() => { + const caType = caCapabilityMap[certificate.caId]; + const supportsRevocation = + !caType || + caSupportsCapability(caType, CaCapability.REVOKE_CERTIFICATES); - if (!canDisableRenewal) return null; + if (!supportsRevocation || isRevoked) { + return null; + } - return ( - - {(isAllowed) => ( - { - await handleDisableAutoRenewal( - certificate.id, - certificate.commonName - ); - }} - disabled={!isAllowed} - icon={} - > - Disable auto renewal - - )} - - ); - })()} - {/* Manual renewal action for profile-issued certificates that are not revoked/expired (including failed ones) */} - {(() => { - const canRenew = - (certificate.profileId || certificate.caId) && - certificate.hasPrivateKey !== false && - !certificate.renewedByCertificateId && - !isRevoked && - !isExpired; - - if (!canRenew) return null; - - return ( - - {(isAllowed) => ( - { - handlePopUpOpen("renewCertificate", { - certificateId: certificate.id, - commonName: certificate.commonName - }); - }} - disabled={!isAllowed} - icon={} - > - Renew Now - - )} - - ); - })()} - {/* PKI Sync management - only for active certificates that are not renewed */} - {certificate.status === CertStatus.ACTIVE && - !certificate.renewedByCertificateId && ( - - {(isAllowed) => ( - - handlePopUpOpen("managePkiSyncs", { - certificateId: certificate.id, - commonName: certificate.commonName - }) - } - disabled={!isAllowed} - icon={} - > - Manage PKI Syncs - - )} - - )} - {/* Only show revoke button if CA supports revocation and certificate is not already revoked */} - {(() => { - const caType = caCapabilityMap[certificate.caId]; - const supportsRevocation = - !caType || - caSupportsCapability(caType, CaCapability.REVOKE_CERTIFICATES); - - if (!supportsRevocation || isRevoked) { - return null; - } - - return ( - - {(isAllowed) => ( - - handlePopUpOpen("revokeCertificate", { - certificateId: certificate.id - }) - } - disabled={!isAllowed} - icon={} - > - Revoke Certificate - - )} - - ); - })()} - - {(isAllowed) => ( - - handlePopUpOpen("deleteCertificate", { - certificateId: certificate.id, - commonName: certificate.commonName - }) - } - disabled={!isAllowed} - icon={} - > - Delete Certificate - - )} - - -
-
- {!isPending && data?.totalCount !== undefined && data.totalCount >= PER_PAGE_INIT && ( - setPage(newPage)} - onChangePerPage={(newPerPage) => setPerPage(newPerPage)} - /> - )} - {!isPending && !data?.certificates?.length && ( - - )} -
+ return ( + + {(isAllowed) => ( + + handlePopUpOpen("revokeCertificate", { + certificateId: certificate.id + }) + } + disabled={!isAllowed} + icon={} + > + Revoke Certificate + + )} + + ); + })()} + + {(isAllowed) => ( + + handlePopUpOpen("deleteCertificate", { + certificateId: certificate.id, + commonName: certificate.commonName + }) + } + disabled={!isAllowed} + icon={} + > + Delete Certificate + + )} + + + +
+ {!isPending && (data?.totalCount || 0) >= PER_PAGE_INIT && ( + setPage(newPage)} + onChangePerPage={(newPerPage) => setPerPage(newPerPage)} + /> + )} + {!isPending && !certificates.length && ( + + )} +
+
); }; diff --git a/frontend/src/pages/cert-manager/IntegrationsListPage/route.tsx b/frontend/src/pages/cert-manager/IntegrationsListPage/route.tsx index faec782c72..0fba9b6b4a 100644 --- a/frontend/src/pages/cert-manager/IntegrationsListPage/route.tsx +++ b/frontend/src/pages/cert-manager/IntegrationsListPage/route.tsx @@ -15,7 +15,7 @@ const IntegrationsListPageQuerySchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/" )({ component: IntegrationsListPage, validateSearch: zodValidator(IntegrationsListPageQuerySchema), diff --git a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx index c8243b914d..88e03a2f31 100644 --- a/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/PkiCollectionDetailsByIDPage/PkiCollectionDetailsByIDPage.tsx @@ -64,7 +64,7 @@ export const PkiCollectionPage = () => { }); handlePopUpClose("deletePkiCollection"); navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/policies", + to: "/organizations/$orgId/projects/cert-manager/$projectId/policies", params: { orgId: currentOrg.id, projectId: params.projectId @@ -77,7 +77,7 @@ export const PkiCollectionPage = () => { {data && (
{ @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Certificate Collections", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/policies", + to: "/organizations/$orgId/projects/cert-manager/$projectId/policies", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx index acea4d4d0f..779afb0a42 100644 --- a/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscriberDetailsByIDPage/PkiSubscriberDetailsByIDPage.tsx @@ -64,7 +64,7 @@ const Page = () => { handlePopUpClose("deletePkiSubscriber"); navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/subscribers", + to: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers", params: { orgId: currentOrg.id, projectId @@ -77,7 +77,7 @@ const Page = () => { {data && (
{ @@ -13,7 +13,7 @@ export const Route = createFileRoute( { label: "Subscribers", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/subscribers", + to: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx b/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx index 880f4af8f9..bf59d6665d 100644 --- a/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscribersPage/components/PkiSubscribersTable.tsx @@ -77,7 +77,7 @@ export const PkiSubscribersTable = ({ handlePopUpOpen }: Props) => { key={`pki-subscriber-${subscriber.id}`} onClick={() => navigate({ - to: "/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName", + to: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName", params: { orgId: currentOrg.id, projectId: currentProject.id, diff --git a/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx b/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx index df39a68a2e..68652dd0b6 100644 --- a/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiSubscribersPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { PkiSubscribersPage } from "./PkiSubscribersPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/" )({ component: PkiSubscribersPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/PkiSyncDetailsByIDPage/route.tsx b/frontend/src/pages/cert-manager/PkiSyncDetailsByIDPage/route.tsx index 49bed6c75d..78f67cc3ac 100644 --- a/frontend/src/pages/cert-manager/PkiSyncDetailsByIDPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiSyncDetailsByIDPage/route.tsx @@ -5,7 +5,7 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { PkiSyncDetailsByIDPage } from "./index"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId" )({ component: PkiSyncDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Integrations", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/integrations", + to: "/organizations/$orgId/projects/cert-manager/$projectId/integrations", params, search: { selectedTab: IntegrationsListPageTabs.PkiSyncs diff --git a/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx b/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx index c943ede97e..305039892e 100644 --- a/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx +++ b/frontend/src/pages/cert-manager/PkiTemplateListPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { PkiTemplateListPage } from "./PkiTemplateListPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/" )({ component: PkiTemplateListPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/PoliciesPage/PoliciesPage.tsx b/frontend/src/pages/cert-manager/PoliciesPage/PoliciesPage.tsx index c734e621e1..2529b69ca9 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/PoliciesPage.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/PoliciesPage.tsx @@ -14,6 +14,7 @@ import { import { ProjectType } from "@app/hooks/api/projects/types"; import { CertificateProfilesTab } from "./components/CertificateProfilesTab"; +import { CertificateRequestsTab } from "./components/CertificateRequestsTab"; import { CertificatesTab } from "./components/CertificatesTab"; import { CertificateTemplatesV2Tab } from "./components/CertificateTemplatesV2Tab"; @@ -21,6 +22,7 @@ enum TabSections { CertificateProfiles = "profiles", CertificateTemplatesV2 = "templates-v2", Certificates = "certificates", + CertificateRequests = "certificate-requests", PkiCollections = "pki-collections" } @@ -28,7 +30,13 @@ export const PoliciesPage = () => { const { t } = useTranslation(); const { currentProject } = useProject(); const { permission } = useProjectPermission(); - const [activeTab, setActiveTab] = useState(TabSections.CertificateProfiles); + const [activeTab, setActiveTab] = useState(TabSections.Certificates); + const [certificateFilter, setCertificateFilter] = useState<{ search?: string }>({}); + + const handleViewCertificateFromRequest = (certificateId: string) => { + setActiveTab(TabSections.Certificates); + setCertificateFilter({ search: certificateId }); + }; const canReadCertificateProfiles = permission.can( ProjectPermissionCertificateProfileActions.Read, @@ -50,12 +58,12 @@ export const PoliciesPage = () => { return (
- {t("common.head-title", { title: "Certificate Management" })} + {t("common.head-title", { title: "Certificate Manager" })}
@@ -65,17 +73,38 @@ export const PoliciesPage = () => { onValueChange={(value) => setActiveTab(value as TabSections)} > + + Certificates + + + Certificate Requests + Certificate Profiles Certificate Templates - - Certificates - + + {canReadCertificates ? ( + + ) : ( + + )} + + + + {canReadCertificates ? ( + + ) : ( + + )} + + {canReadCertificateProfiles ? : } @@ -87,10 +116,6 @@ export const PoliciesPage = () => { )} - - - {canReadCertificates ? : } -
diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CertificateProfilesTab.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CertificateProfilesTab.tsx index 9807cb98fe..1045f809ab 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CertificateProfilesTab.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CertificateProfilesTab.tsx @@ -6,6 +6,7 @@ import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionCertificateProfileActions, ProjectPermissionSub @@ -70,7 +71,10 @@ export const CertificateProfilesTab = () => {
-

Certificate Profiles

+
+

Certificate Profiles

+ +

Unified certificate issuance configurations combining CA, template, and enrollment method diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx index 138e60de3a..43de8c6b23 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateProfilesTab/CreateProfileModal.tsx @@ -79,7 +79,11 @@ const createSchema = z renewBeforeDays: z.number().min(1).max(365).optional() }) .optional(), - acmeConfig: z.object({}).optional(), + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) + .optional(), externalConfigs: z .object({ template: z.string().min(1, "Azure ADCS template is required") @@ -219,7 +223,11 @@ const editSchema = z renewBeforeDays: z.number().min(1).max(365).optional() }) .optional(), - acmeConfig: z.object({}).optional(), + acmeConfig: z + .object({ + skipDnsOwnershipVerification: z.boolean().optional() + }) + .optional(), externalConfigs: z .object({ template: z.string().optional() @@ -406,7 +414,13 @@ export const CreateProfileModal = ({ renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30 } : undefined, - acmeConfig: profile.enrollmentType === EnrollmentType.ACME ? {} : undefined, + acmeConfig: + profile.enrollmentType === EnrollmentType.ACME + ? { + skipDnsOwnershipVerification: + profile.acmeConfig?.skipDnsOwnershipVerification || false + } + : undefined, externalConfigs: profile.externalConfigs ? { template: @@ -429,7 +443,9 @@ export const CreateProfileModal = ({ autoRenew: false, renewBeforeDays: 30 }, - acmeConfig: {}, + acmeConfig: { + skipDnsOwnershipVerification: false + }, externalConfigs: undefined } }); @@ -476,7 +492,13 @@ export const CreateProfileModal = ({ renewBeforeDays: profile.apiConfig?.renewBeforeDays || 30 } : undefined, - acmeConfig: profile.enrollmentType === EnrollmentType.ACME ? {} : undefined, + acmeConfig: + profile.enrollmentType === EnrollmentType.ACME + ? { + skipDnsOwnershipVerification: + profile.acmeConfig?.skipDnsOwnershipVerification || false + } + : undefined, externalConfigs: profile.externalConfigs ? { template: @@ -667,7 +689,9 @@ export const CreateProfileModal = ({ renewBeforeDays: 30 }); setValue("estConfig", undefined); - setValue("acmeConfig", undefined); + setValue("acmeConfig", { + skipDnsOwnershipVerification: false + }); } onChange(value); }} @@ -797,7 +821,9 @@ export const CreateProfileModal = ({ } else if (watchedEnrollmentType === "acme") { setValue("estConfig", undefined); setValue("apiConfig", undefined); - setValue("acmeConfig", {}); + setValue("acmeConfig", { + skipDnsOwnershipVerification: false + }); } onChange(value); }} @@ -846,7 +872,9 @@ export const CreateProfileModal = ({ } else if (value === "acme") { setValue("apiConfig", undefined); setValue("estConfig", undefined); - setValue("acmeConfig", {}); + setValue("acmeConfig", { + skipDnsOwnershipVerification: false + }); } onChange(value); }} @@ -975,10 +1003,24 @@ export const CreateProfileModal = ({

( + name="acmeConfig.skipDnsOwnershipVerification" + render={({ field: { value, onChange }, fieldState: { error } }) => ( -
{/* FIXME: ACME configuration */}
+
+ +
+ + Skip DNS Ownership Validation + +

+ Skip DNS ownership verification during ACME certificate issuance. +

+
+
)} /> diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/CertificateRequestsTab.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/CertificateRequestsTab.tsx new file mode 100644 index 0000000000..102ce8d08e --- /dev/null +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/CertificateRequestsTab.tsx @@ -0,0 +1,9 @@ +import { CertificateRequestsSection } from "@app/pages/cert-manager/CertificateRequestsPage/components"; + +type Props = { + onViewCertificateFromRequest?: (certificateId: string) => void; +}; + +export const CertificateRequestsTab = ({ onViewCertificateFromRequest }: Props) => { + return ; +}; diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/index.ts b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/index.ts new file mode 100644 index 0000000000..8249d740e0 --- /dev/null +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateRequestsTab/index.ts @@ -0,0 +1 @@ +export { CertificateRequestsTab } from "./CertificateRequestsTab"; diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateTemplatesV2Tab/CertificateTemplatesV2Tab.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateTemplatesV2Tab/CertificateTemplatesV2Tab.tsx index c2cad7b9bb..ebc957c1fa 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateTemplatesV2Tab/CertificateTemplatesV2Tab.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificateTemplatesV2Tab/CertificateTemplatesV2Tab.tsx @@ -5,6 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal } from "@app/components/v2"; +import { DocumentationLinkBadge } from "@app/components/v3"; import { ProjectPermissionPkiTemplateActions, ProjectPermissionSub @@ -56,7 +57,10 @@ export const CertificateTemplatesV2Tab = () => {
-

Certificate Templates

+
+

Certificate Templates

+ +

Define certificate policies, validation rules, and attribute constraints for certificate issuance diff --git a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificatesTab/CertificatesTab.tsx b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificatesTab/CertificatesTab.tsx index caf9cdb2f0..24cc69c8a6 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/components/CertificatesTab/CertificatesTab.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/components/CertificatesTab/CertificatesTab.tsx @@ -1,5 +1,12 @@ import { CertificatesSection } from "../../../CertificatesPage/components/CertificatesSection"; -export const CertificatesTab = () => { - return ; +type Props = { + externalFilter?: { + certificateId?: string; + search?: string; + }; +}; + +export const CertificatesTab = ({ externalFilter }: Props) => { + return ; }; diff --git a/frontend/src/pages/cert-manager/PoliciesPage/route.tsx b/frontend/src/pages/cert-manager/PoliciesPage/route.tsx index 807d69bb9a..70794f2674 100644 --- a/frontend/src/pages/cert-manager/PoliciesPage/route.tsx +++ b/frontend/src/pages/cert-manager/PoliciesPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { PoliciesPage } from "./PoliciesPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies" )({ component: PoliciesPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/SettingsPage/route.tsx b/frontend/src/pages/cert-manager/SettingsPage/route.tsx index 59eccb028f..4f205481a3 100644 --- a/frontend/src/pages/cert-manager/SettingsPage/route.tsx +++ b/frontend/src/pages/cert-manager/SettingsPage/route.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { SettingsPage } from "./SettingsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings" )({ component: SettingsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/cert-manager/layout.tsx b/frontend/src/pages/cert-manager/layout.tsx index 0462c230dc..463fc5c30e 100644 --- a/frontend/src/pages/cert-manager/layout.tsx +++ b/frontend/src/pages/cert-manager/layout.tsx @@ -8,7 +8,7 @@ import { PkiManagerLayout } from "@app/layouts/PkiManagerLayout"; import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" )({ component: PkiManagerLayout, beforeLoad: async ({ params, context }) => { diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityLinkForm.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityLinkForm.tsx index 9f7141802a..b8d857f919 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityLinkForm.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityLinkForm.tsx @@ -84,6 +84,7 @@ export const OrgIdentityLinkForm = ({ onClose }: Props) => { onChange={onChange} placeholder="Select machine identity..." // onInputChange={setSearchValue} + autoFocus options={rootOrgIdentities} getOptionValue={(option) => option.id} getOptionLabel={(option) => option.name} diff --git a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityModal.tsx b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityModal.tsx index 737c454d1f..732a22cce7 100644 --- a/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityModal.tsx +++ b/frontend/src/pages/organization/AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityModal.tsx @@ -185,7 +185,7 @@ export const OrgIdentityModal = ({ popUp, handlePopUpToggle }: Props) => { isError={Boolean(error)} errorText={error?.message} > - + )} /> diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx index 6fa3d88542..3a2708688c 100644 --- a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/AppConnectionForm.tsx @@ -41,6 +41,7 @@ import { MySqlConnectionForm } from "./MySqlConnectionForm"; import { NetlifyConnectionForm } from "./NetlifyConnectionForm"; import { NorthflankConnectionForm } from "./NorthflankConnectionForm"; import { OCIConnectionForm } from "./OCIConnectionForm"; +import { OctopusDeployConnectionForm } from "./OctopusDeployConnectionForm"; import { OktaConnectionForm } from "./OktaConnectionForm"; import { OracleDBConnectionForm } from "./OracleDBConnectionForm"; import { PostgresConnectionForm } from "./PostgresConnectionForm"; @@ -176,6 +177,8 @@ const CreateForm = ({ app, onComplete, projectId }: CreateFormProps) => { return ; case AppConnection.MongoDB: return ; + case AppConnection.OctopusDeploy: + return ; default: throw new Error(`Unhandled App ${app}`); } @@ -336,6 +339,8 @@ const UpdateForm = ({ appConnection, onComplete }: UpdateFormProps) => { return ; case AppConnection.MongoDB: return ; + case AppConnection.OctopusDeploy: + return ; default: throw new Error(`Unhandled App ${(appConnection as TAppConnection).app}`); } diff --git a/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OctopusDeployConnectionForm.tsx b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OctopusDeployConnectionForm.tsx new file mode 100644 index 0000000000..6fd60e005f --- /dev/null +++ b/frontend/src/pages/organization/AppConnections/AppConnectionsPage/components/AppConnectionForm/OctopusDeployConnectionForm.tsx @@ -0,0 +1,158 @@ +import { Controller, FormProvider, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; + +import { + Button, + FormControl, + Input, + ModalClose, + SecretInput, + Select, + SelectItem +} from "@app/components/v2"; +import { APP_CONNECTION_MAP, getAppConnectionMethodDetails } from "@app/helpers/appConnections"; +import { + OctopusDeployConnectionMethod, + TOctopusDeployConnection +} from "@app/hooks/api/appConnections"; +import { AppConnection } from "@app/hooks/api/appConnections/enums"; + +import { + genericAppConnectionFieldsSchema, + GenericAppConnectionsFields +} from "./GenericAppConnectionFields"; + +type Props = { + appConnection?: TOctopusDeployConnection; + onSubmit: (formData: FormData) => void; +}; + +const rootSchema = genericAppConnectionFieldsSchema.extend({ + app: z.literal(AppConnection.OctopusDeploy) +}); + +const formSchema = z.discriminatedUnion("method", [ + rootSchema.extend({ + method: z.literal(OctopusDeployConnectionMethod.ApiKey), + credentials: z.object({ + instanceUrl: z + .string() + .trim() + .url("Invalid Instance URL") + .min(1, "Instance URL required") + .max(255), + apiKey: z.string().trim().min(1, "API Key required") + }) + }) +]); + +type FormData = z.infer; + +export const OctopusDeployConnectionForm = ({ appConnection, onSubmit }: Props) => { + const isUpdate = Boolean(appConnection); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: appConnection ?? { + app: AppConnection.OctopusDeploy, + method: OctopusDeployConnectionMethod.ApiKey + } + }); + + const { + handleSubmit, + control, + formState: { isSubmitting, isDirty } + } = form; + + return ( + +

+ {!isUpdate && } + ( + + + + )} + /> + ( + + + + )} + /> + ( + + onChange(e.target.value)} + /> + + )} + /> +
+ + + + +
+ + + ); +}; diff --git a/frontend/src/pages/organization/AuditLogsPage/components/LogsTableRow.tsx b/frontend/src/pages/organization/AuditLogsPage/components/LogsTableRow.tsx index 8463c303a5..90882d43d7 100644 --- a/frontend/src/pages/organization/AuditLogsPage/components/LogsTableRow.tsx +++ b/frontend/src/pages/organization/AuditLogsPage/components/LogsTableRow.tsx @@ -68,6 +68,12 @@ export const LogsTableRow = ({ auditLog, rowNumber, timezone }: Props) => { {auditLog.actor.type === ActorType.IDENTITY && ( )} + {auditLog.actor.type === ActorType.ACME_PROFILE && ( + + )} + {auditLog.actor.type === ActorType.ACME_ACCOUNT && ( + + )}
diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModal.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModal.tsx index b9d1b184c3..9dbd193c4e 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModal.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModal.tsx @@ -1,39 +1,35 @@ import { useState } from "react"; -import { faMagnifyingGlass, faUsers } from "@fortawesome/free-solid-svg-icons"; +import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { HardDriveIcon, UserIcon } from "lucide-react"; +import { twMerge } from "tailwind-merge"; -import { createNotification } from "@app/components/notifications"; -import { OrgPermissionCan } from "@app/components/permissions"; -import { - Button, - EmptyState, - Input, - Modal, - ModalContent, - Pagination, - Table, - TableContainer, - TableSkeleton, - TBody, - Td, - Th, - THead, - Tr -} from "@app/components/v2"; -import { OrgPermissionGroupActions, OrgPermissionSubjects } from "@app/context"; -import { useDebounce, useResetPageHelper } from "@app/hooks"; -import { useAddUserToGroup, useListGroupUsers } from "@app/hooks/api"; -import { EFilterReturnedUsers } from "@app/hooks/api/groups/types"; +import { Button, Input, Modal, ModalContent, Tooltip } from "@app/components/v2"; +import { useDebounce } from "@app/hooks"; import { UsePopUpState } from "@app/hooks/usePopUp"; +import { AddGroupIdentitiesTab, AddGroupUsersTab } from "./AddGroupMemberModalTabs"; + +enum AddMemberType { + Users = "users", + MachineIdentities = "machineIdentities" +} + type Props = { popUp: UsePopUpState<["addGroupMembers"]>; handlePopUpToggle: (popUpName: keyof UsePopUpState<["addGroupMembers"]>, state?: boolean) => void; + isOidcManageGroupMembershipsEnabled: boolean; }; -export const AddGroupMembersModal = ({ popUp, handlePopUpToggle }: Props) => { - const [page, setPage] = useState(1); - const [perPage, setPerPage] = useState(10); +export const AddGroupMembersModal = ({ + popUp, + handlePopUpToggle, + isOidcManageGroupMembershipsEnabled +}: Props) => { + const [addMemberType, setAddMemberType] = useState( + isOidcManageGroupMembershipsEnabled ? AddMemberType.MachineIdentities : AddMemberType.Users + ); + const [searchMemberFilter, setSearchMemberFilter] = useState(""); const [debouncedSearch] = useDebounce(searchMemberFilter); @@ -42,47 +38,6 @@ export const AddGroupMembersModal = ({ popUp, handlePopUpToggle }: Props) => { slug: string; }; - const offset = (page - 1) * perPage; - const { data, isPending } = useListGroupUsers({ - id: popUpData?.groupId, - groupSlug: popUpData?.slug, - offset, - limit: perPage, - search: debouncedSearch, - filter: EFilterReturnedUsers.NON_MEMBERS - }); - - const { totalCount = 0 } = data ?? {}; - - useResetPageHelper({ - totalCount, - offset, - setPage - }); - - const { mutateAsync: addUserToGroupMutateAsync } = useAddUserToGroup(); - - const handleAddMember = async (username: string) => { - if (!popUpData?.slug) { - createNotification({ - text: "Some data is missing, please refresh the page and try again", - type: "error" - }); - return; - } - - await addUserToGroupMutateAsync({ - groupId: popUpData.groupId, - username, - slug: popUpData.slug - }); - - createNotification({ - text: "Successfully assigned user to the group", - type: "success" - }); - }; - return ( { }} > - setSearchMemberFilter(e.target.value)} - leftIcon={} - placeholder="Search members..." - /> - - - - - - - - - {isPending && } - {!isPending && - data?.users?.map(({ id, firstName, lastName, username }) => { - return ( - - - - - ); - })} - -
User -
-

{`${firstName ?? "-"} ${lastName ?? ""}`}

-

{username}

-
- - {(isAllowed) => { - return ( - - ); - }} - -
- {!isPending && totalCount > 0 && ( - setPage(newPage)} - onChangePerPage={(newPerPage) => setPerPage(newPerPage)} +
+ +
+ +
+
+ +
+
+ setSearchMemberFilter(e.target.value)} + leftIcon={} + placeholder="Search members..." + /> +
+ {addMemberType === AddMemberType.Users && + popUpData && + !isOidcManageGroupMembershipsEnabled && ( + )} - {!isPending && !data?.users?.length && ( - - )} -
+ {addMemberType === AddMemberType.MachineIdentities && popUpData && ( + + )}
); diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupIdentitiesTab.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupIdentitiesTab.tsx new file mode 100644 index 0000000000..0e09c0bbe9 --- /dev/null +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupIdentitiesTab.tsx @@ -0,0 +1,143 @@ +import { useState } from "react"; +import { faServer } from "@fortawesome/free-solid-svg-icons"; + +import { createNotification } from "@app/components/notifications"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { + Button, + EmptyState, + Pagination, + Table, + TableContainer, + TableSkeleton, + TBody, + Td, + Th, + THead, + Tr +} from "@app/components/v2"; +import { OrgPermissionGroupActions, OrgPermissionSubjects } from "@app/context"; +import { useResetPageHelper } from "@app/hooks"; +import { useAddIdentityToGroup, useListGroupMachineIdentities } from "@app/hooks/api"; +import { + FilterReturnedMachineIdentities, + TGroupMachineIdentity +} from "@app/hooks/api/groups/types"; + +type Props = { + groupId: string; + groupSlug: string; + search: string; +}; + +export const AddGroupIdentitiesTab = ({ groupId, groupSlug, search }: Props) => { + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + + const offset = (page - 1) * perPage; + const { data, isPending } = useListGroupMachineIdentities({ + id: groupId, + groupSlug, + offset, + limit: perPage, + search, + filter: FilterReturnedMachineIdentities.NON_ASSIGNED_MACHINE_IDENTITIES + }); + + const { totalCount = 0 } = data ?? {}; + + useResetPageHelper({ + totalCount, + offset, + setPage + }); + + const { mutateAsync: addIdentityToGroupMutateAsync } = useAddIdentityToGroup(); + + const handleAddIdentity = async (identityId: string) => { + if (!groupSlug) { + createNotification({ + text: "Some data is missing, please refresh the page and try again", + type: "error" + }); + return; + } + + await addIdentityToGroupMutateAsync({ + groupId, + identityId, + slug: groupSlug + }); + + createNotification({ + text: "Successfully assigned machine identity to the group", + type: "success" + }); + }; + + return ( + + + + + + + + + {isPending && } + {!isPending && + data?.machineIdentities?.map((identity: TGroupMachineIdentity) => { + return ( + + + + + ); + })} + +
Machine Identity +
+

{identity.name}

+
+ + {(isAllowed) => { + return ( + + ); + }} + +
+ {!isPending && totalCount > 0 && ( + setPage(newPage)} + onChangePerPage={(newPerPage) => setPerPage(newPerPage)} + /> + )} + {!isPending && !data?.machineIdentities?.length && ( + + )} +
+ ); +}; diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupUsersTab.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupUsersTab.tsx new file mode 100644 index 0000000000..a2ef53feba --- /dev/null +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/AddGroupUsersTab.tsx @@ -0,0 +1,137 @@ +import { useState } from "react"; +import { faUsers } from "@fortawesome/free-solid-svg-icons"; + +import { createNotification } from "@app/components/notifications"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { + Button, + EmptyState, + Pagination, + Table, + TableContainer, + TableSkeleton, + TBody, + Td, + Th, + THead, + Tr +} from "@app/components/v2"; +import { OrgPermissionGroupActions, OrgPermissionSubjects } from "@app/context"; +import { useResetPageHelper } from "@app/hooks"; +import { useAddUserToGroup, useListGroupUsers } from "@app/hooks/api"; +import { FilterReturnedUsers } from "@app/hooks/api/groups/types"; + +type Props = { + groupId: string; + groupSlug: string; + search: string; +}; + +export const AddGroupUsersTab = ({ groupId, groupSlug, search }: Props) => { + const [page, setPage] = useState(1); + const [perPage, setPerPage] = useState(10); + + const offset = (page - 1) * perPage; + const { data, isPending } = useListGroupUsers({ + id: groupId, + groupSlug, + offset, + limit: perPage, + search, + filter: FilterReturnedUsers.NON_MEMBERS + }); + + const { totalCount = 0 } = data ?? {}; + + useResetPageHelper({ + totalCount, + offset, + setPage + }); + + const { mutateAsync: addUserToGroupMutateAsync } = useAddUserToGroup(); + + const handleAddUser = async (username: string) => { + if (!groupSlug) { + createNotification({ + text: "Some data is missing, please refresh the page and try again", + type: "error" + }); + return; + } + + await addUserToGroupMutateAsync({ + groupId, + username, + slug: groupSlug + }); + + createNotification({ + text: "Successfully assigned user to the group", + type: "success" + }); + }; + + return ( + + + + + + + + + {isPending && } + {!isPending && + data?.users?.map(({ id, firstName, lastName, username }) => { + return ( + + + + + ); + })} + +
User +
+

{`${firstName ?? "-"} ${lastName ?? ""}`}

+

{username}

+
+ + {(isAllowed) => { + return ( + + ); + }} + +
+ {!isPending && totalCount > 0 && ( + setPage(newPage)} + onChangePerPage={(newPerPage) => setPerPage(newPerPage)} + /> + )} + {!isPending && !data?.users?.length && ( + + )} +
+ ); +}; diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/index.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/index.tsx new file mode 100644 index 0000000000..e40c6da6b7 --- /dev/null +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupMemberModalTabs/index.tsx @@ -0,0 +1,2 @@ +export { AddGroupIdentitiesTab } from "./AddGroupIdentitiesTab"; +export { AddGroupUsersTab } from "./AddGroupUsersTab"; diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupProjectModal.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupProjectModal.tsx index c7040ec54a..ec97c216cd 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupProjectModal.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/AddGroupProjectModal.tsx @@ -27,7 +27,7 @@ import { useAddGroupToWorkspace as useAddProjectToGroup, useListGroupProjects } from "@app/hooks/api"; -import { EFilterReturnedProjects } from "@app/hooks/api/groups/types"; +import { FilterReturnedProjects } from "@app/hooks/api/groups/types"; import { ProjectType } from "@app/hooks/api/projects/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; @@ -57,7 +57,7 @@ export const AddGroupProjectModal = ({ popUp, handlePopUpToggle }: Props) => { offset, limit: perPage, search: debouncedSearch, - filter: EFilterReturnedProjects.UNASSIGNED_PROJECTS + filter: FilterReturnedProjects.UNASSIGNED_PROJECTS }); const { totalCount = 0 } = data ?? {}; diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersSection.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersSection.tsx index 024bc54d64..da1a627f63 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersSection.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersSection.tsx @@ -3,9 +3,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; -import { DeleteActionModal, IconButton, Tooltip } from "@app/components/v2"; +import { DeleteActionModal, IconButton } from "@app/components/v2"; import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context"; -import { useOidcManageGroupMembershipsEnabled, useRemoveUserFromGroup } from "@app/hooks/api"; +import { + useOidcManageGroupMembershipsEnabled, + useRemoveIdentityFromGroup, + useRemoveUserFromGroup +} from "@app/hooks/api"; +import { GroupMemberType } from "@app/hooks/api/groups/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { AddGroupMembersModal } from "../AddGroupMemberModal"; @@ -16,6 +21,10 @@ type Props = { groupSlug: string; }; +type RemoveMemberData = + | { memberType: GroupMemberType.USER; username: string } + | { memberType: GroupMemberType.MACHINE_IDENTITY; identityId: string; name: string }; + export const GroupMembersSection = ({ groupId, groupSlug }: Props) => { const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ "addGroupMembers", @@ -28,52 +37,66 @@ export const GroupMembersSection = ({ groupId, groupSlug }: Props) => { useOidcManageGroupMembershipsEnabled(currentOrg.id); const { mutateAsync: removeUserFromGroupMutateAsync } = useRemoveUserFromGroup(); - const handleRemoveUserFromGroup = async (username: string) => { - await removeUserFromGroupMutateAsync({ - groupId, - username, - slug: groupSlug - }); + const { mutateAsync: removeIdentityFromGroupMutateAsync } = useRemoveIdentityFromGroup(); - createNotification({ - text: `Successfully removed user ${username} from the group`, - type: "success" - }); + const handleRemoveMemberFromGroup = async (memberData: RemoveMemberData) => { + if (memberData.memberType === GroupMemberType.USER) { + await removeUserFromGroupMutateAsync({ + groupId, + username: memberData.username, + slug: groupSlug + }); + + createNotification({ + text: `Successfully removed user ${memberData.username} from the group`, + type: "success" + }); + } else { + await removeIdentityFromGroupMutateAsync({ + groupId, + identityId: memberData.identityId, + slug: groupSlug + }); + + createNotification({ + text: `Successfully removed identity ${memberData.name} from the group`, + type: "success" + }); + } handlePopUpToggle("removeMemberFromGroup", false); }; + const getMemberName = (memberData: RemoveMemberData) => { + if (!memberData) return ""; + if (memberData.memberType === GroupMemberType.USER) { + return memberData.username; + } + return memberData.name; + }; + return (
-

Members

+

Group Members

{(isAllowed) => ( - -
- { - handlePopUpOpen("addGroupMembers", { - groupId, - slug: groupSlug - }); - }} - > - - -
-
+
+ { + handlePopUpOpen("addGroupMembers", { + groupId, + slug: groupSlug + }); + }} + > + + +
)}
@@ -84,21 +107,19 @@ export const GroupMembersSection = ({ groupId, groupSlug }: Props) => { handlePopUpOpen={handlePopUpOpen} />
- + handlePopUpToggle("removeMemberFromGroup", isOpen)} deleteKey="confirm" onDeleteApproved={() => { - const userData = popUp?.removeMemberFromGroup?.data as { - username: string; - id: string; - }; - - return handleRemoveUserFromGroup(userData.username); + const memberData = popUp?.removeMemberFromGroup?.data as RemoveMemberData; + return handleRemoveMemberFromGroup(memberData); }} />
diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx index f56f852d4a..0902b01d2f 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx @@ -1,16 +1,25 @@ -import { useMemo } from "react"; +import { useState } from "react"; import { faArrowDown, faArrowUp, + faCheckCircle, + faFilter, faFolder, faMagnifyingGlass, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { HardDriveIcon, UserIcon } from "lucide-react"; +import { twMerge } from "tailwind-merge"; import { OrgPermissionCan } from "@app/components/permissions"; import { Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, EmptyState, IconButton, Input, @@ -31,12 +40,18 @@ import { setUserTablePreference } from "@app/helpers/userTablePreferences"; import { usePagination, useResetPageHelper } from "@app/hooks"; -import { useListGroupUsers, useOidcManageGroupMembershipsEnabled } from "@app/hooks/api"; +import { useOidcManageGroupMembershipsEnabled } from "@app/hooks/api"; import { OrderByDirection } from "@app/hooks/api/generic/types"; -import { EFilterReturnedUsers } from "@app/hooks/api/groups/types"; +import { useListGroupMembers } from "@app/hooks/api/groups/queries"; +import { + FilterMemberType, + GroupMembersOrderBy, + GroupMemberType +} from "@app/hooks/api/groups/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; -import { GroupMembershipRow } from "./GroupMembershipRow"; +import { GroupMembershipIdentityRow } from "./GroupMembershipIdentityRow"; +import { GroupMembershipUserRow } from "./GroupMembershipUserRow"; type Props = { groupId: string; @@ -47,10 +62,6 @@ type Props = { ) => void; }; -enum GroupMembersOrderBy { - Name = "name" -} - export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props) => { const { search, @@ -61,11 +72,14 @@ export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props setPerPage, offset, orderDirection, - toggleOrderDirection + toggleOrderDirection, + orderBy } = usePagination(GroupMembersOrderBy.Name, { initPerPage: getUserTablePreference("groupMembersTable", PreferenceKey.PerPage, 20) }); + const [memberTypeFilter, setMemberTypeFilter] = useState([]); + const handlePerPageChange = (newPerPage: number) => { setPerPage(newPerPage); setUserTablePreference("groupMembersTable", PreferenceKey.PerPage, newPerPage); @@ -76,66 +90,103 @@ export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props const { data: isOidcManageGroupMembershipsEnabled = false } = useOidcManageGroupMembershipsEnabled(currentOrg.id); - const { data: groupMemberships, isPending } = useListGroupUsers({ + const { data: groupMemberships, isPending } = useListGroupMembers({ id: groupId, groupSlug, offset, limit: perPage, search, - filter: EFilterReturnedUsers.EXISTING_MEMBERS + orderBy, + orderDirection, + memberTypeFilter: memberTypeFilter.length > 0 ? memberTypeFilter : undefined }); - const filteredGroupMemberships = useMemo(() => { - return groupMemberships && groupMemberships?.users - ? groupMemberships?.users - ?.filter((membership) => { - const userSearchString = `${membership.firstName && membership.firstName} ${ - membership.lastName && membership.lastName - } ${membership.email && membership.email} ${ - membership.username && membership.username - }`; - return userSearchString.toLowerCase().includes(search.trim().toLowerCase()); - }) - .sort((a, b) => { - const [membershipOne, membershipTwo] = - orderDirection === OrderByDirection.ASC ? [a, b] : [b, a]; - - const membershipOneComparisonString = membershipOne.firstName - ? membershipOne.firstName - : membershipOne.email; - - const membershipTwoComparisonString = membershipTwo.firstName - ? membershipTwo.firstName - : membershipTwo.email; - - const comparison = membershipOneComparisonString - .toLowerCase() - .localeCompare(membershipTwoComparisonString.toLowerCase()); - - return comparison; - }) - : []; - }, [groupMemberships, orderDirection, search]); + const { members = [], totalCount = 0 } = groupMemberships ?? {}; useResetPageHelper({ - totalCount: filteredGroupMemberships?.length, + totalCount, offset, setPage }); + const filterOptions = [ + { + icon: , + label: "Users", + value: FilterMemberType.USERS + }, + { + icon: , + label: "Machine Identities", + value: FilterMemberType.MACHINE_IDENTITIES + } + ]; + return (
- setSearch(e.target.value)} - leftIcon={} - placeholder="Search users..." - /> +
+ setSearch(e.target.value)} + leftIcon={} + placeholder="Search members..." + /> + + + 0 && "border-primary/50 text-primary" + )} + > + + + + + Filter by Member Type + {filterOptions.map((option) => ( + { + e.preventDefault(); + setMemberTypeFilter((prev) => { + if (prev.includes(option.value)) { + return prev.filter((f) => f !== option.value); + } + return [...prev, option.value]; + }); + setPage(1); + }} + icon={ + memberTypeFilter.includes(option.value) && ( + + ) + } + > +
+ {option.icon} + {option.label} +
+
+ ))} +
+
+
- - @@ -158,37 +208,43 @@ export const GroupMembersTable = ({ groupId, groupSlug, handlePopUpOpen }: Props {isPending && } {!isPending && - filteredGroupMemberships.slice(offset, perPage * page).map((userGroupMembership) => { - return ( - { + return userGroupMembership.type === GroupMemberType.USER ? ( + + ) : ( + ); })}
+ +
Name
Email Added On
- {Boolean(filteredGroupMemberships.length) && ( + {Boolean(totalCount) && ( )} - {!isPending && !filteredGroupMemberships?.length && ( + {!isPending && !members.length && ( )} - {!groupMemberships?.users.length && ( + {!groupMemberships?.members.length && ( {(isAllowed) => ( , + data?: object + ) => void; +}; + +export const GroupMembershipIdentityRow = ({ + identity: { + machineIdentity: { name }, + joinedGroupAt, + id + }, + handlePopUpOpen +}: Props) => { + return ( + + + + + +

{name}

+ + + +

{new Date(joinedGroupAt).toLocaleDateString()}

+
+ + + + + + + + + + + + {(isAllowed) => { + return ( +
+ } + onClick={() => + handlePopUpOpen("removeMemberFromGroup", { + memberType: GroupMemberType.MACHINE_IDENTITY, + identityId: id, + name + }) + } + isDisabled={!isAllowed} + > + Remove Identity From Group + +
+ ); + }} +
+
+
+
+ + + ); +}; diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx similarity index 75% rename from frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx rename to frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx index 8ec279a9d3..eb5fc45e56 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx @@ -1,5 +1,6 @@ import { faEllipsisV, faUserMinus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { UserIcon } from "lucide-react"; import { OrgPermissionCan } from "@app/components/permissions"; import { @@ -14,19 +15,23 @@ import { } from "@app/components/v2"; import { OrgPermissionGroupActions, OrgPermissionSubjects, useOrganization } from "@app/context"; import { useOidcManageGroupMembershipsEnabled } from "@app/hooks/api"; -import { TGroupUser } from "@app/hooks/api/groups/types"; +import { GroupMemberType, TGroupMemberUser } from "@app/hooks/api/groups/types"; import { UsePopUpState } from "@app/hooks/usePopUp"; type Props = { - user: TGroupUser; + user: TGroupMemberUser; handlePopUpOpen: ( popUpName: keyof UsePopUpState<["removeMemberFromGroup"]>, data?: object ) => void; }; -export const GroupMembershipRow = ({ - user: { firstName, lastName, username, joinedGroupAt, email, id }, +export const GroupMembershipUserRow = ({ + user: { + user: { firstName, lastName, email, username }, + joinedGroupAt, + id + }, handlePopUpOpen }: Props) => { const { currentOrg } = useOrganization(); @@ -36,15 +41,18 @@ export const GroupMembershipRow = ({ return ( - -

{`${firstName ?? "-"} ${lastName ?? ""}`}

+ + - -

{email}

+ +

+ {`${firstName ?? "-"} ${lastName ?? ""}`}{" "} + ({email}) +

-

{new Date(joinedGroupAt).toLocaleDateString()}

+

{new Date(joinedGroupAt).toLocaleDateString()}

@@ -75,7 +83,12 @@ export const GroupMembershipRow = ({
} - onClick={() => handlePopUpOpen("removeMemberFromGroup", { username })} + onClick={() => + handlePopUpOpen("removeMemberFromGroup", { + memberType: GroupMemberType.USER, + username + }) + } isDisabled={!isAllowed || isOidcManageGroupMembershipsEnabled} > Remove User From Group diff --git a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupProjectsSection/GroupProjectsSection.tsx b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupProjectsSection/GroupProjectsSection.tsx index d6997c6cb7..1ef653dc2a 100644 --- a/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupProjectsSection/GroupProjectsSection.tsx +++ b/frontend/src/pages/organization/GroupDetailsByIDPage/components/GroupProjectsSection/GroupProjectsSection.tsx @@ -41,7 +41,7 @@ export const GroupProjectsSection = ({ groupId, groupSlug }: Props) => { return (
-

Projects

+

Group Projects

{(isAllowed) => ( {children}

) : ( -

Not set

+

Not set

)} diff --git a/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx b/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx index c0117b758d..300d30119d 100644 --- a/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx +++ b/frontend/src/pages/organization/ProjectsPage/ProjectsPage.tsx @@ -33,7 +33,7 @@ export const ProjectsPage = () => { const hasChildRoute = matches.some( (match) => match.pathname.includes("/secret-management/") || - match.pathname.includes("/cert-management/") || + match.pathname.includes("/cert-manager/") || match.pathname.includes("/kms/") || match.pathname.includes("/pam/") || match.pathname.includes("/ssh/") || diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgProductSelectSection/OrgProductSelectSection.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgProductSelectSection/OrgProductSelectSection.tsx index e1fc2712d8..de1d584d1c 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgProductSelectSection/OrgProductSelectSection.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgProductSelectSection/OrgProductSelectSection.tsx @@ -13,7 +13,7 @@ export const OrgProductSelectSection = () => { enabled: true }, pkiProductEnabled: { - name: "Certificate Management", + name: "Certificate Manager", enabled: true }, kmsProductEnabled: { diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgSsoTab/OrgGeneralAuthSection.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgSsoTab/OrgGeneralAuthSection.tsx index d35a043235..517e233c46 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgSsoTab/OrgGeneralAuthSection.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgSsoTab/OrgGeneralAuthSection.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import { faInfoCircle } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { twMerge } from "tailwind-merge"; @@ -5,7 +6,8 @@ import { twMerge } from "tailwind-merge"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; -import { Switch, Tooltip } from "@app/components/v2"; +import { Button, Modal, ModalClose, ModalContent, Switch, Tooltip } from "@app/components/v2"; +import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2"; import { OrgPermissionActions, OrgPermissionSubjects, @@ -38,11 +40,71 @@ export const OrgGeneralAuthSection = ({ }) => { const { currentOrg } = useOrganization(); const { subscription } = useSubscription(); - const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([ + "upgradePlan", + "enforceSamlSsoConfirmation" + ] as const); const { mutateAsync } = useUpdateOrg(); const logout = useLogoutUser(); + const [bypassEnabledInModal, setBypassEnabledInModal] = useState(false); + const [enforcementTypeInModal, setEnforcementTypeInModal] = useState( + null + ); + + const handleEnforceSsoConfirm = async () => { + if (!currentOrg?.id || !enforcementTypeInModal) return; + + try { + if (bypassEnabledInModal && !currentOrg?.bypassOrgAuthEnabled) { + await mutateAsync({ + orgId: currentOrg?.id, + bypassOrgAuthEnabled: true + }); + } + + if (enforcementTypeInModal === EnforceAuthType.SAML) { + await mutateAsync({ + orgId: currentOrg?.id, + authEnforced: true + }); + + createNotification({ + text: "Successfully enabled org-level SAML SSO enforcement", + type: "success" + }); + + handlePopUpToggle("enforceSamlSsoConfirmation", false); + setBypassEnabledInModal(false); + setEnforcementTypeInModal(null); + + await logout.mutateAsync(); + window.open(`/api/v1/sso/redirect/saml2/organizations/${currentOrg.slug}`); + window.close(); + } else if (enforcementTypeInModal === EnforceAuthType.GOOGLE) { + await mutateAsync({ + orgId: currentOrg?.id, + googleSsoAuthEnforced: true + }); + + createNotification({ + text: "Successfully enabled org-level Google SSO enforcement", + type: "success" + }); + + handlePopUpToggle("enforceSamlSsoConfirmation", false); + setBypassEnabledInModal(false); + setEnforcementTypeInModal(null); + + await logout.mutateAsync(); + window.open(`/api/v1/sso/redirect/google?org_slug=${currentOrg.slug}`); + window.close(); + } + } catch (err) { + console.error(err); + } + }; const handleEnforceOrgAuthToggle = async (value: boolean, type: EnforceAuthType) => { if (!currentOrg?.id) return; @@ -53,20 +115,47 @@ export const OrgGeneralAuthSection = ({ return; } + if (value) { + setBypassEnabledInModal(currentOrg?.bypassOrgAuthEnabled ?? false); + setEnforcementTypeInModal(EnforceAuthType.SAML); + handlePopUpOpen("enforceSamlSsoConfirmation"); + return; + } + await mutateAsync({ orgId: currentOrg?.id, authEnforced: value }); - } else if (type === EnforceAuthType.GOOGLE) { + + createNotification({ + text: "Successfully disabled org-level SAML SSO enforcement", + type: "success" + }); + return; + } + + if (type === EnforceAuthType.GOOGLE) { if (!subscription?.enforceGoogleSSO) { handlePopUpOpen("upgradePlan"); return; } + if (value) { + setBypassEnabledInModal(currentOrg?.bypassOrgAuthEnabled ?? false); + setEnforcementTypeInModal(EnforceAuthType.GOOGLE); + handlePopUpOpen("enforceSamlSsoConfirmation"); + return; + } + await mutateAsync({ orgId: currentOrg?.id, googleSsoAuthEnforced: value }); + + createNotification({ + text: "Successfully disabled org-level Google SSO enforcement", + type: "success" + }); } else if (type === EnforceAuthType.OIDC) { if (!subscription?.oidcSSO) { handlePopUpOpen("upgradePlan"); @@ -77,29 +166,22 @@ export const OrgGeneralAuthSection = ({ orgId: currentOrg?.id, authEnforced: value }); + + createNotification({ + text: `Successfully ${value ? "enabled" : "disabled"} org-level OIDC SSO enforcement`, + type: "success" + }); + + if (value) { + await logout.mutateAsync(); + window.close(); + } } else { createNotification({ text: `Invalid auth enforcement type ${type}`, type: "error" }); } - - createNotification({ - text: `Successfully ${value ? "enabled" : "disabled"} org-level auth`, - type: "success" - }); - - if (value) { - await logout.mutateAsync(); - - if (type === EnforceAuthType.SAML) { - window.open(`/api/v1/sso/redirect/saml2/organizations/${currentOrg.slug}`); - } else if (type === EnforceAuthType.GOOGLE) { - window.open(`/api/v1/sso/redirect/google?org_slug=${currentOrg.slug}`); - } - - window.close(); - } }; const handleEnableBypassOrgAuthToggle = async (value: boolean) => { @@ -239,73 +321,143 @@ export const OrgGeneralAuthSection = ({

- {(currentOrg?.authEnforced || currentOrg?.googleSsoAuthEnforced) && ( -
-
-
- Enable Admin SSO Bypass - - - When enabling admin SSO bypass, we highly recommend enabling MFA enforcement - at the organization-level for security reasons. - -

- In case of a lockout, admins can use the{" "} - - Admin Login Portal - {" "} - at{" "} - - {window.location.origin}/login/admin - -

-
- } - > - - -
- - {(isAllowed) => ( - handleEnableBypassOrgAuthToggle(value)} - isDisabled={!isAllowed} - /> - )} - +
+
+
+ Enable Admin SSO Bypass + + + When enabling admin SSO bypass, we highly recommend enabling MFA enforcement at + the organization-level for security reasons. + +

+ In case of a lockout, admins can use the{" "} + + Admin Login Portal + {" "} + at{" "} + + {window.location.origin}/login/admin + +

+
+ } + > + +
-

- - Allow organization admins to bypass SSO login enforcement when your SSO provider is - unavailable, misconfigured, or inaccessible. - -

+ + {(isAllowed) => ( + handleEnableBypassOrgAuthToggle(value)} + isDisabled={!isAllowed} + /> + )} +
- )} +

+ + Allow organization admins to bypass SSO login enforcement when your SSO provider is + unavailable, misconfigured, or inaccessible. + +

+
handlePopUpToggle("upgradePlan", isOpen)} text="Your current plan does not include access to enforce SAML SSO. To unlock this feature, please upgrade to Infisical Pro plan." /> + { + handlePopUpToggle("enforceSamlSsoConfirmation", isOpen); + setBypassEnabledInModal(currentOrg?.bypassOrgAuthEnabled ?? false); + if (!isOpen) { + setEnforcementTypeInModal(null); + } + }} + > + + +

+ All users will be required to authenticate via{" "} + {enforcementTypeInModal === EnforceAuthType.SAML ? "SAML" : "Google"} SSO to access + this organization. Other authentication methods will be disabled. +

+

+ Before proceeding, ensure your{" "} + {enforcementTypeInModal === EnforceAuthType.SAML ? "SAML" : "Google"} provider is + available and properly configured to avoid access issues. +

+
+ + {!currentOrg?.bypassOrgAuthEnabled && ( +
+
+

Enable Admin SSO Bypass

+

+ Allow organization admins to bypass SSO login enforcement if they experience any + issues with their{" "} + {enforcementTypeInModal === EnforceAuthType.SAML ? "SAML" : "Google"} provider +

+
+ +
+ )} + +
+ + + + +
+
+
); }; diff --git a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx index 17224536da..d6ea4c4faa 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ProjectTemplatesTab/components/ProjectTemplateDetailsModal.tsx @@ -49,7 +49,7 @@ const PROJECT_TYPE_MENU_ITEMS = [ value: ProjectType.SecretManager }, { - label: "Certificates Management", + label: "Certificate Manager", value: ProjectType.CertificateManager }, { diff --git a/frontend/src/pages/pam/PamAccountsPage/components/AccountViewToggle.tsx b/frontend/src/pages/pam/PamAccountsPage/components/AccountViewToggle.tsx index 51e5685515..4448845cf2 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/AccountViewToggle.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/AccountViewToggle.tsx @@ -1,4 +1,7 @@ -import { Button } from "@app/components/v2"; +import { faBorderAll, faList } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { IconButton } from "@app/components/v2"; import { PamAccountView } from "@app/hooks/api/pam"; type Props = { @@ -9,30 +12,32 @@ type Props = { export const AccountViewToggle = ({ value, onChange }: Props) => { return (
- - + +
); }; diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountCard.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountCard.tsx new file mode 100644 index 0000000000..4edf39bcd8 --- /dev/null +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountCard.tsx @@ -0,0 +1,52 @@ +import { LogInIcon, PackageOpenIcon } from "lucide-react"; + +import { Badge, UnstableButton } from "@app/components/v3"; +import { PAM_RESOURCE_TYPE_MAP, TPamAccount } from "@app/hooks/api/pam"; + +type Props = { + account: TPamAccount; + onAccess: (resource: TPamAccount) => void; + accountPath?: string; +}; + +export const PamAccountCard = ({ account, onAccess, accountPath }: Props) => { + const { name, description, resource } = account; + + const { image, name: resourceTypeName } = PAM_RESOURCE_TYPE_MAP[account.resource.resourceType]; + + return ( + + ); +}; diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx index a2c668b279..c8196cf32a 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamAccountRow.tsx @@ -10,7 +10,7 @@ import { } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { formatDistance } from "date-fns"; -import { FolderIcon, PackageOpenIcon } from "lucide-react"; +import { PackageOpenIcon } from "lucide-react"; import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; @@ -39,8 +39,6 @@ type Props = { onUpdate: (resource: TPamAccount) => void; onDelete: (resource: TPamAccount) => void; search: string; - isFlatView: boolean; - accountPath?: string; isAccessLoading?: boolean; }; @@ -50,8 +48,6 @@ export const PamAccountRow = ({ onAccess, onUpdate, onDelete, - isFlatView, - accountPath, isAccessLoading }: Props) => { const { id, name } = account; @@ -95,14 +91,6 @@ export const PamAccountRow = ({ - {isFlatView && accountPath && ( - - - - - - - )} {"lastRotatedAt" in account && account.lastRotatedAt && ( { const navigate = useNavigate({ from: ROUTE_PATHS.Pam.AccountsPage.path }); const { accessAwsIam, loadingAccountId } = useAccessAwsIamAccount(); + const { mutateAsync: checkPolicyMatch } = useCheckPolicyMatch(); const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ "misc", @@ -128,7 +132,7 @@ export const PamAccountsTable = ({ projectId }: Props) => { setOrderDirection, setOrderBy } = usePagination(PamAccountOrderBy.Name, { - initPerPage: getUserTablePreference("pamAccountsTable", PreferenceKey.PerPage, 20), + initPerPage: getUserTablePreference("pamAccountsTable", PreferenceKey.PerPage, 18), initSearch }); @@ -231,10 +235,43 @@ export const PamAccountsTable = ({ projectId }: Props) => { const resources = resourcesData?.resources || []; + const accessAccount = async (account: TPamAccount) => { + let fullAccountPath = account.name; + const folderPath = account.folderId ? folderPaths[account.folderId] : undefined; + if (folderPath) { + fullAccountPath = `${folderPath}/${account.name}`; + } + + const { requiresApproval } = await checkPolicyMatch({ + policyType: ApprovalPolicyType.PamAccess, + projectId, + inputs: { + accountPath: fullAccountPath + } + }); + + if (requiresApproval) { + createNotification({ + text: "This account is protected by an approval policy, you must request access", + type: "info" + }); + + // Open request access modal with pre-populated path + handlePopUpOpen("requestAccount", { accountPath: fullAccountPath }); + return; + } + + // For AWS IAM, directly open console without modal + if (account.resource.resourceType === PamResourceType.AwsIam) { + accessAwsIam(account, fullAccountPath); + } else { + handlePopUpOpen("accessAccount", account); + } + }; + return ( -
- {accountView === PamAccountView.Nested && } -
+
+
{(isAllowed) => isAllowed && ( @@ -392,32 +429,64 @@ export const PamAccountsTable = ({ projectId }: Props) => { )}
- - - - - - - - - {isLoading && } - {!isLoading && ( - <> - {accountView !== PamAccountView.Flat && - foldersToRender.map((folder) => ( + {accountView === PamAccountView.Nested && } + {accountView === PamAccountView.Flat ? ( + <> +
+ {filteredAccounts.map((account) => ( + accessAccount(e)} + /> + ))} +
+ {!isLoading && isContentEmpty && ( + + )} + {Boolean(totalCount) && !isLoading && !isContentEmpty && ( + setPage(newPage)} + onChangePerPage={handlePerPageChange} + perPageList={[9, 18, 48, 99]} + /> + )} + + ) : ( + +
-
- Accounts - handleSort(PamAccountOrderBy.Name)} - > - - -
-
-
+ + + + + + + {isLoading && } + {!isLoading && ( + <> + {foldersToRender.map((folder) => ( { onDelete={(e) => handlePopUpOpen("deleteFolder", e)} /> ))} - {filteredAccounts.map((account) => ( - { - // For AWS IAM, directly open console without modal - if (e.resource.resourceType === PamResourceType.AwsIam) { - let fullAccountPath = e?.name; - const folderPath = e.folderId ? folderPaths[e.folderId] : undefined; - if (folderPath) { - const path = folderPath.replace(/^\/+|\/+$/g, ""); - fullAccountPath = `${path}/${e?.name}`; - } - - accessAwsIam(e, fullAccountPath); - } else { - handlePopUpOpen("accessAccount", e); - } - }} - onUpdate={(e) => handlePopUpOpen("updateAccount", e)} - onDelete={(e) => handlePopUpOpen("deleteAccount", e)} - /> - ))} - - )} - -
+
+ Accounts + handleSort(PamAccountOrderBy.Name)} + > + + +
+
+
- {Boolean(totalCount) && !isLoading && ( - setPage(newPage)} - onChangePerPage={handlePerPageChange} - /> - )} - {!isLoading && isContentEmpty && ( - - )} -
+ {filteredAccounts.map((account) => ( + accessAccount(e)} + onUpdate={(e) => handlePopUpOpen("updateAccount", e)} + onDelete={(e) => handlePopUpOpen("deleteAccount", e)} + /> + ))} + + )} + + + {!isLoading && isContentEmpty && ( + + )} + {Boolean(totalCount) && !isLoading && !isContentEmpty && ( + setPage(newPage)} + onChangePerPage={handlePerPageChange} + perPageList={[9, 18, 48, 99]} + /> + )} + + )} handlePopUpToggle("deleteFolder", isOpen)} @@ -504,6 +559,7 @@ export const PamAccountsTable = ({ projectId }: Props) => { handlePopUpToggle("requestAccount", isOpen)} + accountPath={popUp.requestAccount.data?.accountPath} /> { if (onComplete) onComplete(account); onOpenChange(false); + setSelectedResource(null); }} onBack={() => setSelectedResource(null)} resourceId={selectedResource.id} diff --git a/frontend/src/pages/pam/PamAccountsPage/components/PamRequestAccountAccessModal.tsx b/frontend/src/pages/pam/PamAccountsPage/components/PamRequestAccountAccessModal.tsx index 243c0c1328..b8b415ffb1 100644 --- a/frontend/src/pages/pam/PamAccountsPage/components/PamRequestAccountAccessModal.tsx +++ b/frontend/src/pages/pam/PamAccountsPage/components/PamRequestAccountAccessModal.tsx @@ -1,4 +1,3 @@ -import { useMemo } from "react"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import ms from "ms"; @@ -18,10 +17,8 @@ import { import { useProject } from "@app/context"; import { ApprovalPolicyType } from "@app/hooks/api/approvalPolicies"; import { useCreateApprovalRequest } from "@app/hooks/api/approvalRequests/mutations"; -import { TPamAccount } from "@app/hooks/api/pam"; type Props = { - account?: TPamAccount; accountPath?: string; isOpen: boolean; onOpenChange: (isOpen: boolean) => void; @@ -48,24 +45,15 @@ const formSchema = z.object({ type FormData = z.infer; -const Content = ({ onOpenChange, account, accountPath }: Props) => { +const Content = ({ onOpenChange, accountPath }: Props) => { const { projectId } = useProject(); const { mutateAsync: createApprovalRequest, isPending: isSubmitting } = useCreateApprovalRequest(); - const fullAccountPath = useMemo(() => { - const accountName = account?.name ?? ""; - if (accountPath) { - const path = accountPath.replace(/^\/+|\/+$/g, ""); - return `${path}/${accountName}`; - } - return accountName; - }, [account, accountPath]); - const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { - accountPath: fullAccountPath, + accountPath, accessDuration: "4h", justification: "" } @@ -74,7 +62,7 @@ const Content = ({ onOpenChange, account, accountPath }: Props) => { const { control, handleSubmit, - formState: { isDirty } + formState: { isValid } } = form; const onSubmit = async (formData: FormData) => { @@ -155,7 +143,7 @@ const Content = ({ onOpenChange, account, accountPath }: Props) => { type="submit" colorSchema="secondary" isLoading={isSubmitting} - isDisabled={isSubmitting || !isDirty} + isDisabled={isSubmitting || !isValid} > Request Access diff --git a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectIdentityModal.tsx b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectIdentityModal.tsx index 7e1e98c54b..7dc8e93fc4 100644 --- a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectIdentityModal.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectIdentityModal.tsx @@ -170,7 +170,7 @@ export const ProjectIdentityModal = ({ onClose, identity }: ContentProps) => { isError={Boolean(error)} errorText={error?.message} > - + )} /> diff --git a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx index 8e00c8e3be..71e289465b 100644 --- a/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/IdentityTab/components/ProjectLinkIdentityModal.tsx @@ -113,6 +113,7 @@ export const ProjectLinkIdentityModal = ({ handlePopUpToggle }: Props) => { onChange={onChange} isLoading={isMembershipsLoading} placeholder="Select machine identity..." + autoFocus // onInputChange={setSearchValue} options={filteredIdentityMembershipOrgs.map((membership) => ({ name: membership.name, diff --git a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/AddMemberModal.tsx b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/AddMemberModal.tsx index 7498b31819..c809528f3b 100644 --- a/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/AddMemberModal.tsx +++ b/frontend/src/pages/project/AccessControlPage/components/MembersTab/components/AddMemberModal.tsx @@ -151,6 +151,11 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => { type: "success" }); handlePopUpToggle("addMember", false); + if (requesterEmail) { + navigate({ + search: (prev) => ({ ...prev, requesterEmail: "" }) + }); + } reset(); }; @@ -203,7 +208,7 @@ export const AddMemberModal = ({ popUp, handlePopUpToggle }: Props) => { { - if (!isOpen) + if (!isOpen && requesterEmail) navigate({ search: (prev) => ({ ...prev, requesterEmail: "" }) }); diff --git a/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx b/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx index 2ecb6f2340..bdc0dc1958 100644 --- a/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/AccessControlPage/route-cert-manager.tsx @@ -12,7 +12,7 @@ const AccessControlPageQuerySchema = z.object({ }); export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management" )({ component: AccessControlPage, validateSearch: zodValidator(AccessControlPageQuerySchema), diff --git a/frontend/src/pages/project/AppConnectionsPage/route-cert-manager.tsx b/frontend/src/pages/project/AppConnectionsPage/route-cert-manager.tsx index 51e48ec098..b9f140526e 100644 --- a/frontend/src/pages/project/AppConnectionsPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/AppConnectionsPage/route-cert-manager.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { AppConnectionsPage } from "./AppConnectionsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections" )({ component: AppConnectionsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/project/AuditLogsPage/route-cert-manager.tsx b/frontend/src/pages/project/AuditLogsPage/route-cert-manager.tsx index e6f381a4bb..a16c38de79 100644 --- a/frontend/src/pages/project/AuditLogsPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/AuditLogsPage/route-cert-manager.tsx @@ -3,7 +3,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { AuditLogsPage } from "./AuditLogsPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs" )({ component: AuditLogsPage, beforeLoad: ({ context }) => { diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx index 23610006b9..f8854a2142 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembersTable.tsx @@ -1,17 +1,26 @@ -import { useEffect, useMemo } from "react"; +import { useEffect, useState } from "react"; import { faArrowDown, faArrowUp, + faCheckCircle, + faFilter, faFolder, faMagnifyingGlass, faSearch } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate, useSearch } from "@tanstack/react-router"; +import { HardDriveIcon, UserIcon } from "lucide-react"; +import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; import { ConfirmActionModal, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, EmptyState, IconButton, Input, @@ -35,19 +44,21 @@ import { usePagination, usePopUp, useResetPageHelper } from "@app/hooks"; import { useAssumeProjectPrivileges } from "@app/hooks/api"; import { ActorType } from "@app/hooks/api/auditLogs/enums"; import { OrderByDirection } from "@app/hooks/api/generic/types"; -import { useListProjectGroupUsers } from "@app/hooks/api/groups/queries"; -import { EFilterReturnedUsers, TGroupMembership } from "@app/hooks/api/groups/types"; +import { useListGroupMembers } from "@app/hooks/api/groups/queries"; +import { + FilterMemberType, + GroupMembersOrderBy, + GroupMemberType, + TGroupMembership +} from "@app/hooks/api/groups/types"; -import { GroupMembershipRow } from "./GroupMembershipRow"; +import { GroupMembershipIdentityRow } from "./GroupMembershipIdentityRow"; +import { GroupMembershipUserRow } from "./GroupMembershipUserRow"; type Props = { groupMembership: TGroupMembership; }; -enum GroupMembersOrderBy { - Name = "name" -} - export const GroupMembersTable = ({ groupMembership }: Props) => { const navigate = useNavigate(); const { @@ -59,7 +70,8 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { setPerPage, offset, orderDirection, - toggleOrderDirection + toggleOrderDirection, + orderBy } = usePagination(GroupMembersOrderBy.Name, { initPerPage: getUserTablePreference("projectGroupMembersTable", PreferenceKey.PerPage, 20) }); @@ -79,6 +91,8 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { } }, [username]); + const [memberTypeFilter, setMemberTypeFilter] = useState([]); + const { handlePopUpToggle, popUp, handlePopUpOpen } = usePopUp(["assumePrivileges"] as const); const handlePerPageChange = (newPerPage: number) => { @@ -89,50 +103,21 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { const { currentOrg } = useOrganization(); const { currentProject } = useProject(); - const { data: groupMemberships, isPending } = useListProjectGroupUsers({ + const { data: groupMemberships, isPending } = useListGroupMembers({ id: groupMembership.group.id, groupSlug: groupMembership.group.slug, - projectId: currentProject.id, offset, limit: perPage, search, - filter: EFilterReturnedUsers.EXISTING_MEMBERS + orderBy, + orderDirection, + memberTypeFilter: memberTypeFilter.length > 0 ? memberTypeFilter : undefined }); - const filteredGroupMemberships = useMemo(() => { - return groupMemberships && groupMemberships?.users - ? groupMemberships?.users - ?.filter((membership) => { - const userSearchString = `${membership.firstName && membership.firstName} ${ - membership.lastName && membership.lastName - } ${membership.email && membership.email} ${ - membership.username && membership.username - }`; - return userSearchString.toLowerCase().includes(search.trim().toLowerCase()); - }) - .sort((a, b) => { - const [membershipOne, membershipTwo] = - orderDirection === OrderByDirection.ASC ? [a, b] : [b, a]; - - const membershipOneComparisonString = membershipOne.firstName - ? membershipOne.firstName - : membershipOne.email; - - const membershipTwoComparisonString = membershipTwo.firstName - ? membershipTwo.firstName - : membershipTwo.email; - - const comparison = membershipOneComparisonString - .toLowerCase() - .localeCompare(membershipTwoComparisonString.toLowerCase()); - - return comparison; - }) - : []; - }, [groupMemberships, orderDirection, search]); + const { members = [], totalCount = 0 } = groupMemberships ?? {}; useResetPageHelper({ - totalCount: filteredGroupMemberships?.length, + totalCount, offset, setPage }); @@ -140,18 +125,24 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { const assumePrivileges = useAssumeProjectPrivileges(); const handleAssumePrivileges = async () => { - const { userId } = popUp?.assumePrivileges?.data as { userId: string }; + const { actorId, actorType } = popUp?.assumePrivileges?.data as { + actorId: string; + actorType: ActorType; + }; assumePrivileges.mutate( { - actorId: userId, - actorType: ActorType.USER, + actorId, + actorType, projectId: currentProject.id }, { onSuccess: () => { createNotification({ type: "success", - text: "User privilege assumption has started" + text: + actorType === ActorType.IDENTITY + ? "Machine identity privilege assumption has started" + : "User privilege assumption has started" }); const url = getProjectHomePage(currentProject.type, currentProject.environments); @@ -163,19 +154,84 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { ); }; + const filterOptions = [ + { + icon: , + label: "Users", + value: FilterMemberType.USERS + }, + { + icon: , + label: "Machine Identities", + value: FilterMemberType.MACHINE_IDENTITIES + } + ]; + return (
- setSearch(e.target.value)} - leftIcon={} - placeholder="Search users..." - /> +
+ setSearch(e.target.value)} + leftIcon={} + placeholder="Search members..." + /> + + + 0 && "border-primary/50 text-primary" + )} + > + + + + + Filter by Member Type + {filterOptions.map((option) => ( + { + e.preventDefault(); + setMemberTypeFilter((prev) => { + if (prev.includes(option.value)) { + return prev.filter((f) => f !== option.value); + } + return [...prev, option.value]; + }); + setPage(1); + }} + icon={ + memberTypeFilter.includes(option.value) && ( + + ) + } + > +
+ {option.icon} + {option.label} +
+
+ ))} +
+
+
- - @@ -198,42 +253,58 @@ export const GroupMembersTable = ({ groupMembership }: Props) => { {isPending && } {!isPending && - filteredGroupMemberships.slice(offset, perPage * page).map((userGroupMembership) => { - return ( - { + return userGroupMembership.type === GroupMemberType.USER ? ( + handlePopUpOpen("assumePrivileges", { userId })} + onAssumePrivileges={(userId) => + handlePopUpOpen("assumePrivileges", { + actorId: userId, + actorType: ActorType.USER + }) + } + /> + ) : ( + + handlePopUpOpen("assumePrivileges", { + actorId: identityId, + actorType: ActorType.IDENTITY + }) + } /> ); })}
+ +
Name {
Email Added On
- {Boolean(filteredGroupMemberships.length) && ( + {Boolean(totalCount) && ( )} - {!isPending && !filteredGroupMemberships?.length && ( + {!isPending && !members.length && ( )}
handlePopUpToggle("assumePrivileges", isOpen)} onConfirmed={handleAssumePrivileges} buttonText="Confirm" diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipIdentityRow.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipIdentityRow.tsx new file mode 100644 index 0000000000..2e00c43e51 --- /dev/null +++ b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipIdentityRow.tsx @@ -0,0 +1,81 @@ +import { faEllipsisV, faUser } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { HardDriveIcon } from "lucide-react"; + +import { ProjectPermissionCan } from "@app/components/permissions"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + IconButton, + Td, + Tooltip, + Tr +} from "@app/components/v2"; +import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/context"; +import { TGroupMemberMachineIdentity } from "@app/hooks/api/groups/types"; + +type Props = { + identity: TGroupMemberMachineIdentity; + onAssumePrivileges: (identityId: string) => void; +}; + +export const GroupMembershipIdentityRow = ({ + identity: { + machineIdentity: { name }, + joinedGroupAt, + id + }, + onAssumePrivileges +}: Props) => { + return ( + + + + + +

{name}

+ + + +

{new Date(joinedGroupAt).toLocaleDateString()}

+
+ + + + + + + + + + + + {(isAllowed) => { + return ( + } + onClick={() => onAssumePrivileges(id)} + isDisabled={!isAllowed} + > + Assume Privileges + + ); + }} + + + + + + + ); +}; diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx similarity index 77% rename from frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx rename to frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx index 55f5664773..3288bea81b 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipRow.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/components/GroupMembersSection/GroupMembershipUserRow.tsx @@ -1,5 +1,6 @@ import { faEllipsisV, faUser } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { UserIcon } from "lucide-react"; import { ProjectPermissionCan } from "@app/components/permissions"; import { @@ -13,28 +14,35 @@ import { Tr } from "@app/components/v2"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/context"; -import { TGroupUser } from "@app/hooks/api/groups/types"; +import { TGroupMemberUser } from "@app/hooks/api/groups/types"; type Props = { - user: TGroupUser; + user: TGroupMemberUser; onAssumePrivileges: (userId: string) => void; }; -export const GroupMembershipRow = ({ - user: { firstName, lastName, joinedGroupAt, email, id }, +export const GroupMembershipUserRow = ({ + user: { + user: { firstName, lastName, email }, + joinedGroupAt, + id + }, onAssumePrivileges }: Props) => { return ( - -

{`${firstName ?? "-"} ${lastName ?? ""}`}

+ + - -

{email}

+ +

+ {`${firstName ?? "-"} ${lastName ?? ""}`}{" "} + ({email}) +

-

{new Date(joinedGroupAt).toLocaleDateString()}

+

{new Date(joinedGroupAt).toLocaleDateString()}

diff --git a/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx index 84c1b320b5..e33bf7a9a2 100644 --- a/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/GroupDetailsByIDPage/route-cert-manager.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId" )({ component: GroupDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/access-management", + to: "/organizations/$orgId/projects/cert-manager/$projectId/access-management", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx index 486bcdae1a..5b7a9b7dcf 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/IdentityDetailsByIDPage.tsx @@ -1,7 +1,6 @@ import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; import { subject } from "@casl/ability"; -import { DropdownMenu } from "@radix-ui/react-dropdown-menu"; import { useQuery } from "@tanstack/react-query"; import { Link, useNavigate, useParams } from "@tanstack/react-router"; import { ChevronLeftIcon, EllipsisIcon, InfoIcon } from "lucide-react"; @@ -17,6 +16,7 @@ import { } from "@app/components/v2"; import { OrgIcon, + SubOrgIcon, UnstableAlert, UnstableAlertDescription, UnstableAlertTitle, @@ -26,6 +26,7 @@ import { UnstableCardDescription, UnstableCardHeader, UnstableCardTitle, + UnstableDropdownMenu, UnstableDropdownMenuContent, UnstableDropdownMenuItem, UnstableDropdownMenuTrigger, @@ -63,7 +64,7 @@ const Page = () => { select: (el) => el.identityId as string }); const { currentProject, projectId } = useProject(); - const { currentOrg } = useOrganization(); + const { currentOrg, isSubOrganization } = useOrganization(); const { data: identityMembershipDetails, isPending: isMembershipDetailsLoading } = useGetProjectIdentityMembershipV2(projectId, identityId); @@ -164,6 +165,12 @@ const Page = () => { return ; } + const isOrgIdentity = !isProjectIdentity; + const isSubOrgIdentity = + isOrgIdentity && + isSubOrganization && + currentOrg.rootOrgId !== identityMembershipDetails?.identity.orgId; + return (
{identityMembershipDetails ? ( @@ -187,7 +194,7 @@ const Page = () => { description={`Configure and manage${isProjectIdentity ? " machine identity and " : " "}project access control`} title={identityMembershipDetails.identity.name} > - + Options @@ -197,7 +204,7 @@ const Page = () => { { - navigator.clipboard.writeText(identityMembershipDetails.id); + navigator.clipboard.writeText(identityMembershipDetails.identity.id); createNotification({ text: "Machine identity ID copied to clipboard", type: "info" @@ -211,7 +218,6 @@ const Page = () => { a={subject(ProjectPermissionSub.Identity, { identityId: identityMembershipDetails?.identity.id })} - passThrough={false} > {(isAllowed) => ( { Assume Privileges
@@ -251,12 +257,13 @@ const Page = () => { )} - +
@@ -275,15 +282,15 @@ const Page = () => { - - + + {isSubOrgIdentity ? : } - Machine identity managed by organization + Machine identity managed by {isSubOrgIdentity ? "sub-" : ""}organization

- This machine identity's authentication methods are controlled by your - organization. To make changes,{" "} + This machine identity's authentication methods are managed by your + {isSubOrgIdentity ? "sub-" : ""}organization.
To make changes,{" "} { className="inline-block cursor-pointer text-foreground underline underline-offset-2" params={{ identityId, - orgId: currentOrg.id + orgId: identityMembershipDetails.identity.orgId }} > - go to organization access control + go to {isSubOrgIdentity ? "sub-" : ""}organization access control ) : null } diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx index b51501d481..9aa864b593 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeModifySection.tsx @@ -114,6 +114,7 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({ const { handleSubmit, + reset, formState: { isDirty, isSubmitting } } = form; @@ -310,7 +311,7 @@ export const IdentityProjectAdditionalPrivilegeModifySection = ({ variant="link" isDisabled={isSubmitting} isLoading={isSubmitting} - onClick={onGoBack} + onClick={() => reset()} > Discard Changes diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeSection.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeSection.tsx index cc686a2457..9d37c50d13 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeSection.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityProjectAdditionalPrivilegeSection/IdentityProjectAdditionalPrivilegeSection.tsx @@ -81,9 +81,7 @@ export const IdentityProjectAdditionalPrivilegeSection = ({ identityMembershipDe return ( <> - + Project Additional Privileges Assign one-off policies to this machine identity diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityRoleDetailsSection/IdentityRoleDetailsSection.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityRoleDetailsSection/IdentityRoleDetailsSection.tsx index 9d88924b31..b16b74690f 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityRoleDetailsSection/IdentityRoleDetailsSection.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/components/IdentityRoleDetailsSection/IdentityRoleDetailsSection.tsx @@ -96,9 +96,7 @@ export const IdentityRoleDetailsSection = ({ return ( <> - + Project Roles Manage roles assigned to this machine identity @@ -208,8 +206,6 @@ export const IdentityRoleDetailsSection = ({ a={subject(ProjectPermissionSub.Identity, { identityId: identityMembershipDetails.identity.id })} - renderTooltip - allowedLabel="Remove Role" > {(isAllowed) => ( - {/* */} Remove Role )} diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/components/ProjectIdentityDetailsSection.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/components/ProjectIdentityDetailsSection.tsx index f26dd60dae..34df3888b1 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/components/ProjectIdentityDetailsSection.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/components/ProjectIdentityDetailsSection.tsx @@ -12,6 +12,7 @@ import { DetailValue, OrgIcon, ProjectIcon, + SubOrgIcon, UnstableButtonGroup, UnstableCard, UnstableCardAction, @@ -30,10 +31,16 @@ import { ProjectIdentityModal } from "@app/pages/project/AccessControlPage/compo type Props = { identity: TProjectIdentity; isOrgIdentity?: boolean; + isSubOrgIdentity?: boolean; membership: IdentityProjectMembershipV1; }; -export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, membership }: Props) => { +export const ProjectIdentityDetailsSection = ({ + identity, + isOrgIdentity, + isSubOrgIdentity, + membership +}: Props) => { // eslint-disable-next-line @typescript-eslint/naming-convention,@typescript-eslint/no-unused-vars const [_, isCopyingId, setCopyTextId] = useTimedReset({ initialState: "Copy ID to clipboard" @@ -43,10 +50,8 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members return ( <> - - + + Details Machine identity details {!isOrgIdentity && ( @@ -92,7 +97,7 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members variant="ghost" size="xs" > - {/* TODO(scott): color this should be a button variant */} + {/* TODO(scott): color this should be a button variant and create re-usable copy button */} {isCopyingId ? : } @@ -102,9 +107,9 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members Managed by {isOrgIdentity ? ( - - - Organization + + {isSubOrgIdentity ? : } + {isSubOrgIdentity ? "Sub-" : ""}Organization ) : ( @@ -129,7 +134,7 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members )) ) : ( - No metadata + No metadata )} @@ -145,7 +150,7 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members {membership.lastLoginAuthMethod ? ( identityAuthToNameMap[membership.lastLoginAuthMethod] ) : ( - N/A + N/A )} @@ -155,7 +160,7 @@ export const ProjectIdentityDetailsSection = ({ identity, isOrgIdentity, members {membership.lastLoginTime ? ( format(membership.lastLoginTime, "PPpp") ) : ( - N/A + N/A )} diff --git a/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx index 934674252e..7d5fdf9116 100644 --- a/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/IdentityDetailsByIDPage/route-cert-manager.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId" )({ component: IdentityDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/access-management", + to: "/organizations/$orgId/projects/cert-manager/$projectId/access-management", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx index 46883733d7..095faed42f 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/MemberDetailsByIDPage.tsx @@ -3,25 +3,34 @@ import { useTranslation } from "react-i18next"; import { faChevronLeft } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Link, useNavigate, useParams } from "@tanstack/react-router"; -import { formatRelative } from "date-fns"; +import { EllipsisIcon, InfoIcon } from "lucide-react"; import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; import { - Button, ConfirmActionModal, DeleteActionModal, EmptyState, PageHeader, - Spinner + Spinner, + Tooltip } from "@app/components/v2"; +import { + Badge, + UnstableButton, + UnstableDropdownMenu, + UnstableDropdownMenuContent, + UnstableDropdownMenuItem, + UnstableDropdownMenuTrigger +} from "@app/components/v3"; import { ProjectPermissionActions, ProjectPermissionMemberActions, ProjectPermissionSub, useOrganization, - useProject + useProject, + useUser } from "@app/context"; import { getProjectBaseURL, getProjectHomePage } from "@app/helpers/project"; import { usePopUp } from "@app/hooks"; @@ -35,6 +44,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { MemberProjectAdditionalPrivilegeSection } from "./components/MemberProjectAdditionalPrivilegeSection"; import { MemberRoleDetailsSection } from "./components/MemberRoleDetailsSection"; +import { ProjectMemberDetailsSection } from "./components/ProjectMemberDetailsSection"; export const Page = () => { const navigate = useNavigate(); @@ -44,12 +54,14 @@ export const Page = () => { }); const { currentOrg } = useOrganization(); const { currentProject, projectId } = useProject(); + const { + user: { id: currentUserId } + } = useUser(); const { data: membershipDetails, isPending: isMembershipDetailsLoading } = useGetWorkspaceUserDetails(projectId, membershipId); - const { mutateAsync: removeUserFromWorkspace, isPending: isRemovingUserFromWorkspace } = - useDeleteUserFromWorkspace(); + const { mutateAsync: removeUserFromWorkspace } = useDeleteUserFromWorkspace(); const assumePrivileges = useAssumeProjectPrivileges(); const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ @@ -112,8 +124,10 @@ export const Page = () => { ); } + const isOwnProjectMembershipDetails = currentUserId === membershipDetails?.user?.id; + return ( -

+
{membershipDetails ? ( <> { search={{ selectedTab: ProjectAccessControlTabs.Member }} - className="mb-4 flex items-center gap-x-2 text-sm text-mineshaft-400" + className="mb-4 flex w-fit items-center gap-x-1 text-sm text-mineshaft-400 transition duration-100 hover:text-mineshaft-400/80" > Project Users @@ -135,62 +149,100 @@ export const Page = () => { title={ membershipDetails.user.firstName || membershipDetails.user.lastName ? `${membershipDetails.user.firstName} ${membershipDetails.user.lastName}` - : "-" + : membershipDetails.user.email || + membershipDetails.user.username || + membershipDetails.inviteEmail || + "Unnamed User" } - description={`User joined on ${membershipDetails?.createdAt && formatRelative(new Date(membershipDetails?.createdAt || ""), new Date())}`} + description="Configure and manage project access control" > - - {(isAllowed) => ( - - )} - - - - {(isAllowed) => ( - - )} - + {isOwnProjectMembershipDetails ? ( + + + Your project membership + + + ) : ( + + + + Options + + + + + { + navigator.clipboard.writeText(membershipDetails.user.id); + createNotification({ + text: "User ID copied to clipboard", + type: "info" + }); + }} + > + Copy User ID + + + {(isAllowed) => ( + + handlePopUpOpen("assumePrivileges", { + userId: membershipDetails.user.id + }) + } + > + Assume Privileges + +
+ +
+
+
+ )} +
+ + {(isAllowed) => ( + handlePopUpOpen("removeMember")} + > + Remove User From Project + + )} + +
+
+ )} - - handlePopUpOpen("upgradePlan", { - text: "Assigning custom roles to members can be unlocked if you upgrade to Infisical Pro plan." - }) - } - /> - +
+ +
+ + handlePopUpOpen("upgradePlan", { + text: "Assigning custom roles to members can be unlocked if you upgrade to Infisical Pro plan." + }) + } + /> + +
+
- - {popUp?.modifyPrivilege.isOpen ? ( - - handlePopUpClose("modifyPrivilege")} - projectMembershipId={membershipDetails?.id} - privilegeId={(popUp?.modifyPrivilege?.data as { id: string })?.id} - isDisabled={ - isOwnProjectMembershipDetails || - permission.cannot(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member) - } - /> - - ) : ( - -
-

- Project Additional Privileges -

- {userId !== membershipDetails?.user?.id && - membershipDetails?.status !== "invited" && ( - + + + Project Additional Privileges + Assign one-off policies to this user + {!isOwnProjectMembershipDetails && hasAdditionalPrivileges && ( + + + {(isAllowed) => ( + { + handlePopUpOpen("modifyPrivilege"); + }} + isDisabled={!isAllowed} > - {(isAllowed) => ( - { - handlePopUpOpen("modifyPrivilege"); - }} - isDisabled={!isAllowed} - > - - - )} - + + Add Additional Privileges + )} + + + )} + + + {/* eslint-disable-next-line no-nested-ternary */} + {isPending ? ( + // scott: todo proper loader +
+
-
- - - - - - - - - - {isPending && } - {!isPending && - userProjectPrivileges?.map((privilegeDetails) => { - const isTemporary = privilegeDetails?.isTemporary; - const isExpired = - privilegeDetails.isTemporary && - new Date() > new Date(privilegeDetails.temporaryAccessEndTime || ""); + ) : userProjectPrivileges?.length ? ( + + + + Name + Duration + {!isOwnProjectMembershipDetails && } + + + + {!isPending && + userProjectPrivileges?.map((privilegeDetails) => { + const isTemporary = privilegeDetails?.isTemporary; + const isExpired = + privilegeDetails.isTemporary && + new Date() > new Date(privilegeDetails.temporaryAccessEndTime || ""); - let text = "Permanent"; - let toolTipText = "Non-Expiring Access"; - if (privilegeDetails.isTemporary) { - if (isExpired) { - text = "Access Expired"; - toolTipText = "Timed Access Expired"; - } else { - text = formatDistance( - new Date(privilegeDetails.temporaryAccessEndTime || ""), - new Date() - ); - toolTipText = `Until ${format( - new Date(privilegeDetails.temporaryAccessEndTime || ""), - "yyyy-MM-dd hh:mm:ss aaa" - )}`; - } - } + let text = "Permanent"; + let toolTipText = "Non-Expiring Access"; + if (privilegeDetails.isTemporary) { + if (isExpired) { + text = "Access Expired"; + toolTipText = "Timed Access Expired"; + } else { + text = formatDistance( + new Date(privilegeDetails.temporaryAccessEndTime || ""), + new Date() + ); + toolTipText = `Until ${format( + new Date(privilegeDetails.temporaryAccessEndTime || ""), + "yyyy-MM-dd hh:mm:ss aaa" + )}`; + } + } - return ( - { - if (evt.key === "Enter") { - handlePopUpOpen("modifyPrivilege", privilegeDetails); - } - }} - onClick={() => handlePopUpOpen("modifyPrivilege", privilegeDetails)} - > - - - - - ); - })} - -
NameDuration -
{privilegeDetails.slug} - - - {text} - - - -
+ return ( + + + {privilegeDetails.slug} + + + {isTemporary ? ( + + + {isExpired ? : } + {text} + + + ) : ( + text + )} + + {!isOwnProjectMembershipDetails && ( + + + + + + + + {(isAllowed) => ( - { + e.stopPropagation(); + handlePopUpOpen("modifyPrivilege", privilegeDetails); + }} + > + Edit Additional Privilege + + )} + + + {(isAllowed) => ( + { e.stopPropagation(); - e.preventDefault(); handlePopUpOpen("deletePrivilege", { id: privilegeDetails?.id, slug: privilegeDetails?.slug }); }} > - - + Remove Additional Privilege + )} - - - -
-
- {!isPending && !userProjectPrivileges?.length && ( - - )} -
-
- handlePopUpToggle("deletePrivilege", isOpen)} - onDeleteApproved={() => handlePrivilegeDelete()} - /> - - )} - -
+ + + + )} + + ); + })} + + + ) : ( + + + This user has no additional privileges + + Add an additional privilege to grant one-off access policies + + + {!isOwnProjectMembershipDetails && ( + + + {(isAllowed) => ( + { + handlePopUpOpen("modifyPrivilege"); + }} + isDisabled={!isAllowed || isOwnProjectMembershipDetails} + > + + Add Additional Privileges + + )} + + + )} + + )} + + + handlePopUpToggle("modifyPrivilege", isOpen)} + > + + handlePopUpClose("modifyPrivilege")} + projectMembershipId={membershipDetails?.id} + privilegeId={(popUp?.modifyPrivilege?.data as { id: string })?.id} + isDisabled={ + isOwnProjectMembershipDetails || + permission.cannot(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member) + } + /> + + + handlePopUpToggle("deletePrivilege", isOpen)} + onDeleteApproved={() => handlePrivilegeDelete()} + /> + ); }; diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx index 6719d3785b..7185f5a2f0 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberProjectAdditionalPrivilegeSection/MembershipProjectAdditionalPrivilegeModifySection.tsx @@ -1,5 +1,5 @@ import { Controller, FormProvider, useForm } from "react-hook-form"; -import { faCaretDown, faChevronLeft, faClock, faSave } from "@fortawesome/free-solid-svg-icons"; +import { faCaretDown, faClock, faSave } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { format, formatDistance } from "date-fns"; @@ -20,6 +20,7 @@ import { Tag, Tooltip } from "@app/components/v2"; +import { UnstableSeparator } from "@app/components/v3"; import { ProjectPermissionMemberActions, ProjectPermissionSub, @@ -111,6 +112,7 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({ const { handleSubmit, + reset, formState: { isDirty, isSubmitting } } = form; @@ -176,59 +178,9 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({ } return ( -
+ -
- -
- {isDirty && ( - - )} -
- - -
-
-
-
-
Overview
-

- Additional privileges take precedence over roles when permissions conflict -

+
-
-
Policies
- {(isCreate || !isPending) && } -
- {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map((subject) => ( - - {renderConditionalComponents(subject, isDisabled)} - - ))} + +
+
+
Policies
+
+ {isDirty && ( + + )} +
+ +
+
+ {(isCreate || !isPending) && } +
+ {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map( + (permissionSubject) => ( + + {renderConditionalComponents(permissionSubject, isDisabled)} + + ) + )} +
+
+ +
+ +
diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberRoleDetailsSection/MemberRoleDetailsSection.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberRoleDetailsSection/MemberRoleDetailsSection.tsx index 2654e237e2..f935eb67b7 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberRoleDetailsSection/MemberRoleDetailsSection.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/components/MemberRoleDetailsSection/MemberRoleDetailsSection.tsx @@ -1,27 +1,35 @@ -import { faFolder, faPencil, faTrash } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { format, formatDistance } from "date-fns"; -import { twMerge } from "tailwind-merge"; +import { ClockAlertIcon, ClockIcon, EllipsisIcon, PencilIcon } from "lucide-react"; import { createNotification } from "@app/components/notifications"; import { ProjectPermissionCan } from "@app/components/permissions"; +import { DeleteActionModal, Lottie, Modal, ModalContent, Tooltip } from "@app/components/v2"; import { - DeleteActionModal, - EmptyState, - IconButton, - Modal, - ModalContent, - Table, - TableContainer, - TableSkeleton, - Tag, - TBody, - Td, - Th, - THead, - Tooltip, - Tr -} from "@app/components/v2"; + Badge, + UnstableButton, + UnstableCard, + UnstableCardAction, + UnstableCardContent, + UnstableCardDescription, + UnstableCardHeader, + UnstableCardTitle, + UnstableDropdownMenu, + UnstableDropdownMenuContent, + UnstableDropdownMenuItem, + UnstableDropdownMenuTrigger, + UnstableEmpty, + UnstableEmptyContent, + UnstableEmptyDescription, + UnstableEmptyHeader, + UnstableEmptyTitle, + UnstableIconButton, + UnstableTable, + UnstableTableBody, + UnstableTableCell, + UnstableTableHead, + UnstableTableHeader, + UnstableTableRow +} from "@app/components/v3/generic"; import { ProjectPermissionActions, ProjectPermissionSub, useProject, useUser } from "@app/context"; import { formatProjectRoleName } from "@app/helpers/roles"; import { usePopUp } from "@app/hooks"; @@ -88,131 +96,176 @@ export const MemberRoleDetailsSection = ({ handlePopUpClose("deleteRole"); }; + const hasRoles = Boolean(membershipDetails?.roles.length); + return ( -
-
-

Project Roles

- {!isOwnProjectMembershipDetails && membershipDetails?.status !== "invited" && ( - - {(isAllowed) => ( - { - handlePopUpOpen("modifyRole"); - }} - isDisabled={!isAllowed} + <> + + + Project Roles + Manage roles assigned to this user + {!isOwnProjectMembershipDetails && hasRoles && ( + + - - - )} - - )} -
-
- - - - - - - - - - {isMembershipDetailsLoading && ( - - )} - {!isMembershipDetailsLoading && - membershipDetails?.roles?.map((roleDetails) => { - const isTemporary = roleDetails?.isTemporary; - const isExpired = - roleDetails.isTemporary && - new Date() > new Date(roleDetails.temporaryAccessEndTime || ""); - - let text = "Permanent"; - let toolTipText = "Non-Expiring Access"; - if (roleDetails.isTemporary) { - if (isExpired) { - text = "Access Expired"; - toolTipText = "Timed Access Expired"; - } else { - text = formatDistance( - new Date(roleDetails.temporaryAccessEndTime || ""), - new Date() - ); - toolTipText = `Until ${format( - new Date(roleDetails.temporaryAccessEndTime || ""), - "yyyy-MM-dd hh:mm:ss aaa" - )}`; - } - } - - return ( - - - - - - ); - })} - -
RoleDuration -
- {roleDetails.role === "custom" - ? roleDetails.customRoleName - : formatProjectRoleName(roleDetails.role)} - - - - {text} - - - -
- - {(isAllowed) => ( - { - e.stopPropagation(); - handlePopUpOpen("deleteRole", { - id: roleDetails?.id, - slug: roleDetails?.customRoleName || roleDetails?.role - }); - }} - > - - - )} - -
-
- {!isMembershipDetailsLoading && !membershipDetails?.roles?.length && ( - + {(isAllowed) => ( + { + handlePopUpOpen("modifyRole"); + }} + isDisabled={!isAllowed} + > + + Edit Roles + + )} + + )} -
-
+ + + { + /* eslint-disable-next-line no-nested-ternary */ + isMembershipDetailsLoading ? ( + // scott: todo proper loader +
+ +
+ ) : hasRoles ? ( + + + + Role + Duration + {!isOwnProjectMembershipDetails && } + + + + {membershipDetails?.roles?.map((roleDetails) => { + const isTemporary = roleDetails?.isTemporary; + const isExpired = + roleDetails.isTemporary && + new Date() > new Date(roleDetails.temporaryAccessEndTime || ""); + + let text = "Permanent"; + let toolTipText = "Non-Expiring Access"; + if (roleDetails.isTemporary) { + if (isExpired) { + text = "Access Expired"; + toolTipText = "Timed Access Expired"; + } else { + text = formatDistance( + new Date(roleDetails.temporaryAccessEndTime || ""), + new Date() + ); + toolTipText = `Until ${format( + new Date(roleDetails.temporaryAccessEndTime || ""), + "yyyy-MM-dd hh:mm:ss aaa" + )}`; + } + } + + return ( + + + {roleDetails.role === "custom" + ? roleDetails.customRoleName + : formatProjectRoleName(roleDetails.role)} + + + {isTemporary ? ( + + + {isExpired ? : } + {text} + + + ) : ( + text + )} + + {!isOwnProjectMembershipDetails && ( + + + + + + + + + + {(isAllowed) => ( + { + e.stopPropagation(); + handlePopUpOpen("deleteRole", { + id: roleDetails?.id, + slug: roleDetails?.customRoleName || roleDetails?.role + }); + }} + isDisabled={!isAllowed} + variant="danger" + > + Remove Role + + )} + + + + + )} + + ); + })} + + + ) : ( + + + This user doesn t have any roles + + Give this user one or more roles + + + + + {(isAllowed) => ( + { + handlePopUpOpen("modifyRole"); + }} + isDisabled={!isAllowed || isOwnProjectMembershipDetails} + > + + Edit Roles + + )} + + + + ) + } +
+ + -
+ ); }; diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/components/ProjectMemberDetailsSection.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/components/ProjectMemberDetailsSection.tsx new file mode 100644 index 0000000000..09cd3593de --- /dev/null +++ b/frontend/src/pages/project/MemberDetailsByIDPage/components/ProjectMemberDetailsSection.tsx @@ -0,0 +1,105 @@ +import { format } from "date-fns"; +import { CheckIcon, ClipboardListIcon } from "lucide-react"; + +import { Tooltip } from "@app/components/v2"; +import { + Detail, + DetailGroup, + DetailLabel, + DetailValue, + UnstableCard, + UnstableCardContent, + UnstableCardDescription, + UnstableCardHeader, + UnstableCardTitle, + UnstableIconButton +} from "@app/components/v3"; +import { useTimedReset } from "@app/hooks"; +import { TWorkspaceUser } from "@app/hooks/api/types"; + +type Props = { + membership: TWorkspaceUser; +}; + +export const ProjectMemberDetailsSection = ({ membership }: Props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/naming-convention + const [_copyId, isCopyingId, setCopyTextId] = useTimedReset({ + initialState: "Copy ID to clipboard" + }); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/naming-convention + const [_copyEmail, isCopyingEmail, setCopyEmail] = useTimedReset({ + initialState: "Copy email to clipboard" + }); + + const { + user: { email, username, firstName, lastName, id: userId } + } = membership; + + const name = firstName || lastName ? `${firstName} ${lastName}`.trim() : null; + + return ( + + + Details + User membership details + + + + + Name + {name || Not set} + + + ID + + {membership.user.id} + + { + navigator.clipboard.writeText(userId); + setCopyTextId("Copied"); + }} + variant="ghost" + size="xs" + > + {/* TODO(scott): color this should be a button variant and create re-usable copy button */} + {isCopyingId ? : } + + + + + + Email + + {email} + + { + navigator.clipboard.writeText(email); + setCopyEmail("Copied"); + }} + variant="ghost" + size="xs" + > + {/* TODO(scott): color this should be a button variant and create re-usable copy button */} + {isCopyingEmail ? : } + + + + + {username !== email && ( + + Username + {username || Not set} + + )} + + Joined project + {format(membership.createdAt, "PPpp")} + + + + + ); +}; diff --git a/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx b/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx index fdbc5a0485..787ce9572e 100644 --- a/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/MemberDetailsByIDPage/route-cert-manager.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId" )({ component: MemberDetailsByIDPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/access-management", + to: "/organizations/$orgId/projects/cert-manager/$projectId/access-management", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx index 06ff997104..559deca382 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/route-cert-manager.tsx @@ -5,7 +5,7 @@ import { ProjectAccessControlTabs } from "@app/types/project"; import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage"; export const Route = createFileRoute( - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug" )({ component: RoleDetailsBySlugPage, beforeLoad: ({ context, params }) => { @@ -15,7 +15,7 @@ export const Route = createFileRoute( { label: "Access Control", link: linkOptions({ - to: "/organizations/$orgId/projects/cert-management/$projectId/access-management", + to: "/organizations/$orgId/projects/cert-manager/$projectId/access-management", params: { orgId: params.orgId, projectId: params.projectId diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.tsx index 9d5774d5dd..efc68ef53e 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.tsx @@ -1,7 +1,5 @@ import { Helmet } from "react-helmet"; import { useTranslation } from "react-i18next"; -import { faWarning } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate, useSearch } from "@tanstack/react-router"; import { ProjectPermissionCan } from "@app/components/permissions"; @@ -14,7 +12,6 @@ import { useProject } from "@app/context"; import { ProjectPermissionSecretSyncActions } from "@app/context/ProjectPermissionContext/types"; -import { useGetWorkspaceIntegrations } from "@app/hooks/api"; import { ProjectType } from "@app/hooks/api/projects/types"; import { IntegrationsListPageTabs } from "@app/types/integrations"; @@ -35,9 +32,6 @@ export const IntegrationsListPage = () => { from: ROUTE_PATHS.SecretManager.IntegrationsListPage.id }); - const { data: integrations } = useGetWorkspaceIntegrations(currentProject.id); - const hasNativeIntegrations = Boolean(integrations?.length); - const updateSelectedTab = (tab: string) => { navigate({ to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path, @@ -77,11 +71,9 @@ export const IntegrationsListPage = () => { Infrastructure Integrations - {hasNativeIntegrations && ( - - Native Integrations - - )} + + Native Integrations + { - {hasNativeIntegrations && ( - -
-
- -
-

- We're moving Native Integrations to{" "} - - Secret Syncs - - . -

-

- If the integration you need isn't available in the Secret Syncs menu, - please get in touch with us at{" "} - - team@infisical.com - - . -

-
-
-
- - - -
- )} + + + + +
diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx index bb9d02d3da..9332023f56 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/IntegrationsListPage.utils.tsx @@ -1,4 +1,10 @@ +import crypto from "crypto"; + +import { NavigateFn } from "@tanstack/react-router"; + import { createNotification } from "@app/components/notifications"; +import { localStorageService } from "@app/helpers/localStorage"; +import { TCloudIntegration } from "@app/hooks/api/types"; export const createIntegrationMissingEnvVarsNotification = ( slug: string, @@ -21,3 +27,349 @@ export const createIntegrationMissingEnvVarsNotification = ( ), title: "Missing Environment Variables" }); + +export const redirectForProviderAuth = ( + orgId: string, + projectId: string, + navigate: NavigateFn, + integrationOption: TCloudIntegration +) => { + try { + // generate CSRF token for OAuth2 code-token exchange integrations + const state = crypto.randomBytes(16).toString("hex"); + localStorage.setItem("latestCSRFToken", state); + localStorageService.setIntegrationProjectId(projectId); + + switch (integrationOption.slug) { + case "gcp-secret-manager": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize", + params: { + orgId, + projectId + } + }); + break; + case "azure-key-vault": { + if (!integrationOption.clientId) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug); + return; + } + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize", + params: { + orgId, + projectId + }, + search: { + clientId: integrationOption.clientId, + state + } + }); + break; + } + case "azure-app-configuration": { + if (!integrationOption.clientId) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug); + return; + } + const link = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${window.location.origin}/integrations/azure-app-configuration/oauth2/callback&response_mode=query&scope=https://azconfig.io/.default openid offline_access&state=${state}`; + window.location.assign(link); + break; + } + case "aws-parameter-store": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize", + params: { + orgId, + projectId + } + }); + break; + case "aws-secret-manager": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize", + params: { + orgId, + projectId + } + }); + break; + case "heroku": { + if (!integrationOption.clientId) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug); + return; + } + const link = `https://id.heroku.com/oauth/authorize?client_id=${integrationOption.clientId}&response_type=code&scope=write-protected&state=${state}`; + window.location.assign(link); + break; + } + case "vercel": { + if (!integrationOption.clientSlug) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug); + return; + } + const link = `https://vercel.com/integrations/${integrationOption.clientSlug}/new?state=${state}`; + window.location.assign(link); + break; + } + case "netlify": { + if (!integrationOption.clientId) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug); + return; + } + const link = `https://app.netlify.com/authorize?client_id=${integrationOption.clientId}&response_type=code&state=${state}&redirect_uri=${window.location.origin}/integrations/netlify/oauth2/callback`; + + window.location.assign(link); + break; + } + case "github": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection", + params: { + orgId, + projectId + } + }); + break; + case "gitlab": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize", + params: { + orgId, + projectId + } + }); + break; + case "render": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize", + params: { + orgId, + projectId + } + }); + break; + case "flyio": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize", + params: { + orgId, + projectId + } + }); + break; + case "circleci": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize", + params: { + orgId, + projectId + } + }); + break; + case "databricks": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize", + params: { + orgId, + projectId + } + }); + break; + case "laravel-forge": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize", + params: { + orgId, + projectId + } + }); + break; + case "travisci": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize", + params: { + orgId, + projectId + } + }); + break; + case "supabase": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize", + params: { + orgId, + projectId + } + }); + break; + case "checkly": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize", + params: { + orgId, + projectId + } + }); + break; + case "qovery": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize", + params: { + orgId, + projectId + } + }); + break; + case "railway": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize", + params: { + orgId, + projectId + } + }); + break; + case "terraform-cloud": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize", + params: { + orgId, + projectId + } + }); + break; + case "hashicorp-vault": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize", + params: { + orgId, + projectId + } + }); + break; + case "cloudflare-pages": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize", + params: { + orgId, + projectId + } + }); + break; + case "cloudflare-workers": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize", + params: { + orgId, + projectId + } + }); + break; + case "bitbucket": { + if (!integrationOption.clientId) { + createIntegrationMissingEnvVarsNotification(integrationOption.slug, "cicd"); + return; + } + const link = `https://bitbucket.org/site/oauth2/authorize?client_id=${integrationOption.clientId}&response_type=code&redirect_uri=${window.location.origin}/integrations/bitbucket/oauth2/callback&state=${state}`; + window.location.assign(link); + break; + } + case "codefresh": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize", + params: { + orgId, + projectId + } + }); + break; + case "digital-ocean-app-platform": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize", + params: { + orgId, + projectId + } + }); + break; + case "cloud-66": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize", + params: { + orgId, + projectId + } + }); + break; + case "northflank": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize", + params: { + orgId, + projectId + } + }); + break; + case "windmill": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize", + params: { + orgId, + projectId + } + }); + break; + case "teamcity": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize", + params: { + orgId, + projectId + } + }); + break; + case "hasura-cloud": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize", + params: { + orgId, + projectId + } + }); + break; + case "rundeck": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize", + params: { + orgId, + projectId + } + }); + break; + case "azure-devops": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize", + params: { + orgId, + projectId + } + }); + break; + case "octopus-deploy": + navigate({ + to: "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize", + params: { + orgId, + projectId + } + }); + break; + default: + break; + } + } catch (err) { + console.error(err); + } +}; diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/CloudIntegrationSection.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/CloudIntegrationSection.tsx new file mode 100644 index 0000000000..ff92f9f413 --- /dev/null +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/CloudIntegrationSection.tsx @@ -0,0 +1,258 @@ +import { useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { + faCheck, + faChevronLeft, + faMagnifyingGlass, + faSearch, + faXmark +} from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useNavigate } from "@tanstack/react-router"; + +import { NoEnvironmentsBanner } from "@app/components/integrations/NoEnvironmentsBanner"; +import { createNotification } from "@app/components/notifications"; +import { + Button, + DeleteActionModal, + EmptyState, + Input, + Skeleton, + Tooltip +} from "@app/components/v2"; +import { ROUTE_PATHS } from "@app/const/routes"; +import { + ProjectPermissionActions, + ProjectPermissionSub, + useOrganization, + useProject, + useProjectPermission +} from "@app/context"; +import { usePopUp } from "@app/hooks"; +import { SecretSync } from "@app/hooks/api/secretSyncs"; +import { IntegrationAuth, TCloudIntegration } from "@app/hooks/api/types"; +import { IntegrationsListPageTabs } from "@app/types/integrations"; + +type Props = { + isLoading?: boolean; + integrationAuths?: Record; + cloudIntegrations?: TCloudIntegration[]; + onIntegrationStart: (slug: string) => void; + // cb: handle popUpClose child->parent communication pattern + onIntegrationRevoke: (slug: string, cb: () => void) => void; + onViewActiveIntegrations?: () => void; +}; + +type TRevokeIntegrationPopUp = { provider: string }; + +const SECRET_SYNCS = Object.values(SecretSync) as string[]; +const isSecretSyncAvailable = (type: string) => SECRET_SYNCS.includes(type); + +export const CloudIntegrationSection = ({ + isLoading, + cloudIntegrations = [], + integrationAuths = {}, + onIntegrationStart, + onIntegrationRevoke, + onViewActiveIntegrations +}: Props) => { + const { t } = useTranslation(); + const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ + "deleteConfirmation" + ] as const); + const { permission } = useProjectPermission(); + const { currentOrg } = useOrganization(); + const { currentProject } = useProject(); + const navigate = useNavigate(); + + const isEmpty = !isLoading && !cloudIntegrations?.length; + + const sortedCloudIntegrations = useMemo(() => { + const sortedIntegrations = cloudIntegrations.sort((a, b) => a.name.localeCompare(b.name)); + + if (currentProject?.environments.length === 0) { + return sortedIntegrations.map((integration) => ({ ...integration, isAvailable: false })); + } + + return sortedIntegrations; + }, [cloudIntegrations, currentProject?.environments]); + + const [search, setSearch] = useState(""); + + const filteredIntegrations = sortedCloudIntegrations?.filter((cloudIntegration) => + cloudIntegration.name.toLowerCase().includes(search.toLowerCase().trim()) + ); + + return ( +
+ {currentProject?.environments.length === 0 && ( +
+ +
+ )} +
+ {onViewActiveIntegrations && ( + + )} +
+
+

{t("integrations.cloud-integrations")}

+

{t("integrations.click-to-start")}

+
+ setSearch(e.target.value)} + leftIcon={} + placeholder="Search cloud integrations..." + containerClassName="flex-1 h-min text-base" + /> +
+
+
+ {isLoading && + Array.from({ length: 12 }).map((_, index) => ( + + ))} + + {!isLoading && filteredIntegrations.length ? ( + filteredIntegrations.map((cloudIntegration) => { + const syncSlug = cloudIntegration.syncSlug ?? cloudIntegration.slug; + const isSyncAvailable = isSecretSyncAvailable(syncSlug); + + return ( +
null} + role="button" + tabIndex={0} + className={`group relative ${ + cloudIntegration.isAvailable + ? "cursor-pointer duration-200 hover:bg-mineshaft-700" + : "opacity-50" + } flex h-36 flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-3`} + onClick={() => { + if (isSyncAvailable) { + navigate({ + to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path, + params: { + orgId: currentOrg.id, + projectId: currentProject.id + }, + search: { + selectedTab: IntegrationsListPageTabs.SecretSyncs, + addSync: syncSlug as SecretSync + } + }); + return; + } + if (!cloudIntegration.isAvailable) return; + if ( + permission.cannot( + ProjectPermissionActions.Create, + ProjectPermissionSub.Integrations + ) + ) { + createNotification({ + type: "error", + text: "You do not have permission to create an integration" + }); + return; + } + onIntegrationStart(cloudIntegration.slug); + }} + key={cloudIntegration.slug} + > +
+ integration logo +
+ {cloudIntegration.name} +
+
+ {cloudIntegration.isAvailable && + Boolean(integrationAuths?.[cloudIntegration.slug]) && ( +
+
+
+ + Authorized +
+ +
null} + role="button" + tabIndex={0} + onClick={async (event) => { + event.stopPropagation(); + handlePopUpOpen("deleteConfirmation", { + provider: cloudIntegration.slug + }); + }} + className="absolute top-0 right-0 flex h-0 w-12 cursor-pointer items-center justify-center overflow-hidden rounded-r-md bg-red text-xs opacity-50 transition-all duration-300 group-hover:h-full hover:opacity-100" + > + +
+
+
+
+ )} + {isSyncAvailable && ( +
+
+
+ Secret Sync Available +
+
+
+ )} +
+ ); + }) + ) : ( + + )} +
+ {isEmpty && ( +
+ {Array.from({ length: 16 }).map((_, index) => ( +
+ ))} +
+ )} + handlePopUpToggle("deleteConfirmation", isOpen)} + deleteKey={(popUp?.deleteConfirmation?.data as TRevokeIntegrationPopUp)?.provider || ""} + onDeleteApproved={async () => { + onIntegrationRevoke( + (popUp.deleteConfirmation.data as TRevokeIntegrationPopUp)?.provider, + () => handlePopUpClose("deleteConfirmation") + ); + }} + /> +
+ ); +}; diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/index.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/index.tsx new file mode 100644 index 0000000000..62f7a006c4 --- /dev/null +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/CloudIntegrationSection/index.tsx @@ -0,0 +1 @@ +export { CloudIntegrationSection } from "./CloudIntegrationSection"; diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/NativeIntegrationsTab.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/NativeIntegrationsTab.tsx index b51c06df42..9670278578 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/NativeIntegrationsTab.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/NativeIntegrationsTab/NativeIntegrationsTab.tsx @@ -1,8 +1,11 @@ -import { useCallback, useEffect } from "react"; +import { useCallback, useEffect, useState } from "react"; +import { faPlus } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { useNavigate } from "@tanstack/react-router"; import { createNotification } from "@app/components/notifications"; -import { Checkbox, DeleteActionModal, Spinner } from "@app/components/v2"; -import { useProject } from "@app/context"; +import { Button, Checkbox, DeleteActionModal, Spinner } from "@app/components/v2"; +import { useOrganization, useProject } from "@app/context"; import { usePopUp, useToggle } from "@app/hooks"; import { useDeleteIntegration, @@ -14,26 +17,38 @@ import { import { IntegrationAuth } from "@app/hooks/api/integrationAuth/types"; import { TIntegration } from "@app/hooks/api/integrations/types"; +import { redirectForProviderAuth } from "../../IntegrationsListPage.utils"; +import { CloudIntegrationSection } from "../CloudIntegrationSection"; import { IntegrationsTable } from "./IntegrationsTable"; +enum IntegrationView { + List = "list", + New = "new" +} + export const NativeIntegrationsTab = () => { + const { currentOrg } = useOrganization(); const { currentProject } = useProject(); const { environments, id: workspaceId } = currentProject; + const navigate = useNavigate(); const { data: cloudIntegrations, isPending: isCloudIntegrationsLoading } = useGetCloudIntegrations(); - const { data: integrationAuths, isFetching: isIntegrationAuthFetching } = - useGetWorkspaceAuthorizations( - workspaceId, - useCallback((data: IntegrationAuth[]) => { - const groupBy: Record = {}; - data.forEach((el) => { - groupBy[el.integration] = el; - }); - return groupBy; - }, []) - ); + const { + data: integrationAuths, + isPending: isIntegrationAuthLoading, + isFetching: isIntegrationAuthFetching + } = useGetWorkspaceAuthorizations( + workspaceId, + useCallback((data: IntegrationAuth[]) => { + const groupBy: Record = {}; + data.forEach((el) => { + groupBy[el.integration] = el; + }); + return groupBy; + }, []) + ); // mutation const { @@ -43,8 +58,11 @@ export const NativeIntegrationsTab = () => { } = useGetWorkspaceIntegrations(workspaceId); const { mutateAsync: deleteIntegration } = useDeleteIntegration(); - - const { reset: resetDeleteIntegrationAuths } = useDeleteIntegrationAuths(); + const { + mutateAsync: deleteIntegrationAuths, + isSuccess: isDeleteIntegrationAuthSuccess, + reset: resetDeleteIntegrationAuths + } = useDeleteIntegrationAuths(); const isIntegrationsAuthorizedEmpty = !Object.keys(integrationAuths || {}).length; const isIntegrationsEmpty = !integrations?.length; @@ -53,6 +71,7 @@ export const NativeIntegrationsTab = () => { // After the refetch is completed check if its empty. Then set bot active and reset the submit hook for isSuccess to go back to false useEffect(() => { if ( + isDeleteIntegrationAuthSuccess && !isIntegrationFetching && !isIntegrationAuthFetching && isIntegrationsAuthorizedEmpty && @@ -62,11 +81,29 @@ export const NativeIntegrationsTab = () => { } }, [ isIntegrationFetching, + isDeleteIntegrationAuthSuccess, isIntegrationAuthFetching, isIntegrationsAuthorizedEmpty, isIntegrationsEmpty ]); + const handleProviderIntegration = async (provider: string) => { + const selectedCloudIntegration = cloudIntegrations?.find(({ slug }) => provider === slug); + if (!selectedCloudIntegration) return; + + try { + redirectForProviderAuth(currentOrg.id, currentProject.id, navigate, selectedCloudIntegration); + } catch (error) { + console.error(error); + } + }; + + // function to strat integration for a provider + // confirmation to user passing the bot key for provider to get secret access + const handleProviderIntegrationStart = (provider: string) => { + handleProviderIntegration(provider); + }; + const handleIntegrationDelete = async ( integrationId: string, shouldDeleteIntegrationSecrets: boolean, @@ -80,11 +117,28 @@ export const NativeIntegrationsTab = () => { }); }; + const handleIntegrationAuthRevoke = async (provider: string, cb?: () => void) => { + const integrationAuthForProvider = integrationAuths?.[provider]; + if (!integrationAuthForProvider) return; + + await deleteIntegrationAuths({ + integration: provider, + workspaceId + }); + if (cb) cb(); + createNotification({ + type: "success", + text: "Revoked provider authentication" + }); + }; + const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ "deleteConfirmation", "deleteSecretsConfirmation" ] as const); + const [view, setView] = useState(IntegrationView.List); + const [shouldDeleteSecrets, setShouldDeleteSecrets] = useToggle(false); if (isIntegrationLoading || isCloudIntegrationsLoading) @@ -96,10 +150,18 @@ export const NativeIntegrationsTab = () => { return ( <> - {integrations?.length && ( + {view === IntegrationView.List ? (

Native Integrations

+
{ }} />
+ ) : ( + setView(IntegrationView.List)} + /> )} { + const { primaryText, secondaryText } = getSecretSyncDestinationColValues(secretSync); + + return ; +}; diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx index 9857941443..d157453b30 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/SecretSyncDestinationCol/SecretSyncDestinationCol.tsx @@ -25,6 +25,7 @@ import { LaravelForgeSyncDestinationCol } from "./LaravelForgeSyncDestinationCol import { NetlifySyncDestinationCol } from "./NetlifySyncDestinationCol"; import { NorthflankSyncDestinationCol } from "./NorthflankSyncDestinationCol"; import { OCIVaultSyncDestinationCol } from "./OCIVaultSyncDestinationCol"; +import { OctopusDeploySyncDestinationCol } from "./OctopusDeploySyncDestinationCol"; import { RailwaySyncDestinationCol } from "./RailwaySyncDestinationCol"; import { RenderSyncDestinationCol } from "./RenderSyncDestinationCol"; import { SupabaseSyncDestinationCol } from "./SupabaseSyncDestinationCol"; @@ -106,6 +107,8 @@ export const SecretSyncDestinationCol = ({ secretSync }: Props) => { return ; case SecretSync.Chef: return ; + case SecretSync.OctopusDeploy: + return ; default: throw new Error( `Unhandled Secret Sync Destination Col: ${(secretSync as TSecretSync).destination}` diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts index de0aad100b..ebc1676448 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/components/SecretSyncsTab/SecretSyncTable/helpers/index.ts @@ -8,6 +8,7 @@ import { } from "@app/hooks/api/secretSyncs/types/github-sync"; import { GitLabSyncScope } from "@app/hooks/api/secretSyncs/types/gitlab-sync"; import { HumanitecSyncScope } from "@app/hooks/api/secretSyncs/types/humanitec-sync"; +import { OctopusDeploySyncScope } from "@app/hooks/api/secretSyncs/types/octopus-deploy-sync"; import { RenderSyncScope } from "@app/hooks/api/secretSyncs/types/render-sync"; // This functional ensures parity across what is displayed in the destination column @@ -206,6 +207,13 @@ export const getSecretSyncDestinationColValues = (secretSync: TSecretSync) => { primaryText = destinationConfig.dataBagName; secondaryText = destinationConfig.dataBagItemName; break; + case SecretSync.OctopusDeploy: + primaryText = destinationConfig.scope; + if (destinationConfig.scope === OctopusDeploySyncScope.Project) { + primaryText = destinationConfig.projectName || destinationConfig.projectId; + } + secondaryText = destinationConfig.spaceName || destinationConfig.spaceId; + break; default: throw new Error(`Unhandled Destination Col Values ${destination}`); } diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/OctopusDeploySyncDestinationSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/OctopusDeploySyncDestinationSection.tsx new file mode 100644 index 0000000000..4431d99c59 --- /dev/null +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/OctopusDeploySyncDestinationSection.tsx @@ -0,0 +1,99 @@ +import { GenericFieldLabel } from "@app/components/secret-syncs"; +import { useOctopusDeployConnectionGetScopeValues } from "@app/hooks/api/appConnections/octopus-deploy"; +import { + OctopusDeploySyncScope, + TOctopusDeploySync +} from "@app/hooks/api/secretSyncs/types/octopus-deploy-sync"; + +type Props = { + secretSync: TOctopusDeploySync; +}; + +export const OctopusDeploySyncDestinationSection = ({ secretSync }: Props) => { + const { + destinationConfig: { spaceId, scope, spaceName, scopeValues, projectId, projectName }, + connectionId + } = secretSync; + + const { data: scopeValuesData, isFetched } = useOctopusDeployConnectionGetScopeValues( + connectionId, + spaceId, + projectId, + { + enabled: Boolean(connectionId && spaceId && projectId && scope) + } + ); + + const { + environments = [], + channels = [], + processes = [], + roles = [], + actions = [], + machines = [] + } = scopeValues ?? {}; + + return ( + <> + {spaceName || spaceId} + + {scope} + + {scope === OctopusDeploySyncScope.Project && ( + {projectName || projectId} + )} + {isFetched && ( + <> + {environments.length > 0 && ( + + {scopeValuesData?.environments + .filter((env) => environments.includes(env.id)) + .map((env) => env.name) + .join(", ") ?? environments.join(", ")} + + )} + {roles.length > 0 && ( + + {scopeValuesData?.roles + .filter((role) => roles.includes(role.id)) + .map((role) => role.name) + .join(", ") ?? roles.join(", ")} + + )} + {machines.length > 0 && ( + + {scopeValuesData?.machines + .filter((machine) => machines.includes(machine.id)) + .map((machine) => machine.name) + .join(", ") ?? machines.join(", ")} + + )} + {processes.length > 0 && ( + + {scopeValuesData?.processes + .filter((process) => processes.includes(process.id)) + .map((process) => process.name) + .join(", ") ?? processes.join(", ")} + + )} + {actions.length > 0 && ( + + {scopeValuesData?.actions + .filter((action) => actions.includes(action.id)) + .map((action) => action.name) + .join(", ") ?? actions.join(", ")} + + )} + {channels.length > 0 && ( + + {scopeValuesData?.channels + .filter((channel) => channels.includes(channel.id)) + .map((channel) => channel.name) + .join(", ") ?? channels.join(", ")} + + )} + + )} + + ); +}; diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx index de527d6c8a..d4727c4678 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncDestinationSection/SecretSyncDestinatonSection.tsx @@ -36,6 +36,7 @@ import { LaravelForgeSyncDestinationSection } from "./LaravelForgeSyncDestinatio import { NetlifySyncDestinationSection } from "./NetlifySyncDestinationSection"; import { NorthflankSyncDestinationSection } from "./NorthflankSyncDestinationSection"; import { OCIVaultSyncDestinationSection } from "./OCIVaultSyncDestinationSection"; +import { OctopusDeploySyncDestinationSection } from "./OctopusDeploySyncDestinationSection"; import { RailwaySyncDestinationSection } from "./RailwaySyncDestinationSection"; import { RenderSyncDestinationSection } from "./RenderSyncDestinationSection"; import { SupabaseSyncDestinationSection } from "./SupabaseSyncDestinationSection"; @@ -160,6 +161,9 @@ export const SecretSyncDestinationSection = ({ secretSync, onEditDestination }: case SecretSync.Chef: DestinationComponents = ; break; + case SecretSync.OctopusDeploy: + DestinationComponents = ; + break; default: throw new Error(`Unhandled Destination Section components: ${destination}`); } diff --git a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx index a8de5b379f..923b20cf0a 100644 --- a/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx +++ b/frontend/src/pages/secret-manager/SecretSyncDetailsByIDPage/components/SecretSyncOptionsSection/SecretSyncOptionsSection.tsx @@ -75,6 +75,7 @@ export const SecretSyncOptionsSection = ({ secretSync, onEditOptions }: Props) = case SecretSync.Bitbucket: case SecretSync.LaravelForge: case SecretSync.Chef: + case SecretSync.OctopusDeploy: AdditionalSyncOptionsComponent = null; break; default: diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index a538a02cf5..9e2541d64c 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -8,4029 +8,3917 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute } from "@tanstack/react-router"; // Import Routes -import { Route as rootRoute } from './pages/root' -import { Route as middlewaresRestrictLoginSignupImport } from './pages/middlewares/restrict-login-signup' -import { Route as middlewaresAuthenticateImport } from './pages/middlewares/authenticate' -import { Route as publicUpgradePathPageRouteImport } from './pages/public/UpgradePathPage/route' -import { Route as publicShareSecretPageRouteImport } from './pages/public/ShareSecretPage/route' -import { Route as authCliRedirectPageRouteImport } from './pages/auth/CliRedirectPage/route' -import { Route as indexImport } from './pages/index' -import { Route as middlewaresInjectOrgDetailsImport } from './pages/middlewares/inject-org-details' -import { Route as authVerifyEmailPageRouteImport } from './pages/auth/VerifyEmailPage/route' -import { Route as authSignUpInvitePageRouteImport } from './pages/auth/SignUpInvitePage/route' -import { Route as authRequestNewInvitePageRouteImport } from './pages/auth/RequestNewInvitePage/route' -import { Route as authPasswordResetPageRouteImport } from './pages/auth/PasswordResetPage/route' -import { Route as authEmailNotVerifiedPageRouteImport } from './pages/auth/EmailNotVerifiedPage/route' -import { Route as authPasswordSetupPageRouteImport } from './pages/auth/PasswordSetupPage/route' -import { Route as userLayoutImport } from './pages/user/layout' -import { Route as organizationLayoutImport } from './pages/organization/layout' -import { Route as publicViewSharedSecretByIDPageRouteImport } from './pages/public/ViewSharedSecretByIDPage/route' -import { Route as publicViewSecretRequestByIDPageRouteImport } from './pages/public/ViewSecretRequestByIDPage/route' -import { Route as authSignUpSsoPageRouteImport } from './pages/auth/SignUpSsoPage/route' -import { Route as authLoginSsoPageRouteImport } from './pages/auth/LoginSsoPage/route' -import { Route as authSelectOrgPageRouteImport } from './pages/auth/SelectOrgPage/route' -import { Route as authLoginLdapPageRouteImport } from './pages/auth/LoginLdapPage/route' -import { Route as authAdminLoginPageRouteImport } from './pages/auth/AdminLoginPage/route' -import { Route as adminSignUpPageRouteImport } from './pages/admin/SignUpPage/route' -import { Route as organizationNoOrgPageRouteImport } from './pages/organization/NoOrgPage/route' -import { Route as authSignUpPageRouteImport } from './pages/auth/SignUpPage/route' -import { Route as authLoginPageRouteImport } from './pages/auth/LoginPage/route' -import { Route as redirectsProjectRedirectImport } from './pages/redirects/project-redirect' -import { Route as redirectsOrganizationRedirectImport } from './pages/redirects/organization-redirect' -import { Route as adminLayoutImport } from './pages/admin/layout' -import { Route as authProviderSuccessPageRouteImport } from './pages/auth/ProviderSuccessPage/route' -import { Route as authProviderErrorPageRouteImport } from './pages/auth/ProviderErrorPage/route' -import { Route as userPersonalSettingsPageRouteImport } from './pages/user/PersonalSettingsPage/route' -import { Route as adminIntegrationsPageRouteImport } from './pages/admin/IntegrationsPage/route' -import { Route as adminEnvironmentPageRouteImport } from './pages/admin/EnvironmentPage/route' -import { Route as adminEncryptionPageRouteImport } from './pages/admin/EncryptionPage/route' -import { Route as adminCachingPageRouteImport } from './pages/admin/CachingPage/route' -import { Route as adminAuthenticationPageRouteImport } from './pages/admin/AuthenticationPage/route' -import { Route as adminAccessManagementPageRouteImport } from './pages/admin/AccessManagementPage/route' -import { Route as adminGeneralPageRouteImport } from './pages/admin/GeneralPage/route' -import { Route as adminResourceOverviewPageRouteImport } from './pages/admin/ResourceOverviewPage/route' -import { Route as organizationProjectsPageRouteImport } from './pages/organization/ProjectsPage/route' -import { Route as organizationNetworkingPageRouteImport } from './pages/organization/NetworkingPage/route' -import { Route as organizationBillingPageRouteImport } from './pages/organization/BillingPage/route' -import { Route as organizationAuditLogsPageRouteImport } from './pages/organization/AuditLogsPage/route' -import { Route as organizationAccessManagementPageRouteImport } from './pages/organization/AccessManagementPage/route' -import { Route as secretManagerIntegrationsRouteVercelOauthRedirectImport } from './pages/secret-manager/integrations/route-vercel-oauth-redirect' -import { Route as secretManagerIntegrationsRouteNetlifyOauthRedirectImport } from './pages/secret-manager/integrations/route-netlify-oauth-redirect' -import { Route as secretManagerIntegrationsRouteHerokuOauthRedirectImport } from './pages/secret-manager/integrations/route-heroku-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGitlabOauthRedirectImport } from './pages/secret-manager/integrations/route-gitlab-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGithubOauthRedirectImport } from './pages/secret-manager/integrations/route-github-oauth-redirect' -import { Route as secretManagerIntegrationsRouteGcpOauthRedirectImport } from './pages/secret-manager/integrations/route-gcp-oauth-redirect' -import { Route as secretManagerIntegrationsRouteBitbucketOauthRedirectImport } from './pages/secret-manager/integrations/route-bitbucket-oauth-redirect' -import { Route as secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect' -import { Route as secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport } from './pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect' -import { Route as organizationRoleByIDPageRouteImport } from './pages/organization/RoleByIDPage/route' -import { Route as organizationUserDetailsByIDPageRouteImport } from './pages/organization/UserDetailsByIDPage/route' -import { Route as organizationIdentityDetailsByIDPageRouteImport } from './pages/organization/IdentityDetailsByIDPage/route' -import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route' -import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route' -import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route' -import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route' -import { Route as secretManagerRedirectsRedirectApprovalPageImport } from './pages/secret-manager/redirects/redirect-approval-page' -import { Route as organizationSettingsPageOauthCallbackPageRouteImport } from './pages/organization/SettingsPage/OauthCallbackPage/route' -import { Route as sshLayoutImport } from './pages/ssh/layout' -import { Route as secretScanningLayoutImport } from './pages/secret-scanning/layout' -import { Route as secretManagerLayoutImport } from './pages/secret-manager/layout' -import { Route as pamLayoutImport } from './pages/pam/layout' -import { Route as kmsLayoutImport } from './pages/kms/layout' -import { Route as certManagerLayoutImport } from './pages/cert-manager/layout' -import { Route as organizationAppConnectionsOauthCallbackPageRouteImport } from './pages/organization/AppConnections/OauthCallbackPage/route' -import { Route as projectAuditLogsPageRouteSshImport } from './pages/project/AuditLogsPage/route-ssh' -import { Route as projectAccessControlPageRouteSshImport } from './pages/project/AccessControlPage/route-ssh' -import { Route as projectAuditLogsPageRouteSecretScanningImport } from './pages/project/AuditLogsPage/route-secret-scanning' -import { Route as projectAppConnectionsPageRouteSecretScanningImport } from './pages/project/AppConnectionsPage/route-secret-scanning' -import { Route as projectAccessControlPageRouteSecretScanningImport } from './pages/project/AccessControlPage/route-secret-scanning' -import { Route as projectAuditLogsPageRouteSecretManagerImport } from './pages/project/AuditLogsPage/route-secret-manager' -import { Route as projectAppConnectionsPageRouteSecretManagerImport } from './pages/project/AppConnectionsPage/route-secret-manager' -import { Route as projectAccessControlPageRouteSecretManagerImport } from './pages/project/AccessControlPage/route-secret-manager' -import { Route as projectAuditLogsPageRoutePamImport } from './pages/project/AuditLogsPage/route-pam' -import { Route as projectAccessControlPageRoutePamImport } from './pages/project/AccessControlPage/route-pam' -import { Route as projectAuditLogsPageRouteKmsImport } from './pages/project/AuditLogsPage/route-kms' -import { Route as projectAccessControlPageRouteKmsImport } from './pages/project/AccessControlPage/route-kms' -import { Route as projectAuditLogsPageRouteCertManagerImport } from './pages/project/AuditLogsPage/route-cert-manager' -import { Route as projectAppConnectionsPageRouteCertManagerImport } from './pages/project/AppConnectionsPage/route-cert-manager' -import { Route as projectAccessControlPageRouteCertManagerImport } from './pages/project/AccessControlPage/route-cert-manager' -import { Route as sshSettingsPageRouteImport } from './pages/ssh/SettingsPage/route' -import { Route as sshSshHostsPageRouteImport } from './pages/ssh/SshHostsPage/route' -import { Route as sshSshCertsPageRouteImport } from './pages/ssh/SshCertsPage/route' -import { Route as sshSshCasPageRouteImport } from './pages/ssh/SshCasPage/route' -import { Route as secretScanningSettingsPageRouteImport } from './pages/secret-scanning/SettingsPage/route' -import { Route as secretScanningSecretScanningFindingsPageRouteImport } from './pages/secret-scanning/SecretScanningFindingsPage/route' -import { Route as secretManagerSettingsPageRouteImport } from './pages/secret-manager/SettingsPage/route' -import { Route as secretManagerSecretRotationPageRouteImport } from './pages/secret-manager/SecretRotationPage/route' -import { Route as secretManagerOverviewPageRouteImport } from './pages/secret-manager/OverviewPage/route' -import { Route as secretManagerSecretApprovalsPageRouteImport } from './pages/secret-manager/SecretApprovalsPage/route' -import { Route as secretManagerIPAllowlistPageRouteImport } from './pages/secret-manager/IPAllowlistPage/route' -import { Route as pamSettingsPageRouteImport } from './pages/pam/SettingsPage/route' -import { Route as pamPamResourcesPageRouteImport } from './pages/pam/PamResourcesPage/route' -import { Route as pamApprovalsPageRouteImport } from './pages/pam/ApprovalsPage/route' -import { Route as pamPamAccountsPageRouteImport } from './pages/pam/PamAccountsPage/route' -import { Route as kmsSettingsPageRouteImport } from './pages/kms/SettingsPage/route' -import { Route as kmsOverviewPageRouteImport } from './pages/kms/OverviewPage/route' -import { Route as kmsKmipPageRouteImport } from './pages/kms/KmipPage/route' -import { Route as certManagerSettingsPageRouteImport } from './pages/cert-manager/SettingsPage/route' -import { Route as certManagerPoliciesPageRouteImport } from './pages/cert-manager/PoliciesPage/route' -import { Route as certManagerCertificateAuthoritiesPageRouteImport } from './pages/cert-manager/CertificateAuthoritiesPage/route' -import { Route as certManagerAlertingPageRouteImport } from './pages/cert-manager/AlertingPage/route' -import { Route as projectRoleDetailsBySlugPageRouteSshImport } from './pages/project/RoleDetailsBySlugPage/route-ssh' -import { Route as projectMemberDetailsByIDPageRouteSshImport } from './pages/project/MemberDetailsByIDPage/route-ssh' -import { Route as projectIdentityDetailsByIDPageRouteSshImport } from './pages/project/IdentityDetailsByIDPage/route-ssh' -import { Route as projectGroupDetailsByIDPageRouteSshImport } from './pages/project/GroupDetailsByIDPage/route-ssh' -import { Route as projectRoleDetailsBySlugPageRouteSecretScanningImport } from './pages/project/RoleDetailsBySlugPage/route-secret-scanning' -import { Route as projectMemberDetailsByIDPageRouteSecretScanningImport } from './pages/project/MemberDetailsByIDPage/route-secret-scanning' -import { Route as projectIdentityDetailsByIDPageRouteSecretScanningImport } from './pages/project/IdentityDetailsByIDPage/route-secret-scanning' -import { Route as projectGroupDetailsByIDPageRouteSecretScanningImport } from './pages/project/GroupDetailsByIDPage/route-secret-scanning' -import { Route as projectRoleDetailsBySlugPageRouteSecretManagerImport } from './pages/project/RoleDetailsBySlugPage/route-secret-manager' -import { Route as projectMemberDetailsByIDPageRouteSecretManagerImport } from './pages/project/MemberDetailsByIDPage/route-secret-manager' -import { Route as projectIdentityDetailsByIDPageRouteSecretManagerImport } from './pages/project/IdentityDetailsByIDPage/route-secret-manager' -import { Route as projectGroupDetailsByIDPageRouteSecretManagerImport } from './pages/project/GroupDetailsByIDPage/route-secret-manager' -import { Route as projectRoleDetailsBySlugPageRoutePamImport } from './pages/project/RoleDetailsBySlugPage/route-pam' -import { Route as projectMemberDetailsByIDPageRoutePamImport } from './pages/project/MemberDetailsByIDPage/route-pam' -import { Route as projectIdentityDetailsByIDPageRoutePamImport } from './pages/project/IdentityDetailsByIDPage/route-pam' -import { Route as projectGroupDetailsByIDPageRoutePamImport } from './pages/project/GroupDetailsByIDPage/route-pam' -import { Route as projectRoleDetailsBySlugPageRouteKmsImport } from './pages/project/RoleDetailsBySlugPage/route-kms' -import { Route as projectMemberDetailsByIDPageRouteKmsImport } from './pages/project/MemberDetailsByIDPage/route-kms' -import { Route as projectIdentityDetailsByIDPageRouteKmsImport } from './pages/project/IdentityDetailsByIDPage/route-kms' -import { Route as projectGroupDetailsByIDPageRouteKmsImport } from './pages/project/GroupDetailsByIDPage/route-kms' -import { Route as projectRoleDetailsBySlugPageRouteCertManagerImport } from './pages/project/RoleDetailsBySlugPage/route-cert-manager' -import { Route as certManagerPkiCollectionDetailsByIDPageRoutesImport } from './pages/cert-manager/PkiCollectionDetailsByIDPage/routes' -import { Route as projectMemberDetailsByIDPageRouteCertManagerImport } from './pages/project/MemberDetailsByIDPage/route-cert-manager' -import { Route as projectIdentityDetailsByIDPageRouteCertManagerImport } from './pages/project/IdentityDetailsByIDPage/route-cert-manager' -import { Route as projectGroupDetailsByIDPageRouteCertManagerImport } from './pages/project/GroupDetailsByIDPage/route-cert-manager' -import { Route as sshSshHostGroupDetailsByIDPageRouteImport } from './pages/ssh/SshHostGroupDetailsByIDPage/route' -import { Route as sshSshCaByIDPageRouteImport } from './pages/ssh/SshCaByIDPage/route' -import { Route as secretManagerSecretDashboardPageRouteImport } from './pages/secret-manager/SecretDashboardPage/route' -import { Route as secretManagerIntegrationsSelectIntegrationAuthPageRouteImport } from './pages/secret-manager/integrations/SelectIntegrationAuthPage/route' -import { Route as secretManagerIntegrationsDetailsByIDPageRouteImport } from './pages/secret-manager/IntegrationsDetailsByIDPage/route' -import { Route as pamPamSessionsByIDPageRouteImport } from './pages/pam/PamSessionsByIDPage/route' -import { Route as pamApprovalRequestDetailPageRouteImport } from './pages/pam/ApprovalRequestDetailPage/route' -import { Route as certManagerPkiSubscriberDetailsByIDPageRouteImport } from './pages/cert-manager/PkiSubscriberDetailsByIDPage/route' -import { Route as certManagerPkiSyncDetailsByIDPageRouteImport } from './pages/cert-manager/PkiSyncDetailsByIDPage/route' -import { Route as certManagerCertAuthDetailsByIDPageRouteImport } from './pages/cert-manager/CertAuthDetailsByIDPage/route' -import { Route as secretScanningSecretScanningDataSourcesPageRouteImport } from './pages/secret-scanning/SecretScanningDataSourcesPage/route' -import { Route as secretManagerIntegrationsListPageRouteImport } from './pages/secret-manager/IntegrationsListPage/route' -import { Route as pamPamSessionsPageRouteImport } from './pages/pam/PamSessionsPage/route' -import { Route as certManagerPkiSubscribersPageRouteImport } from './pages/cert-manager/PkiSubscribersPage/route' -import { Route as certManagerIntegrationsListPageRouteImport } from './pages/cert-manager/IntegrationsListPage/route' -import { Route as certManagerPkiTemplateListPageRouteImport } from './pages/cert-manager/PkiTemplateListPage/route' -import { Route as secretScanningSecretScanningDataSourceByIdPageRouteImport } from './pages/secret-scanning/SecretScanningDataSourceByIdPage/route' -import { Route as secretManagerIntegrationsWindmillConfigurePageRouteImport } from './pages/secret-manager/integrations/WindmillConfigurePage/route' -import { Route as secretManagerIntegrationsWindmillAuthorizePageRouteImport } from './pages/secret-manager/integrations/WindmillAuthorizePage/route' -import { Route as secretManagerIntegrationsVercelConfigurePageRouteImport } from './pages/secret-manager/integrations/VercelConfigurePage/route' -import { Route as secretManagerIntegrationsTravisCIConfigurePageRouteImport } from './pages/secret-manager/integrations/TravisCIConfigurePage/route' -import { Route as secretManagerIntegrationsTravisCIAuthorizePageRouteImport } from './pages/secret-manager/integrations/TravisCIAuthorizePage/route' -import { Route as secretManagerIntegrationsTerraformCloudConfigurePageRouteImport } from './pages/secret-manager/integrations/TerraformCloudConfigurePage/route' -import { Route as secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport } from './pages/secret-manager/integrations/TerraformCloudAuthorizePage/route' -import { Route as secretManagerIntegrationsTeamcityConfigurePageRouteImport } from './pages/secret-manager/integrations/TeamcityConfigurePage/route' -import { Route as secretManagerIntegrationsTeamcityAuthorizePageRouteImport } from './pages/secret-manager/integrations/TeamcityAuthorizePage/route' -import { Route as secretManagerIntegrationsSupabaseConfigurePageRouteImport } from './pages/secret-manager/integrations/SupabaseConfigurePage/route' -import { Route as secretManagerIntegrationsSupabaseAuthorizePageRouteImport } from './pages/secret-manager/integrations/SupabaseAuthorizePage/route' -import { Route as secretManagerIntegrationsRundeckConfigurePageRouteImport } from './pages/secret-manager/integrations/RundeckConfigurePage/route' -import { Route as secretManagerIntegrationsRundeckAuthorizePageRouteImport } from './pages/secret-manager/integrations/RundeckAuthorizePage/route' -import { Route as secretManagerIntegrationsRenderConfigurePageRouteImport } from './pages/secret-manager/integrations/RenderConfigurePage/route' -import { Route as secretManagerIntegrationsRenderAuthorizePageRouteImport } from './pages/secret-manager/integrations/RenderAuthorizePage/route' -import { Route as secretManagerIntegrationsRailwayConfigurePageRouteImport } from './pages/secret-manager/integrations/RailwayConfigurePage/route' -import { Route as secretManagerIntegrationsRailwayAuthorizePageRouteImport } from './pages/secret-manager/integrations/RailwayAuthorizePage/route' -import { Route as secretManagerIntegrationsQoveryConfigurePageRouteImport } from './pages/secret-manager/integrations/QoveryConfigurePage/route' -import { Route as secretManagerIntegrationsQoveryAuthorizePageRouteImport } from './pages/secret-manager/integrations/QoveryAuthorizePage/route' -import { Route as secretManagerIntegrationsOctopusDeployConfigurePageRouteImport } from './pages/secret-manager/integrations/OctopusDeployConfigurePage/route' -import { Route as secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport } from './pages/secret-manager/integrations/OctopusDeployAuthorizePage/route' -import { Route as secretManagerIntegrationsNorthflankConfigurePageRouteImport } from './pages/secret-manager/integrations/NorthflankConfigurePage/route' -import { Route as secretManagerIntegrationsNorthflankAuthorizePageRouteImport } from './pages/secret-manager/integrations/NorthflankAuthorizePage/route' -import { Route as secretManagerIntegrationsNetlifyConfigurePageRouteImport } from './pages/secret-manager/integrations/NetlifyConfigurePage/route' -import { Route as secretManagerIntegrationsLaravelForgeConfigurePageRouteImport } from './pages/secret-manager/integrations/LaravelForgeConfigurePage/route' -import { Route as secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport } from './pages/secret-manager/integrations/LaravelForgeAuthorizePage/route' -import { Route as secretManagerIntegrationsHerokuConfigurePageRouteImport } from './pages/secret-manager/integrations/HerokuConfigurePage/route' -import { Route as secretManagerIntegrationsHasuraCloudConfigurePageRouteImport } from './pages/secret-manager/integrations/HasuraCloudConfigurePage/route' -import { Route as secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport } from './pages/secret-manager/integrations/HasuraCloudAuthorizePage/route' -import { Route as secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport } from './pages/secret-manager/integrations/HashicorpVaultConfigurePage/route' -import { Route as secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport } from './pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route' -import { Route as secretManagerIntegrationsGitlabConfigurePageRouteImport } from './pages/secret-manager/integrations/GitlabConfigurePage/route' -import { Route as secretManagerIntegrationsGitlabAuthorizePageRouteImport } from './pages/secret-manager/integrations/GitlabAuthorizePage/route' -import { Route as secretManagerIntegrationsGithubConfigurePageRouteImport } from './pages/secret-manager/integrations/GithubConfigurePage/route' -import { Route as secretManagerIntegrationsGithubAuthorizePageRouteImport } from './pages/secret-manager/integrations/GithubAuthorizePage/route' -import { Route as secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport } from './pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route' -import { Route as secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport } from './pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route' -import { Route as secretManagerIntegrationsFlyioConfigurePageRouteImport } from './pages/secret-manager/integrations/FlyioConfigurePage/route' -import { Route as secretManagerIntegrationsFlyioAuthorizePageRouteImport } from './pages/secret-manager/integrations/FlyioAuthorizePage/route' -import { Route as secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport } from './pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route' -import { Route as secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport } from './pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route' -import { Route as secretManagerIntegrationsDatabricksConfigurePageRouteImport } from './pages/secret-manager/integrations/DatabricksConfigurePage/route' -import { Route as secretManagerIntegrationsDatabricksAuthorizePageRouteImport } from './pages/secret-manager/integrations/DatabricksAuthorizePage/route' -import { Route as secretManagerIntegrationsCodefreshConfigurePageRouteImport } from './pages/secret-manager/integrations/CodefreshConfigurePage/route' -import { Route as secretManagerIntegrationsCodefreshAuthorizePageRouteImport } from './pages/secret-manager/integrations/CodefreshAuthorizePage/route' -import { Route as secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport } from './pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route' -import { Route as secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport } from './pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route' -import { Route as secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport } from './pages/secret-manager/integrations/CloudflarePagesConfigurePage/route' -import { Route as secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport } from './pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route' -import { Route as secretManagerIntegrationsCloud66ConfigurePageRouteImport } from './pages/secret-manager/integrations/Cloud66ConfigurePage/route' -import { Route as secretManagerIntegrationsCloud66AuthorizePageRouteImport } from './pages/secret-manager/integrations/Cloud66AuthorizePage/route' -import { Route as secretManagerIntegrationsCircleCIConfigurePageRouteImport } from './pages/secret-manager/integrations/CircleCIConfigurePage/route' -import { Route as secretManagerIntegrationsCircleCIAuthorizePageRouteImport } from './pages/secret-manager/integrations/CircleCIAuthorizePage/route' -import { Route as secretManagerIntegrationsChecklyConfigurePageRouteImport } from './pages/secret-manager/integrations/ChecklyConfigurePage/route' -import { Route as secretManagerIntegrationsChecklyAuthorizePageRouteImport } from './pages/secret-manager/integrations/ChecklyAuthorizePage/route' -import { Route as secretManagerIntegrationsBitbucketConfigurePageRouteImport } from './pages/secret-manager/integrations/BitbucketConfigurePage/route' -import { Route as secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport } from './pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route' -import { Route as secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport } from './pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route' -import { Route as secretManagerIntegrationsAzureDevopsConfigurePageRouteImport } from './pages/secret-manager/integrations/AzureDevopsConfigurePage/route' -import { Route as secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport } from './pages/secret-manager/integrations/AzureDevopsAuthorizePage/route' -import { Route as secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport } from './pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route' -import { Route as secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport } from './pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route' -import { Route as secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport } from './pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route' -import { Route as secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport } from './pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route' -import { Route as secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport } from './pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route' -import { Route as secretManagerIntegrationsVercelOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/VercelOauthCallbackPage/route' -import { Route as secretManagerSecretSyncDetailsByIDPageRouteImport } from './pages/secret-manager/SecretSyncDetailsByIDPage/route' -import { Route as secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/NetlifyOauthCallbackPage/route' -import { Route as secretManagerIntegrationsHerokuOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/HerokuOauthCallbackPage/route' -import { Route as secretManagerIntegrationsGitlabOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/GitlabOauthCallbackPage/route' -import { Route as secretManagerIntegrationsGithubOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/GithubOauthCallbackPage/route' -import { Route as secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route' -import { Route as secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/BitbucketOauthCallbackPage/route' -import { Route as secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route' -import { Route as secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport } from './pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route' -import { Route as secretManagerCommitsPageRouteImport } from './pages/secret-manager/CommitsPage/route' -import { Route as secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport } from './pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route' -import { Route as secretManagerCommitDetailsPageRouteImport } from './pages/secret-manager/CommitDetailsPage/route' +import { Route as rootRoute } from "./pages/root"; +import { Route as middlewaresRestrictLoginSignupImport } from "./pages/middlewares/restrict-login-signup"; +import { Route as middlewaresAuthenticateImport } from "./pages/middlewares/authenticate"; +import { Route as publicUpgradePathPageRouteImport } from "./pages/public/UpgradePathPage/route"; +import { Route as publicShareSecretPageRouteImport } from "./pages/public/ShareSecretPage/route"; +import { Route as authCliRedirectPageRouteImport } from "./pages/auth/CliRedirectPage/route"; +import { Route as indexImport } from "./pages/index"; +import { Route as middlewaresInjectOrgDetailsImport } from "./pages/middlewares/inject-org-details"; +import { Route as authVerifyEmailPageRouteImport } from "./pages/auth/VerifyEmailPage/route"; +import { Route as authSignUpInvitePageRouteImport } from "./pages/auth/SignUpInvitePage/route"; +import { Route as authRequestNewInvitePageRouteImport } from "./pages/auth/RequestNewInvitePage/route"; +import { Route as authPasswordResetPageRouteImport } from "./pages/auth/PasswordResetPage/route"; +import { Route as authEmailNotVerifiedPageRouteImport } from "./pages/auth/EmailNotVerifiedPage/route"; +import { Route as authPasswordSetupPageRouteImport } from "./pages/auth/PasswordSetupPage/route"; +import { Route as userLayoutImport } from "./pages/user/layout"; +import { Route as organizationLayoutImport } from "./pages/organization/layout"; +import { Route as publicViewSharedSecretByIDPageRouteImport } from "./pages/public/ViewSharedSecretByIDPage/route"; +import { Route as publicViewSecretRequestByIDPageRouteImport } from "./pages/public/ViewSecretRequestByIDPage/route"; +import { Route as authSignUpSsoPageRouteImport } from "./pages/auth/SignUpSsoPage/route"; +import { Route as authLoginSsoPageRouteImport } from "./pages/auth/LoginSsoPage/route"; +import { Route as authSelectOrgPageRouteImport } from "./pages/auth/SelectOrgPage/route"; +import { Route as authLoginLdapPageRouteImport } from "./pages/auth/LoginLdapPage/route"; +import { Route as authAdminLoginPageRouteImport } from "./pages/auth/AdminLoginPage/route"; +import { Route as adminSignUpPageRouteImport } from "./pages/admin/SignUpPage/route"; +import { Route as organizationNoOrgPageRouteImport } from "./pages/organization/NoOrgPage/route"; +import { Route as authSignUpPageRouteImport } from "./pages/auth/SignUpPage/route"; +import { Route as authLoginPageRouteImport } from "./pages/auth/LoginPage/route"; +import { Route as redirectsProjectRedirectImport } from "./pages/redirects/project-redirect"; +import { Route as redirectsOrganizationRedirectImport } from "./pages/redirects/organization-redirect"; +import { Route as adminLayoutImport } from "./pages/admin/layout"; +import { Route as authProviderSuccessPageRouteImport } from "./pages/auth/ProviderSuccessPage/route"; +import { Route as authProviderErrorPageRouteImport } from "./pages/auth/ProviderErrorPage/route"; +import { Route as userPersonalSettingsPageRouteImport } from "./pages/user/PersonalSettingsPage/route"; +import { Route as adminIntegrationsPageRouteImport } from "./pages/admin/IntegrationsPage/route"; +import { Route as adminEnvironmentPageRouteImport } from "./pages/admin/EnvironmentPage/route"; +import { Route as adminEncryptionPageRouteImport } from "./pages/admin/EncryptionPage/route"; +import { Route as adminCachingPageRouteImport } from "./pages/admin/CachingPage/route"; +import { Route as adminAuthenticationPageRouteImport } from "./pages/admin/AuthenticationPage/route"; +import { Route as adminAccessManagementPageRouteImport } from "./pages/admin/AccessManagementPage/route"; +import { Route as adminGeneralPageRouteImport } from "./pages/admin/GeneralPage/route"; +import { Route as adminResourceOverviewPageRouteImport } from "./pages/admin/ResourceOverviewPage/route"; +import { Route as organizationProjectsPageRouteImport } from "./pages/organization/ProjectsPage/route"; +import { Route as organizationNetworkingPageRouteImport } from "./pages/organization/NetworkingPage/route"; +import { Route as organizationBillingPageRouteImport } from "./pages/organization/BillingPage/route"; +import { Route as organizationAuditLogsPageRouteImport } from "./pages/organization/AuditLogsPage/route"; +import { Route as organizationAccessManagementPageRouteImport } from "./pages/organization/AccessManagementPage/route"; +import { Route as secretManagerIntegrationsRouteVercelOauthRedirectImport } from "./pages/secret-manager/integrations/route-vercel-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteNetlifyOauthRedirectImport } from "./pages/secret-manager/integrations/route-netlify-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteHerokuOauthRedirectImport } from "./pages/secret-manager/integrations/route-heroku-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteGitlabOauthRedirectImport } from "./pages/secret-manager/integrations/route-gitlab-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteGithubOauthRedirectImport } from "./pages/secret-manager/integrations/route-github-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteGcpOauthRedirectImport } from "./pages/secret-manager/integrations/route-gcp-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteBitbucketOauthRedirectImport } from "./pages/secret-manager/integrations/route-bitbucket-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport } from "./pages/secret-manager/integrations/route-azure-key-vault-oauth-redirect"; +import { Route as secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport } from "./pages/secret-manager/integrations/route-azure-app-configurations-oauth-redirect"; +import { Route as organizationRoleByIDPageRouteImport } from "./pages/organization/RoleByIDPage/route"; +import { Route as organizationUserDetailsByIDPageRouteImport } from "./pages/organization/UserDetailsByIDPage/route"; +import { Route as organizationIdentityDetailsByIDPageRouteImport } from "./pages/organization/IdentityDetailsByIDPage/route"; +import { Route as organizationGroupDetailsByIDPageRouteImport } from "./pages/organization/GroupDetailsByIDPage/route"; +import { Route as organizationSettingsPageRouteImport } from "./pages/organization/SettingsPage/route"; +import { Route as organizationSecretSharingPageRouteImport } from "./pages/organization/SecretSharingPage/route"; +import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from "./pages/organization/AppConnections/AppConnectionsPage/route"; +import { Route as secretManagerRedirectsRedirectApprovalPageImport } from "./pages/secret-manager/redirects/redirect-approval-page"; +import { Route as organizationSettingsPageOauthCallbackPageRouteImport } from "./pages/organization/SettingsPage/OauthCallbackPage/route"; +import { Route as sshLayoutImport } from "./pages/ssh/layout"; +import { Route as secretScanningLayoutImport } from "./pages/secret-scanning/layout"; +import { Route as secretManagerLayoutImport } from "./pages/secret-manager/layout"; +import { Route as pamLayoutImport } from "./pages/pam/layout"; +import { Route as kmsLayoutImport } from "./pages/kms/layout"; +import { Route as certManagerLayoutImport } from "./pages/cert-manager/layout"; +import { Route as organizationAppConnectionsOauthCallbackPageRouteImport } from "./pages/organization/AppConnections/OauthCallbackPage/route"; +import { Route as projectAuditLogsPageRouteSshImport } from "./pages/project/AuditLogsPage/route-ssh"; +import { Route as projectAccessControlPageRouteSshImport } from "./pages/project/AccessControlPage/route-ssh"; +import { Route as projectAuditLogsPageRouteSecretScanningImport } from "./pages/project/AuditLogsPage/route-secret-scanning"; +import { Route as projectAppConnectionsPageRouteSecretScanningImport } from "./pages/project/AppConnectionsPage/route-secret-scanning"; +import { Route as projectAccessControlPageRouteSecretScanningImport } from "./pages/project/AccessControlPage/route-secret-scanning"; +import { Route as projectAuditLogsPageRouteSecretManagerImport } from "./pages/project/AuditLogsPage/route-secret-manager"; +import { Route as projectAppConnectionsPageRouteSecretManagerImport } from "./pages/project/AppConnectionsPage/route-secret-manager"; +import { Route as projectAccessControlPageRouteSecretManagerImport } from "./pages/project/AccessControlPage/route-secret-manager"; +import { Route as projectAuditLogsPageRoutePamImport } from "./pages/project/AuditLogsPage/route-pam"; +import { Route as projectAccessControlPageRoutePamImport } from "./pages/project/AccessControlPage/route-pam"; +import { Route as projectAuditLogsPageRouteKmsImport } from "./pages/project/AuditLogsPage/route-kms"; +import { Route as projectAccessControlPageRouteKmsImport } from "./pages/project/AccessControlPage/route-kms"; +import { Route as projectAuditLogsPageRouteCertManagerImport } from "./pages/project/AuditLogsPage/route-cert-manager"; +import { Route as projectAppConnectionsPageRouteCertManagerImport } from "./pages/project/AppConnectionsPage/route-cert-manager"; +import { Route as projectAccessControlPageRouteCertManagerImport } from "./pages/project/AccessControlPage/route-cert-manager"; +import { Route as sshSettingsPageRouteImport } from "./pages/ssh/SettingsPage/route"; +import { Route as sshSshHostsPageRouteImport } from "./pages/ssh/SshHostsPage/route"; +import { Route as sshSshCertsPageRouteImport } from "./pages/ssh/SshCertsPage/route"; +import { Route as sshSshCasPageRouteImport } from "./pages/ssh/SshCasPage/route"; +import { Route as secretScanningSettingsPageRouteImport } from "./pages/secret-scanning/SettingsPage/route"; +import { Route as secretScanningSecretScanningFindingsPageRouteImport } from "./pages/secret-scanning/SecretScanningFindingsPage/route"; +import { Route as secretManagerSettingsPageRouteImport } from "./pages/secret-manager/SettingsPage/route"; +import { Route as secretManagerSecretRotationPageRouteImport } from "./pages/secret-manager/SecretRotationPage/route"; +import { Route as secretManagerOverviewPageRouteImport } from "./pages/secret-manager/OverviewPage/route"; +import { Route as secretManagerSecretApprovalsPageRouteImport } from "./pages/secret-manager/SecretApprovalsPage/route"; +import { Route as secretManagerIPAllowlistPageRouteImport } from "./pages/secret-manager/IPAllowlistPage/route"; +import { Route as pamSettingsPageRouteImport } from "./pages/pam/SettingsPage/route"; +import { Route as pamPamResourcesPageRouteImport } from "./pages/pam/PamResourcesPage/route"; +import { Route as pamApprovalsPageRouteImport } from "./pages/pam/ApprovalsPage/route"; +import { Route as pamPamAccountsPageRouteImport } from "./pages/pam/PamAccountsPage/route"; +import { Route as kmsSettingsPageRouteImport } from "./pages/kms/SettingsPage/route"; +import { Route as kmsOverviewPageRouteImport } from "./pages/kms/OverviewPage/route"; +import { Route as kmsKmipPageRouteImport } from "./pages/kms/KmipPage/route"; +import { Route as certManagerSettingsPageRouteImport } from "./pages/cert-manager/SettingsPage/route"; +import { Route as certManagerPoliciesPageRouteImport } from "./pages/cert-manager/PoliciesPage/route"; +import { Route as certManagerCertificateAuthoritiesPageRouteImport } from "./pages/cert-manager/CertificateAuthoritiesPage/route"; +import { Route as certManagerAlertingPageRouteImport } from "./pages/cert-manager/AlertingPage/route"; +import { Route as projectRoleDetailsBySlugPageRouteSshImport } from "./pages/project/RoleDetailsBySlugPage/route-ssh"; +import { Route as projectMemberDetailsByIDPageRouteSshImport } from "./pages/project/MemberDetailsByIDPage/route-ssh"; +import { Route as projectIdentityDetailsByIDPageRouteSshImport } from "./pages/project/IdentityDetailsByIDPage/route-ssh"; +import { Route as projectGroupDetailsByIDPageRouteSshImport } from "./pages/project/GroupDetailsByIDPage/route-ssh"; +import { Route as projectRoleDetailsBySlugPageRouteSecretScanningImport } from "./pages/project/RoleDetailsBySlugPage/route-secret-scanning"; +import { Route as projectMemberDetailsByIDPageRouteSecretScanningImport } from "./pages/project/MemberDetailsByIDPage/route-secret-scanning"; +import { Route as projectIdentityDetailsByIDPageRouteSecretScanningImport } from "./pages/project/IdentityDetailsByIDPage/route-secret-scanning"; +import { Route as projectGroupDetailsByIDPageRouteSecretScanningImport } from "./pages/project/GroupDetailsByIDPage/route-secret-scanning"; +import { Route as projectRoleDetailsBySlugPageRouteSecretManagerImport } from "./pages/project/RoleDetailsBySlugPage/route-secret-manager"; +import { Route as projectMemberDetailsByIDPageRouteSecretManagerImport } from "./pages/project/MemberDetailsByIDPage/route-secret-manager"; +import { Route as projectIdentityDetailsByIDPageRouteSecretManagerImport } from "./pages/project/IdentityDetailsByIDPage/route-secret-manager"; +import { Route as projectGroupDetailsByIDPageRouteSecretManagerImport } from "./pages/project/GroupDetailsByIDPage/route-secret-manager"; +import { Route as projectRoleDetailsBySlugPageRoutePamImport } from "./pages/project/RoleDetailsBySlugPage/route-pam"; +import { Route as projectMemberDetailsByIDPageRoutePamImport } from "./pages/project/MemberDetailsByIDPage/route-pam"; +import { Route as projectIdentityDetailsByIDPageRoutePamImport } from "./pages/project/IdentityDetailsByIDPage/route-pam"; +import { Route as projectGroupDetailsByIDPageRoutePamImport } from "./pages/project/GroupDetailsByIDPage/route-pam"; +import { Route as projectRoleDetailsBySlugPageRouteKmsImport } from "./pages/project/RoleDetailsBySlugPage/route-kms"; +import { Route as projectMemberDetailsByIDPageRouteKmsImport } from "./pages/project/MemberDetailsByIDPage/route-kms"; +import { Route as projectIdentityDetailsByIDPageRouteKmsImport } from "./pages/project/IdentityDetailsByIDPage/route-kms"; +import { Route as projectGroupDetailsByIDPageRouteKmsImport } from "./pages/project/GroupDetailsByIDPage/route-kms"; +import { Route as projectRoleDetailsBySlugPageRouteCertManagerImport } from "./pages/project/RoleDetailsBySlugPage/route-cert-manager"; +import { Route as certManagerPkiCollectionDetailsByIDPageRoutesImport } from "./pages/cert-manager/PkiCollectionDetailsByIDPage/routes"; +import { Route as projectMemberDetailsByIDPageRouteCertManagerImport } from "./pages/project/MemberDetailsByIDPage/route-cert-manager"; +import { Route as projectIdentityDetailsByIDPageRouteCertManagerImport } from "./pages/project/IdentityDetailsByIDPage/route-cert-manager"; +import { Route as projectGroupDetailsByIDPageRouteCertManagerImport } from "./pages/project/GroupDetailsByIDPage/route-cert-manager"; +import { Route as sshSshHostGroupDetailsByIDPageRouteImport } from "./pages/ssh/SshHostGroupDetailsByIDPage/route"; +import { Route as sshSshCaByIDPageRouteImport } from "./pages/ssh/SshCaByIDPage/route"; +import { Route as secretManagerSecretDashboardPageRouteImport } from "./pages/secret-manager/SecretDashboardPage/route"; +import { Route as secretManagerIntegrationsSelectIntegrationAuthPageRouteImport } from "./pages/secret-manager/integrations/SelectIntegrationAuthPage/route"; +import { Route as secretManagerIntegrationsDetailsByIDPageRouteImport } from "./pages/secret-manager/IntegrationsDetailsByIDPage/route"; +import { Route as pamPamSessionsByIDPageRouteImport } from "./pages/pam/PamSessionsByIDPage/route"; +import { Route as pamApprovalRequestDetailPageRouteImport } from "./pages/pam/ApprovalRequestDetailPage/route"; +import { Route as certManagerPkiSubscriberDetailsByIDPageRouteImport } from "./pages/cert-manager/PkiSubscriberDetailsByIDPage/route"; +import { Route as certManagerPkiSyncDetailsByIDPageRouteImport } from "./pages/cert-manager/PkiSyncDetailsByIDPage/route"; +import { Route as certManagerCertAuthDetailsByIDPageRouteImport } from "./pages/cert-manager/CertAuthDetailsByIDPage/route"; +import { Route as secretScanningSecretScanningDataSourcesPageRouteImport } from "./pages/secret-scanning/SecretScanningDataSourcesPage/route"; +import { Route as secretManagerIntegrationsListPageRouteImport } from "./pages/secret-manager/IntegrationsListPage/route"; +import { Route as pamPamSessionsPageRouteImport } from "./pages/pam/PamSessionsPage/route"; +import { Route as certManagerPkiSubscribersPageRouteImport } from "./pages/cert-manager/PkiSubscribersPage/route"; +import { Route as certManagerIntegrationsListPageRouteImport } from "./pages/cert-manager/IntegrationsListPage/route"; +import { Route as certManagerPkiTemplateListPageRouteImport } from "./pages/cert-manager/PkiTemplateListPage/route"; +import { Route as secretScanningSecretScanningDataSourceByIdPageRouteImport } from "./pages/secret-scanning/SecretScanningDataSourceByIdPage/route"; +import { Route as secretManagerIntegrationsWindmillConfigurePageRouteImport } from "./pages/secret-manager/integrations/WindmillConfigurePage/route"; +import { Route as secretManagerIntegrationsWindmillAuthorizePageRouteImport } from "./pages/secret-manager/integrations/WindmillAuthorizePage/route"; +import { Route as secretManagerIntegrationsVercelConfigurePageRouteImport } from "./pages/secret-manager/integrations/VercelConfigurePage/route"; +import { Route as secretManagerIntegrationsTravisCIConfigurePageRouteImport } from "./pages/secret-manager/integrations/TravisCIConfigurePage/route"; +import { Route as secretManagerIntegrationsTravisCIAuthorizePageRouteImport } from "./pages/secret-manager/integrations/TravisCIAuthorizePage/route"; +import { Route as secretManagerIntegrationsTerraformCloudConfigurePageRouteImport } from "./pages/secret-manager/integrations/TerraformCloudConfigurePage/route"; +import { Route as secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport } from "./pages/secret-manager/integrations/TerraformCloudAuthorizePage/route"; +import { Route as secretManagerIntegrationsTeamcityConfigurePageRouteImport } from "./pages/secret-manager/integrations/TeamcityConfigurePage/route"; +import { Route as secretManagerIntegrationsTeamcityAuthorizePageRouteImport } from "./pages/secret-manager/integrations/TeamcityAuthorizePage/route"; +import { Route as secretManagerIntegrationsSupabaseConfigurePageRouteImport } from "./pages/secret-manager/integrations/SupabaseConfigurePage/route"; +import { Route as secretManagerIntegrationsSupabaseAuthorizePageRouteImport } from "./pages/secret-manager/integrations/SupabaseAuthorizePage/route"; +import { Route as secretManagerIntegrationsRundeckConfigurePageRouteImport } from "./pages/secret-manager/integrations/RundeckConfigurePage/route"; +import { Route as secretManagerIntegrationsRundeckAuthorizePageRouteImport } from "./pages/secret-manager/integrations/RundeckAuthorizePage/route"; +import { Route as secretManagerIntegrationsRenderConfigurePageRouteImport } from "./pages/secret-manager/integrations/RenderConfigurePage/route"; +import { Route as secretManagerIntegrationsRenderAuthorizePageRouteImport } from "./pages/secret-manager/integrations/RenderAuthorizePage/route"; +import { Route as secretManagerIntegrationsRailwayConfigurePageRouteImport } from "./pages/secret-manager/integrations/RailwayConfigurePage/route"; +import { Route as secretManagerIntegrationsRailwayAuthorizePageRouteImport } from "./pages/secret-manager/integrations/RailwayAuthorizePage/route"; +import { Route as secretManagerIntegrationsQoveryConfigurePageRouteImport } from "./pages/secret-manager/integrations/QoveryConfigurePage/route"; +import { Route as secretManagerIntegrationsQoveryAuthorizePageRouteImport } from "./pages/secret-manager/integrations/QoveryAuthorizePage/route"; +import { Route as secretManagerIntegrationsOctopusDeployConfigurePageRouteImport } from "./pages/secret-manager/integrations/OctopusDeployConfigurePage/route"; +import { Route as secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport } from "./pages/secret-manager/integrations/OctopusDeployAuthorizePage/route"; +import { Route as secretManagerIntegrationsNorthflankConfigurePageRouteImport } from "./pages/secret-manager/integrations/NorthflankConfigurePage/route"; +import { Route as secretManagerIntegrationsNorthflankAuthorizePageRouteImport } from "./pages/secret-manager/integrations/NorthflankAuthorizePage/route"; +import { Route as secretManagerIntegrationsNetlifyConfigurePageRouteImport } from "./pages/secret-manager/integrations/NetlifyConfigurePage/route"; +import { Route as secretManagerIntegrationsLaravelForgeConfigurePageRouteImport } from "./pages/secret-manager/integrations/LaravelForgeConfigurePage/route"; +import { Route as secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport } from "./pages/secret-manager/integrations/LaravelForgeAuthorizePage/route"; +import { Route as secretManagerIntegrationsHerokuConfigurePageRouteImport } from "./pages/secret-manager/integrations/HerokuConfigurePage/route"; +import { Route as secretManagerIntegrationsHasuraCloudConfigurePageRouteImport } from "./pages/secret-manager/integrations/HasuraCloudConfigurePage/route"; +import { Route as secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport } from "./pages/secret-manager/integrations/HasuraCloudAuthorizePage/route"; +import { Route as secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport } from "./pages/secret-manager/integrations/HashicorpVaultConfigurePage/route"; +import { Route as secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport } from "./pages/secret-manager/integrations/HashicorpVaultAuthorizePage/route"; +import { Route as secretManagerIntegrationsGitlabConfigurePageRouteImport } from "./pages/secret-manager/integrations/GitlabConfigurePage/route"; +import { Route as secretManagerIntegrationsGitlabAuthorizePageRouteImport } from "./pages/secret-manager/integrations/GitlabAuthorizePage/route"; +import { Route as secretManagerIntegrationsGithubConfigurePageRouteImport } from "./pages/secret-manager/integrations/GithubConfigurePage/route"; +import { Route as secretManagerIntegrationsGithubAuthorizePageRouteImport } from "./pages/secret-manager/integrations/GithubAuthorizePage/route"; +import { Route as secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport } from "./pages/secret-manager/integrations/GcpSecretManagerConfigurePage/route"; +import { Route as secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport } from "./pages/secret-manager/integrations/GcpSecretManagerAuthorizePage/route"; +import { Route as secretManagerIntegrationsFlyioConfigurePageRouteImport } from "./pages/secret-manager/integrations/FlyioConfigurePage/route"; +import { Route as secretManagerIntegrationsFlyioAuthorizePageRouteImport } from "./pages/secret-manager/integrations/FlyioAuthorizePage/route"; +import { Route as secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport } from "./pages/secret-manager/integrations/DigitalOceanAppPlatformConfigurePage/route"; +import { Route as secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport } from "./pages/secret-manager/integrations/DigitalOceanAppPlatformAuthorizePage/route"; +import { Route as secretManagerIntegrationsDatabricksConfigurePageRouteImport } from "./pages/secret-manager/integrations/DatabricksConfigurePage/route"; +import { Route as secretManagerIntegrationsDatabricksAuthorizePageRouteImport } from "./pages/secret-manager/integrations/DatabricksAuthorizePage/route"; +import { Route as secretManagerIntegrationsCodefreshConfigurePageRouteImport } from "./pages/secret-manager/integrations/CodefreshConfigurePage/route"; +import { Route as secretManagerIntegrationsCodefreshAuthorizePageRouteImport } from "./pages/secret-manager/integrations/CodefreshAuthorizePage/route"; +import { Route as secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport } from "./pages/secret-manager/integrations/CloudflareWorkersConfigurePage/route"; +import { Route as secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport } from "./pages/secret-manager/integrations/CloudflareWorkersAuthorizePage/route"; +import { Route as secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport } from "./pages/secret-manager/integrations/CloudflarePagesConfigurePage/route"; +import { Route as secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport } from "./pages/secret-manager/integrations/CloudflarePagesAuthorizePage/route"; +import { Route as secretManagerIntegrationsCloud66ConfigurePageRouteImport } from "./pages/secret-manager/integrations/Cloud66ConfigurePage/route"; +import { Route as secretManagerIntegrationsCloud66AuthorizePageRouteImport } from "./pages/secret-manager/integrations/Cloud66AuthorizePage/route"; +import { Route as secretManagerIntegrationsCircleCIConfigurePageRouteImport } from "./pages/secret-manager/integrations/CircleCIConfigurePage/route"; +import { Route as secretManagerIntegrationsCircleCIAuthorizePageRouteImport } from "./pages/secret-manager/integrations/CircleCIAuthorizePage/route"; +import { Route as secretManagerIntegrationsChecklyConfigurePageRouteImport } from "./pages/secret-manager/integrations/ChecklyConfigurePage/route"; +import { Route as secretManagerIntegrationsChecklyAuthorizePageRouteImport } from "./pages/secret-manager/integrations/ChecklyAuthorizePage/route"; +import { Route as secretManagerIntegrationsBitbucketConfigurePageRouteImport } from "./pages/secret-manager/integrations/BitbucketConfigurePage/route"; +import { Route as secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport } from "./pages/secret-manager/integrations/AzureKeyVaultConfigurePage/route"; +import { Route as secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport } from "./pages/secret-manager/integrations/AzureKeyVaultAuthorizePage/route"; +import { Route as secretManagerIntegrationsAzureDevopsConfigurePageRouteImport } from "./pages/secret-manager/integrations/AzureDevopsConfigurePage/route"; +import { Route as secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport } from "./pages/secret-manager/integrations/AzureDevopsAuthorizePage/route"; +import { Route as secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport } from "./pages/secret-manager/integrations/AzureAppConfigurationConfigurePage/route"; +import { Route as secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport } from "./pages/secret-manager/integrations/AwsSecretManagerConfigurePage/route"; +import { Route as secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport } from "./pages/secret-manager/integrations/AwsSecretManagerAuthorizePage/route"; +import { Route as secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport } from "./pages/secret-manager/integrations/AwsParameterStoreConfigurePage/route"; +import { Route as secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport } from "./pages/secret-manager/integrations/AwsParameterStoreAuthorizePage/route"; +import { Route as secretManagerIntegrationsVercelOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/VercelOauthCallbackPage/route"; +import { Route as secretManagerSecretSyncDetailsByIDPageRouteImport } from "./pages/secret-manager/SecretSyncDetailsByIDPage/route"; +import { Route as secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/NetlifyOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsHerokuOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/HerokuOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsGitlabOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/GitlabOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsGithubOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/GithubOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/GcpSecretManagerOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/BitbucketOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/AzureKeyVaultOauthCallbackPage/route"; +import { Route as secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport } from "./pages/secret-manager/integrations/AzureAppConfigurationOauthCallbackPage/route"; +import { Route as secretManagerCommitsPageRouteImport } from "./pages/secret-manager/CommitsPage/route"; +import { Route as secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport } from "./pages/secret-manager/CommitDetailsPage/components/RollbackPreviewTab/route"; +import { Route as secretManagerCommitDetailsPageRouteImport } from "./pages/secret-manager/CommitDetailsPage/route"; // Create Virtual Routes -const RestrictLoginSignupSignupImport = createFileRoute( - '/_restrict-login-signup/signup', -)() -const RestrictLoginSignupLoginImport = createFileRoute( - '/_restrict-login-signup/login', -)() -const AuthenticatePersonalSettingsImport = createFileRoute( - '/_authenticate/personal-settings', -)() +const RestrictLoginSignupSignupImport = createFileRoute("/_restrict-login-signup/signup")(); +const RestrictLoginSignupLoginImport = createFileRoute("/_restrict-login-signup/login")(); +const AuthenticatePersonalSettingsImport = createFileRoute("/_authenticate/personal-settings")(); const AuthenticateInjectOrgDetailsAdminImport = createFileRoute( - '/_authenticate/_inject-org-details/admin', -)() + "/_authenticate/_inject-org-details/admin" +)(); const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/integrations', -)() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$', - )() + "/_authenticate/_inject-org-details/_org-layout/integrations" +)(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId" +)(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings" +)(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing" +)(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections" +)(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$" +)(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport = - createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId" + )(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$" +)(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdImport = + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId" + )(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport = + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions" + )(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsImport = + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers" + )(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations', - )() -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport = + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations" + )(); +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId" + )(); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport = createFileRoute( - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId', - )() + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" + )(); // Create/Update Routes -const middlewaresRestrictLoginSignupRoute = - middlewaresRestrictLoginSignupImport.update({ - id: '/_restrict-login-signup', - getParentRoute: () => rootRoute, - } as any) +const middlewaresRestrictLoginSignupRoute = middlewaresRestrictLoginSignupImport.update({ + id: "/_restrict-login-signup", + getParentRoute: () => rootRoute +} as any); const middlewaresAuthenticateRoute = middlewaresAuthenticateImport.update({ - id: '/_authenticate', - getParentRoute: () => rootRoute, -} as any) + id: "/_authenticate", + getParentRoute: () => rootRoute +} as any); -const publicUpgradePathPageRouteRoute = publicUpgradePathPageRouteImport.update( - { - id: '/upgrade-path', - path: '/upgrade-path', - getParentRoute: () => rootRoute, - } as any, -) +const publicUpgradePathPageRouteRoute = publicUpgradePathPageRouteImport.update({ + id: "/upgrade-path", + path: "/upgrade-path", + getParentRoute: () => rootRoute +} as any); -const publicShareSecretPageRouteRoute = publicShareSecretPageRouteImport.update( - { - id: '/share-secret', - path: '/share-secret', - getParentRoute: () => rootRoute, - } as any, -) +const publicShareSecretPageRouteRoute = publicShareSecretPageRouteImport.update({ + id: "/share-secret", + path: "/share-secret", + getParentRoute: () => rootRoute +} as any); const authCliRedirectPageRouteRoute = authCliRedirectPageRouteImport.update({ - id: '/cli-redirect', - path: '/cli-redirect', - getParentRoute: () => rootRoute, -} as any) + id: "/cli-redirect", + path: "/cli-redirect", + getParentRoute: () => rootRoute +} as any); const indexRoute = indexImport.update({ - id: '/', - path: '/', - getParentRoute: () => rootRoute, -} as any) + id: "/", + path: "/", + getParentRoute: () => rootRoute +} as any); const RestrictLoginSignupSignupRoute = RestrictLoginSignupSignupImport.update({ - id: '/signup', - path: '/signup', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, -} as any) + id: "/signup", + path: "/signup", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); const RestrictLoginSignupLoginRoute = RestrictLoginSignupLoginImport.update({ - id: '/login', - path: '/login', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, -} as any) + id: "/login", + path: "/login", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const AuthenticatePersonalSettingsRoute = - AuthenticatePersonalSettingsImport.update({ - id: '/personal-settings', - path: '/personal-settings', - getParentRoute: () => middlewaresAuthenticateRoute, - } as any) +const AuthenticatePersonalSettingsRoute = AuthenticatePersonalSettingsImport.update({ + id: "/personal-settings", + path: "/personal-settings", + getParentRoute: () => middlewaresAuthenticateRoute +} as any); -const middlewaresInjectOrgDetailsRoute = - middlewaresInjectOrgDetailsImport.update({ - id: '/_inject-org-details', - getParentRoute: () => middlewaresAuthenticateRoute, - } as any) +const middlewaresInjectOrgDetailsRoute = middlewaresInjectOrgDetailsImport.update({ + id: "/_inject-org-details", + getParentRoute: () => middlewaresAuthenticateRoute +} as any); const authVerifyEmailPageRouteRoute = authVerifyEmailPageRouteImport.update({ - id: '/verify-email', - path: '/verify-email', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, -} as any) + id: "/verify-email", + path: "/verify-email", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); const authSignUpInvitePageRouteRoute = authSignUpInvitePageRouteImport.update({ - id: '/signupinvite', - path: '/signupinvite', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, -} as any) + id: "/signupinvite", + path: "/signupinvite", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const authRequestNewInvitePageRouteRoute = - authRequestNewInvitePageRouteImport.update({ - id: '/requestnewinvite', - path: '/requestnewinvite', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, - } as any) +const authRequestNewInvitePageRouteRoute = authRequestNewInvitePageRouteImport.update({ + id: "/requestnewinvite", + path: "/requestnewinvite", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const authPasswordResetPageRouteRoute = authPasswordResetPageRouteImport.update( - { - id: '/password-reset', - path: '/password-reset', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, - } as any, -) +const authPasswordResetPageRouteRoute = authPasswordResetPageRouteImport.update({ + id: "/password-reset", + path: "/password-reset", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const authEmailNotVerifiedPageRouteRoute = - authEmailNotVerifiedPageRouteImport.update({ - id: '/email-not-verified', - path: '/email-not-verified', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, - } as any) +const authEmailNotVerifiedPageRouteRoute = authEmailNotVerifiedPageRouteImport.update({ + id: "/email-not-verified", + path: "/email-not-verified", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const authPasswordSetupPageRouteRoute = authPasswordSetupPageRouteImport.update( - { - id: '/password-setup', - path: '/password-setup', - getParentRoute: () => middlewaresAuthenticateRoute, - } as any, -) +const authPasswordSetupPageRouteRoute = authPasswordSetupPageRouteImport.update({ + id: "/password-setup", + path: "/password-setup", + getParentRoute: () => middlewaresAuthenticateRoute +} as any); const userLayoutRoute = userLayoutImport.update({ - id: '/_layout', - getParentRoute: () => AuthenticatePersonalSettingsRoute, -} as any) + id: "/_layout", + getParentRoute: () => AuthenticatePersonalSettingsRoute +} as any); -const AuthenticateInjectOrgDetailsAdminRoute = - AuthenticateInjectOrgDetailsAdminImport.update({ - id: '/admin', - path: '/admin', - getParentRoute: () => middlewaresInjectOrgDetailsRoute, - } as any) +const AuthenticateInjectOrgDetailsAdminRoute = AuthenticateInjectOrgDetailsAdminImport.update({ + id: "/admin", + path: "/admin", + getParentRoute: () => middlewaresInjectOrgDetailsRoute +} as any); const organizationLayoutRoute = organizationLayoutImport.update({ - id: '/_org-layout', - getParentRoute: () => middlewaresInjectOrgDetailsRoute, -} as any) + id: "/_org-layout", + getParentRoute: () => middlewaresInjectOrgDetailsRoute +} as any); -const publicViewSharedSecretByIDPageRouteRoute = - publicViewSharedSecretByIDPageRouteImport.update({ - id: '/shared/secret/$secretId', - path: '/shared/secret/$secretId', - getParentRoute: () => rootRoute, - } as any) +const publicViewSharedSecretByIDPageRouteRoute = publicViewSharedSecretByIDPageRouteImport.update({ + id: "/shared/secret/$secretId", + path: "/shared/secret/$secretId", + getParentRoute: () => rootRoute +} as any); -const publicViewSecretRequestByIDPageRouteRoute = - publicViewSecretRequestByIDPageRouteImport.update({ - id: '/secret-request/secret/$secretRequestId', - path: '/secret-request/secret/$secretRequestId', - getParentRoute: () => rootRoute, - } as any) +const publicViewSecretRequestByIDPageRouteRoute = publicViewSecretRequestByIDPageRouteImport.update( + { + id: "/secret-request/secret/$secretRequestId", + path: "/secret-request/secret/$secretRequestId", + getParentRoute: () => rootRoute + } as any +); const authSignUpSsoPageRouteRoute = authSignUpSsoPageRouteImport.update({ - id: '/sso', - path: '/sso', - getParentRoute: () => RestrictLoginSignupSignupRoute, -} as any) + id: "/sso", + path: "/sso", + getParentRoute: () => RestrictLoginSignupSignupRoute +} as any); const authLoginSsoPageRouteRoute = authLoginSsoPageRouteImport.update({ - id: '/sso', - path: '/sso', - getParentRoute: () => RestrictLoginSignupLoginRoute, -} as any) + id: "/sso", + path: "/sso", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); const authSelectOrgPageRouteRoute = authSelectOrgPageRouteImport.update({ - id: '/select-organization', - path: '/select-organization', - getParentRoute: () => RestrictLoginSignupLoginRoute, -} as any) + id: "/select-organization", + path: "/select-organization", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); const authLoginLdapPageRouteRoute = authLoginLdapPageRouteImport.update({ - id: '/ldap', - path: '/ldap', - getParentRoute: () => RestrictLoginSignupLoginRoute, -} as any) + id: "/ldap", + path: "/ldap", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); const authAdminLoginPageRouteRoute = authAdminLoginPageRouteImport.update({ - id: '/admin', - path: '/admin', - getParentRoute: () => RestrictLoginSignupLoginRoute, -} as any) + id: "/admin", + path: "/admin", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); const adminSignUpPageRouteRoute = adminSignUpPageRouteImport.update({ - id: '/admin/signup', - path: '/admin/signup', - getParentRoute: () => middlewaresRestrictLoginSignupRoute, -} as any) + id: "/admin/signup", + path: "/admin/signup", + getParentRoute: () => middlewaresRestrictLoginSignupRoute +} as any); -const organizationNoOrgPageRouteRoute = organizationNoOrgPageRouteImport.update( - { - id: '/organizations/none', - path: '/organizations/none', - getParentRoute: () => middlewaresAuthenticateRoute, - } as any, -) +const organizationNoOrgPageRouteRoute = organizationNoOrgPageRouteImport.update({ + id: "/organizations/none", + path: "/organizations/none", + getParentRoute: () => middlewaresAuthenticateRoute +} as any); const authSignUpPageRouteRoute = authSignUpPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => RestrictLoginSignupSignupRoute, -} as any) + id: "/", + path: "/", + getParentRoute: () => RestrictLoginSignupSignupRoute +} as any); const authLoginPageRouteRoute = authLoginPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => RestrictLoginSignupLoginRoute, -} as any) + id: "/", + path: "/", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); const redirectsProjectRedirectRoute = redirectsProjectRedirectImport.update({ - id: '/projects/$', - path: '/projects/$', - getParentRoute: () => middlewaresInjectOrgDetailsRoute, -} as any) + id: "/projects/$", + path: "/projects/$", + getParentRoute: () => middlewaresInjectOrgDetailsRoute +} as any); -const redirectsOrganizationRedirectRoute = - redirectsOrganizationRedirectImport.update({ - id: '/organization/$', - path: '/organization/$', - getParentRoute: () => middlewaresInjectOrgDetailsRoute, - } as any) +const redirectsOrganizationRedirectRoute = redirectsOrganizationRedirectImport.update({ + id: "/organization/$", + path: "/organization/$", + getParentRoute: () => middlewaresInjectOrgDetailsRoute +} as any); const adminLayoutRoute = adminLayoutImport.update({ - id: '/_admin-layout', - getParentRoute: () => AuthenticateInjectOrgDetailsAdminRoute, -} as any) + id: "/_admin-layout", + getParentRoute: () => AuthenticateInjectOrgDetailsAdminRoute +} as any); const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute = AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport.update({ - id: '/integrations', - path: '/integrations', - getParentRoute: () => organizationLayoutRoute, - } as any) + id: "/integrations", + path: "/integrations", + getParentRoute: () => organizationLayoutRoute + } as any); -const authProviderSuccessPageRouteRoute = - authProviderSuccessPageRouteImport.update({ - id: '/provider/success', - path: '/provider/success', - getParentRoute: () => RestrictLoginSignupLoginRoute, - } as any) +const authProviderSuccessPageRouteRoute = authProviderSuccessPageRouteImport.update({ + id: "/provider/success", + path: "/provider/success", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); -const authProviderErrorPageRouteRoute = authProviderErrorPageRouteImport.update( - { - id: '/provider/error', - path: '/provider/error', - getParentRoute: () => RestrictLoginSignupLoginRoute, - } as any, -) +const authProviderErrorPageRouteRoute = authProviderErrorPageRouteImport.update({ + id: "/provider/error", + path: "/provider/error", + getParentRoute: () => RestrictLoginSignupLoginRoute +} as any); -const userPersonalSettingsPageRouteRoute = - userPersonalSettingsPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => userLayoutRoute, - } as any) +const userPersonalSettingsPageRouteRoute = userPersonalSettingsPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => userLayoutRoute +} as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport.update({ - id: '/organizations/$orgId', - path: '/organizations/$orgId', - getParentRoute: () => organizationLayoutRoute, - } as any) + id: "/organizations/$orgId", + path: "/organizations/$orgId", + getParentRoute: () => organizationLayoutRoute + } as any); -const adminIntegrationsPageRouteRoute = adminIntegrationsPageRouteImport.update( - { - id: '/integrations', - path: '/integrations', - getParentRoute: () => adminLayoutRoute, - } as any, -) +const adminIntegrationsPageRouteRoute = adminIntegrationsPageRouteImport.update({ + id: "/integrations", + path: "/integrations", + getParentRoute: () => adminLayoutRoute +} as any); const adminEnvironmentPageRouteRoute = adminEnvironmentPageRouteImport.update({ - id: '/environment', - path: '/environment', - getParentRoute: () => adminLayoutRoute, -} as any) + id: "/environment", + path: "/environment", + getParentRoute: () => adminLayoutRoute +} as any); const adminEncryptionPageRouteRoute = adminEncryptionPageRouteImport.update({ - id: '/encryption', - path: '/encryption', - getParentRoute: () => adminLayoutRoute, -} as any) + id: "/encryption", + path: "/encryption", + getParentRoute: () => adminLayoutRoute +} as any); const adminCachingPageRouteRoute = adminCachingPageRouteImport.update({ - id: '/caching', - path: '/caching', - getParentRoute: () => adminLayoutRoute, -} as any) + id: "/caching", + path: "/caching", + getParentRoute: () => adminLayoutRoute +} as any); -const adminAuthenticationPageRouteRoute = - adminAuthenticationPageRouteImport.update({ - id: '/authentication', - path: '/authentication', - getParentRoute: () => adminLayoutRoute, - } as any) +const adminAuthenticationPageRouteRoute = adminAuthenticationPageRouteImport.update({ + id: "/authentication", + path: "/authentication", + getParentRoute: () => adminLayoutRoute +} as any); -const adminAccessManagementPageRouteRoute = - adminAccessManagementPageRouteImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => adminLayoutRoute, - } as any) +const adminAccessManagementPageRouteRoute = adminAccessManagementPageRouteImport.update({ + id: "/access-management", + path: "/access-management", + getParentRoute: () => adminLayoutRoute +} as any); const adminGeneralPageRouteRoute = adminGeneralPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => adminLayoutRoute, -} as any) + id: "/", + path: "/", + getParentRoute: () => adminLayoutRoute +} as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) + id: "/settings", + path: "/settings", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport.update( - { - id: '/secret-sharing', - path: '/secret-sharing', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport.update({ + id: "/secret-sharing", + path: "/secret-sharing", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport.update( - { - id: '/app-connections', - path: '/app-connections', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport.update({ + id: "/app-connections", + path: "/app-connections", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatImport.update({ - id: '/$', - path: '/$', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) + id: "/$", + path: "/$", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); -const adminResourceOverviewPageRouteRoute = - adminResourceOverviewPageRouteImport.update({ - id: '/resources/overview', - path: '/resources/overview', - getParentRoute: () => adminLayoutRoute, - } as any) +const adminResourceOverviewPageRouteRoute = adminResourceOverviewPageRouteImport.update({ + id: "/resources/overview", + path: "/resources/overview", + getParentRoute: () => adminLayoutRoute +} as any); -const organizationProjectsPageRouteRoute = - organizationProjectsPageRouteImport.update({ - id: '/projects', - path: '/projects', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationProjectsPageRouteRoute = organizationProjectsPageRouteImport.update({ + id: "/projects", + path: "/projects", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute +} as any); -const organizationNetworkingPageRouteRoute = - organizationNetworkingPageRouteImport.update({ - id: '/networking', - path: '/networking', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationNetworkingPageRouteRoute = organizationNetworkingPageRouteImport.update({ + id: "/networking", + path: "/networking", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute +} as any); -const organizationBillingPageRouteRoute = - organizationBillingPageRouteImport.update({ - id: '/billing', - path: '/billing', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationBillingPageRouteRoute = organizationBillingPageRouteImport.update({ + id: "/billing", + path: "/billing", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute +} as any); -const organizationAuditLogsPageRouteRoute = - organizationAuditLogsPageRouteImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationAuditLogsPageRouteRoute = organizationAuditLogsPageRouteImport.update({ + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute +} as any); const organizationAccessManagementPageRouteRoute = organizationAccessManagementPageRouteImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) + id: "/access-management", + path: "/access-management", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport.update( - { - id: '/secret-manager/$projectId', - path: '/secret-manager/$projectId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport.update({ + id: "/secret-manager/$projectId", + path: "/secret-manager/$projectId", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport.update( - { - id: '/$', - path: '/$', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport.update({ + id: "/$", + path: "/$", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any); const secretManagerIntegrationsRouteVercelOauthRedirectRoute = secretManagerIntegrationsRouteVercelOauthRedirectImport.update({ - id: '/vercel/oauth2/callback', - path: '/vercel/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/vercel/oauth2/callback", + path: "/vercel/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteNetlifyOauthRedirectRoute = secretManagerIntegrationsRouteNetlifyOauthRedirectImport.update({ - id: '/netlify/oauth2/callback', - path: '/netlify/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/netlify/oauth2/callback", + path: "/netlify/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteHerokuOauthRedirectRoute = secretManagerIntegrationsRouteHerokuOauthRedirectImport.update({ - id: '/heroku/oauth2/callback', - path: '/heroku/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/heroku/oauth2/callback", + path: "/heroku/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteGitlabOauthRedirectRoute = secretManagerIntegrationsRouteGitlabOauthRedirectImport.update({ - id: '/gitlab/oauth2/callback', - path: '/gitlab/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/gitlab/oauth2/callback", + path: "/gitlab/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteGithubOauthRedirectRoute = secretManagerIntegrationsRouteGithubOauthRedirectImport.update({ - id: '/github/oauth2/callback', - path: '/github/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/github/oauth2/callback", + path: "/github/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteGcpOauthRedirectRoute = secretManagerIntegrationsRouteGcpOauthRedirectImport.update({ - id: '/gcp-secret-manager/oauth2/callback', - path: '/gcp-secret-manager/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/gcp-secret-manager/oauth2/callback", + path: "/gcp-secret-manager/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteBitbucketOauthRedirectRoute = secretManagerIntegrationsRouteBitbucketOauthRedirectImport.update({ - id: '/bitbucket/oauth2/callback', - path: '/bitbucket/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/bitbucket/oauth2/callback", + path: "/bitbucket/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute = secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport.update({ - id: '/azure-key-vault/oauth2/callback', - path: '/azure-key-vault/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any) + id: "/azure-key-vault/oauth2/callback", + path: "/azure-key-vault/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute = - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport.update( - { - id: '/azure-app-configuration/oauth2/callback', - path: '/azure-app-configuration/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute, - } as any, - ) + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport.update({ + id: "/azure-app-configuration/oauth2/callback", + path: "/azure-app-configuration/oauth2/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute + } as any); -const organizationRoleByIDPageRouteRoute = - organizationRoleByIDPageRouteImport.update({ - id: '/roles/$roleId', - path: '/roles/$roleId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationRoleByIDPageRouteRoute = organizationRoleByIDPageRouteImport.update({ + id: "/roles/$roleId", + path: "/roles/$roleId", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute +} as any); -const organizationUserDetailsByIDPageRouteRoute = - organizationUserDetailsByIDPageRouteImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) +const organizationUserDetailsByIDPageRouteRoute = organizationUserDetailsByIDPageRouteImport.update( + { + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any +); const organizationIdentityDetailsByIDPageRouteRoute = organizationIdentityDetailsByIDPageRouteImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); const organizationGroupDetailsByIDPageRouteRoute = organizationGroupDetailsByIDPageRouteImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute, - } as any) + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute + } as any); -const organizationSettingsPageRouteRoute = - organizationSettingsPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute, - } as any) +const organizationSettingsPageRouteRoute = organizationSettingsPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute +} as any); -const organizationSecretSharingPageRouteRoute = - organizationSecretSharingPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute, - } as any) +const organizationSecretSharingPageRouteRoute = organizationSecretSharingPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute +} as any); const organizationAppConnectionsAppConnectionsPageRouteRoute = organizationAppConnectionsAppConnectionsPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute, - } as any) + id: "/", + path: "/", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute + } as any); const secretManagerRedirectsRedirectApprovalPageRoute = secretManagerRedirectsRedirectApprovalPageImport.update({ - id: '/approval', - path: '/approval', + id: "/approval", + path: "/approval", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport.update( - { - id: '/ssh/$projectId', - path: '/ssh/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport.update({ + id: "/ssh/$projectId", + path: "/ssh/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport.update( { - id: '/secret-scanning/$projectId', - path: '/secret-scanning/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + id: "/secret-scanning/$projectId", + path: "/secret-scanning/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any + ); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport.update( { - id: '/secret-management/$projectId', - path: '/secret-management/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + id: "/secret-management/$projectId", + path: "/secret-management/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any + ); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport.update( - { - id: '/pam/$projectId', - path: '/pam/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport.update({ + id: "/pam/$projectId", + path: "/pam/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport.update( - { - id: '/kms/$projectId', - path: '/kms/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport.update({ + id: "/kms/$projectId", + path: "/kms/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any); -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdImport.update( - { - id: '/cert-management/$projectId', - path: '/cert-management/$projectId', - getParentRoute: () => organizationProjectsPageRouteRoute, - } as any, - ) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRoute = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdImport.update({ + id: "/cert-manager/$projectId", + path: "/cert-manager/$projectId", + getParentRoute: () => organizationProjectsPageRouteRoute + } as any); const organizationSettingsPageOauthCallbackPageRouteRoute = organizationSettingsPageOauthCallbackPageRouteImport.update({ - id: '/oauth/callback', - path: '/oauth/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute, - } as any) + id: "/oauth/callback", + path: "/oauth/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute + } as any); const sshLayoutRoute = sshLayoutImport.update({ - id: '/_ssh-layout', + id: "/_ssh-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute +} as any); const secretScanningLayoutRoute = secretScanningLayoutImport.update({ - id: '/_secret-scanning-layout', + id: "/_secret-scanning-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute +} as any); const secretManagerLayoutRoute = secretManagerLayoutImport.update({ - id: '/_secret-manager-layout', + id: "/_secret-manager-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute +} as any); const pamLayoutRoute = pamLayoutImport.update({ - id: '/_pam-layout', + id: "/_pam-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute +} as any); const kmsLayoutRoute = kmsLayoutImport.update({ - id: '/_kms-layout', + id: "/_kms-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute +} as any); const certManagerLayoutRoute = certManagerLayoutImport.update({ - id: '/_cert-manager-layout', + id: "/_cert-manager-layout", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRoute +} as any); const organizationAppConnectionsOauthCallbackPageRouteRoute = organizationAppConnectionsOauthCallbackPageRouteImport.update({ - id: '/$appConnection/oauth/callback', - path: '/$appConnection/oauth/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute, - } as any) + id: "/$appConnection/oauth/callback", + path: "/$appConnection/oauth/callback", + getParentRoute: () => AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute + } as any); -const projectAuditLogsPageRouteSshRoute = - projectAuditLogsPageRouteSshImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => sshLayoutRoute, - } as any) +const projectAuditLogsPageRouteSshRoute = projectAuditLogsPageRouteSshImport.update({ + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => sshLayoutRoute +} as any); -const projectAccessControlPageRouteSshRoute = - projectAccessControlPageRouteSshImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => sshLayoutRoute, - } as any) +const projectAccessControlPageRouteSshRoute = projectAccessControlPageRouteSshImport.update({ + id: "/access-management", + path: "/access-management", + getParentRoute: () => sshLayoutRoute +} as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport.update( { - id: '/data-sources', - path: '/data-sources', - getParentRoute: () => secretScanningLayoutRoute, - } as any, - ) + id: "/data-sources", + path: "/data-sources", + getParentRoute: () => secretScanningLayoutRoute + } as any + ); const projectAuditLogsPageRouteSecretScanningRoute = projectAuditLogsPageRouteSecretScanningImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectAppConnectionsPageRouteSecretScanningRoute = projectAppConnectionsPageRouteSecretScanningImport.update({ - id: '/app-connections', - path: '/app-connections', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/app-connections", + path: "/app-connections", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectAccessControlPageRouteSecretScanningRoute = projectAccessControlPageRouteSecretScanningImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/access-management", + path: "/access-management", + getParentRoute: () => secretScanningLayoutRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport.update( { - id: '/integrations', - path: '/integrations', - getParentRoute: () => secretManagerLayoutRoute, - } as any, - ) + id: "/integrations", + path: "/integrations", + getParentRoute: () => secretManagerLayoutRoute + } as any + ); const projectAuditLogsPageRouteSecretManagerRoute = projectAuditLogsPageRouteSecretManagerImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => secretManagerLayoutRoute + } as any); const projectAppConnectionsPageRouteSecretManagerRoute = projectAppConnectionsPageRouteSecretManagerImport.update({ - id: '/app-connections', - path: '/app-connections', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/app-connections", + path: "/app-connections", + getParentRoute: () => secretManagerLayoutRoute + } as any); const projectAccessControlPageRouteSecretManagerRoute = projectAccessControlPageRouteSecretManagerImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/access-management", + path: "/access-management", + getParentRoute: () => secretManagerLayoutRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport.update( { - id: '/sessions', - path: '/sessions', - getParentRoute: () => pamLayoutRoute, - } as any, - ) + id: "/sessions", + path: "/sessions", + getParentRoute: () => pamLayoutRoute + } as any + ); -const projectAuditLogsPageRoutePamRoute = - projectAuditLogsPageRoutePamImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => pamLayoutRoute, - } as any) +const projectAuditLogsPageRoutePamRoute = projectAuditLogsPageRoutePamImport.update({ + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => pamLayoutRoute +} as any); -const projectAccessControlPageRoutePamRoute = - projectAccessControlPageRoutePamImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => pamLayoutRoute, - } as any) +const projectAccessControlPageRoutePamRoute = projectAccessControlPageRoutePamImport.update({ + id: "/access-management", + path: "/access-management", + getParentRoute: () => pamLayoutRoute +} as any); -const projectAuditLogsPageRouteKmsRoute = - projectAuditLogsPageRouteKmsImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => kmsLayoutRoute, - } as any) +const projectAuditLogsPageRouteKmsRoute = projectAuditLogsPageRouteKmsImport.update({ + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => kmsLayoutRoute +} as any); -const projectAccessControlPageRouteKmsRoute = - projectAccessControlPageRouteKmsImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => kmsLayoutRoute, - } as any) +const projectAccessControlPageRouteKmsRoute = projectAccessControlPageRouteKmsImport.update({ + id: "/access-management", + path: "/access-management", + getParentRoute: () => kmsLayoutRoute +} as any); -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersImport.update( { - id: '/subscribers', - path: '/subscribers', - getParentRoute: () => certManagerLayoutRoute, - } as any, - ) + id: "/subscribers", + path: "/subscribers", + getParentRoute: () => certManagerLayoutRoute + } as any + ); -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsImport.update( { - id: '/integrations', - path: '/integrations', - getParentRoute: () => certManagerLayoutRoute, - } as any, - ) + id: "/integrations", + path: "/integrations", + getParentRoute: () => certManagerLayoutRoute + } as any + ); -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport.update( +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRoute = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesImport.update( { - id: '/certificate-templates', - path: '/certificate-templates', - getParentRoute: () => certManagerLayoutRoute, - } as any, - ) + id: "/certificate-templates", + path: "/certificate-templates", + getParentRoute: () => certManagerLayoutRoute + } as any + ); -const projectAuditLogsPageRouteCertManagerRoute = - projectAuditLogsPageRouteCertManagerImport.update({ - id: '/audit-logs', - path: '/audit-logs', - getParentRoute: () => certManagerLayoutRoute, - } as any) +const projectAuditLogsPageRouteCertManagerRoute = projectAuditLogsPageRouteCertManagerImport.update( + { + id: "/audit-logs", + path: "/audit-logs", + getParentRoute: () => certManagerLayoutRoute + } as any +); const projectAppConnectionsPageRouteCertManagerRoute = projectAppConnectionsPageRouteCertManagerImport.update({ - id: '/app-connections', - path: '/app-connections', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/app-connections", + path: "/app-connections", + getParentRoute: () => certManagerLayoutRoute + } as any); const projectAccessControlPageRouteCertManagerRoute = projectAccessControlPageRouteCertManagerImport.update({ - id: '/access-management', - path: '/access-management', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/access-management", + path: "/access-management", + getParentRoute: () => certManagerLayoutRoute + } as any); const sshSettingsPageRouteRoute = sshSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => sshLayoutRoute, -} as any) + id: "/settings", + path: "/settings", + getParentRoute: () => sshLayoutRoute +} as any); const sshSshHostsPageRouteRoute = sshSshHostsPageRouteImport.update({ - id: '/overview', - path: '/overview', - getParentRoute: () => sshLayoutRoute, -} as any) + id: "/overview", + path: "/overview", + getParentRoute: () => sshLayoutRoute +} as any); const sshSshCertsPageRouteRoute = sshSshCertsPageRouteImport.update({ - id: '/certificates', - path: '/certificates', - getParentRoute: () => sshLayoutRoute, -} as any) + id: "/certificates", + path: "/certificates", + getParentRoute: () => sshLayoutRoute +} as any); const sshSshCasPageRouteRoute = sshSshCasPageRouteImport.update({ - id: '/cas', - path: '/cas', - getParentRoute: () => sshLayoutRoute, -} as any) + id: "/cas", + path: "/cas", + getParentRoute: () => sshLayoutRoute +} as any); -const secretScanningSettingsPageRouteRoute = - secretScanningSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => secretScanningLayoutRoute, - } as any) +const secretScanningSettingsPageRouteRoute = secretScanningSettingsPageRouteImport.update({ + id: "/settings", + path: "/settings", + getParentRoute: () => secretScanningLayoutRoute +} as any); const secretScanningSecretScanningFindingsPageRouteRoute = secretScanningSecretScanningFindingsPageRouteImport.update({ - id: '/findings', - path: '/findings', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/findings", + path: "/findings", + getParentRoute: () => secretScanningLayoutRoute + } as any); -const secretManagerSettingsPageRouteRoute = - secretManagerSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => secretManagerLayoutRoute, - } as any) +const secretManagerSettingsPageRouteRoute = secretManagerSettingsPageRouteImport.update({ + id: "/settings", + path: "/settings", + getParentRoute: () => secretManagerLayoutRoute +} as any); -const secretManagerSecretRotationPageRouteRoute = - secretManagerSecretRotationPageRouteImport.update({ - id: '/secret-rotation', - path: '/secret-rotation', - getParentRoute: () => secretManagerLayoutRoute, - } as any) +const secretManagerSecretRotationPageRouteRoute = secretManagerSecretRotationPageRouteImport.update( + { + id: "/secret-rotation", + path: "/secret-rotation", + getParentRoute: () => secretManagerLayoutRoute + } as any +); -const secretManagerOverviewPageRouteRoute = - secretManagerOverviewPageRouteImport.update({ - id: '/overview', - path: '/overview', - getParentRoute: () => secretManagerLayoutRoute, - } as any) +const secretManagerOverviewPageRouteRoute = secretManagerOverviewPageRouteImport.update({ + id: "/overview", + path: "/overview", + getParentRoute: () => secretManagerLayoutRoute +} as any); const secretManagerSecretApprovalsPageRouteRoute = secretManagerSecretApprovalsPageRouteImport.update({ - id: '/approval', - path: '/approval', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/approval", + path: "/approval", + getParentRoute: () => secretManagerLayoutRoute + } as any); -const secretManagerIPAllowlistPageRouteRoute = - secretManagerIPAllowlistPageRouteImport.update({ - id: '/allowlist', - path: '/allowlist', - getParentRoute: () => secretManagerLayoutRoute, - } as any) +const secretManagerIPAllowlistPageRouteRoute = secretManagerIPAllowlistPageRouteImport.update({ + id: "/allowlist", + path: "/allowlist", + getParentRoute: () => secretManagerLayoutRoute +} as any); const pamSettingsPageRouteRoute = pamSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => pamLayoutRoute, -} as any) + id: "/settings", + path: "/settings", + getParentRoute: () => pamLayoutRoute +} as any); const pamPamResourcesPageRouteRoute = pamPamResourcesPageRouteImport.update({ - id: '/resources', - path: '/resources', - getParentRoute: () => pamLayoutRoute, -} as any) + id: "/resources", + path: "/resources", + getParentRoute: () => pamLayoutRoute +} as any); const pamApprovalsPageRouteRoute = pamApprovalsPageRouteImport.update({ - id: '/approvals', - path: '/approvals', - getParentRoute: () => pamLayoutRoute, -} as any) + id: "/approvals", + path: "/approvals", + getParentRoute: () => pamLayoutRoute +} as any); const pamPamAccountsPageRouteRoute = pamPamAccountsPageRouteImport.update({ - id: '/accounts', - path: '/accounts', - getParentRoute: () => pamLayoutRoute, -} as any) + id: "/accounts", + path: "/accounts", + getParentRoute: () => pamLayoutRoute +} as any); const kmsSettingsPageRouteRoute = kmsSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => kmsLayoutRoute, -} as any) + id: "/settings", + path: "/settings", + getParentRoute: () => kmsLayoutRoute +} as any); const kmsOverviewPageRouteRoute = kmsOverviewPageRouteImport.update({ - id: '/overview', - path: '/overview', - getParentRoute: () => kmsLayoutRoute, -} as any) + id: "/overview", + path: "/overview", + getParentRoute: () => kmsLayoutRoute +} as any); const kmsKmipPageRouteRoute = kmsKmipPageRouteImport.update({ - id: '/kmip', - path: '/kmip', - getParentRoute: () => kmsLayoutRoute, -} as any) + id: "/kmip", + path: "/kmip", + getParentRoute: () => kmsLayoutRoute +} as any); -const certManagerSettingsPageRouteRoute = - certManagerSettingsPageRouteImport.update({ - id: '/settings', - path: '/settings', - getParentRoute: () => certManagerLayoutRoute, - } as any) +const certManagerSettingsPageRouteRoute = certManagerSettingsPageRouteImport.update({ + id: "/settings", + path: "/settings", + getParentRoute: () => certManagerLayoutRoute +} as any); -const certManagerPoliciesPageRouteRoute = - certManagerPoliciesPageRouteImport.update({ - id: '/policies', - path: '/policies', - getParentRoute: () => certManagerLayoutRoute, - } as any) +const certManagerPoliciesPageRouteRoute = certManagerPoliciesPageRouteImport.update({ + id: "/policies", + path: "/policies", + getParentRoute: () => certManagerLayoutRoute +} as any); const certManagerCertificateAuthoritiesPageRouteRoute = certManagerCertificateAuthoritiesPageRouteImport.update({ - id: '/certificate-authorities', - path: '/certificate-authorities', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/certificate-authorities", + path: "/certificate-authorities", + getParentRoute: () => certManagerLayoutRoute + } as any); -const certManagerAlertingPageRouteRoute = - certManagerAlertingPageRouteImport.update({ - id: '/alerting', - path: '/alerting', - getParentRoute: () => certManagerLayoutRoute, - } as any) +const certManagerAlertingPageRouteRoute = certManagerAlertingPageRouteImport.update({ + id: "/alerting", + path: "/alerting", + getParentRoute: () => certManagerLayoutRoute +} as any); -const projectRoleDetailsBySlugPageRouteSshRoute = - projectRoleDetailsBySlugPageRouteSshImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => sshLayoutRoute, - } as any) +const projectRoleDetailsBySlugPageRouteSshRoute = projectRoleDetailsBySlugPageRouteSshImport.update( + { + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => sshLayoutRoute + } as any +); -const projectMemberDetailsByIDPageRouteSshRoute = - projectMemberDetailsByIDPageRouteSshImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => sshLayoutRoute, - } as any) +const projectMemberDetailsByIDPageRouteSshRoute = projectMemberDetailsByIDPageRouteSshImport.update( + { + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => sshLayoutRoute + } as any +); const projectIdentityDetailsByIDPageRouteSshRoute = projectIdentityDetailsByIDPageRouteSshImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => sshLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => sshLayoutRoute + } as any); -const projectGroupDetailsByIDPageRouteSshRoute = - projectGroupDetailsByIDPageRouteSshImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => sshLayoutRoute, - } as any) +const projectGroupDetailsByIDPageRouteSshRoute = projectGroupDetailsByIDPageRouteSshImport.update({ + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => sshLayoutRoute +} as any); const projectRoleDetailsBySlugPageRouteSecretScanningRoute = projectRoleDetailsBySlugPageRouteSecretScanningImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectMemberDetailsByIDPageRouteSecretScanningRoute = projectMemberDetailsByIDPageRouteSecretScanningImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectIdentityDetailsByIDPageRouteSecretScanningRoute = projectIdentityDetailsByIDPageRouteSecretScanningImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectGroupDetailsByIDPageRouteSecretScanningRoute = projectGroupDetailsByIDPageRouteSecretScanningImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => secretScanningLayoutRoute, - } as any) + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => secretScanningLayoutRoute + } as any); const projectRoleDetailsBySlugPageRouteSecretManagerRoute = projectRoleDetailsBySlugPageRouteSecretManagerImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => secretManagerLayoutRoute + } as any); const projectMemberDetailsByIDPageRouteSecretManagerRoute = projectMemberDetailsByIDPageRouteSecretManagerImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => secretManagerLayoutRoute + } as any); const projectIdentityDetailsByIDPageRouteSecretManagerRoute = projectIdentityDetailsByIDPageRouteSecretManagerImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => secretManagerLayoutRoute + } as any); const projectGroupDetailsByIDPageRouteSecretManagerRoute = projectGroupDetailsByIDPageRouteSecretManagerImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => secretManagerLayoutRoute + } as any); -const projectRoleDetailsBySlugPageRoutePamRoute = - projectRoleDetailsBySlugPageRoutePamImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => pamLayoutRoute, - } as any) +const projectRoleDetailsBySlugPageRoutePamRoute = projectRoleDetailsBySlugPageRoutePamImport.update( + { + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => pamLayoutRoute + } as any +); -const projectMemberDetailsByIDPageRoutePamRoute = - projectMemberDetailsByIDPageRoutePamImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => pamLayoutRoute, - } as any) +const projectMemberDetailsByIDPageRoutePamRoute = projectMemberDetailsByIDPageRoutePamImport.update( + { + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => pamLayoutRoute + } as any +); const projectIdentityDetailsByIDPageRoutePamRoute = projectIdentityDetailsByIDPageRoutePamImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => pamLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => pamLayoutRoute + } as any); -const projectGroupDetailsByIDPageRoutePamRoute = - projectGroupDetailsByIDPageRoutePamImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => pamLayoutRoute, - } as any) +const projectGroupDetailsByIDPageRoutePamRoute = projectGroupDetailsByIDPageRoutePamImport.update({ + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => pamLayoutRoute +} as any); -const projectRoleDetailsBySlugPageRouteKmsRoute = - projectRoleDetailsBySlugPageRouteKmsImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => kmsLayoutRoute, - } as any) +const projectRoleDetailsBySlugPageRouteKmsRoute = projectRoleDetailsBySlugPageRouteKmsImport.update( + { + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => kmsLayoutRoute + } as any +); -const projectMemberDetailsByIDPageRouteKmsRoute = - projectMemberDetailsByIDPageRouteKmsImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => kmsLayoutRoute, - } as any) +const projectMemberDetailsByIDPageRouteKmsRoute = projectMemberDetailsByIDPageRouteKmsImport.update( + { + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => kmsLayoutRoute + } as any +); const projectIdentityDetailsByIDPageRouteKmsRoute = projectIdentityDetailsByIDPageRouteKmsImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => kmsLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => kmsLayoutRoute + } as any); -const projectGroupDetailsByIDPageRouteKmsRoute = - projectGroupDetailsByIDPageRouteKmsImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => kmsLayoutRoute, - } as any) +const projectGroupDetailsByIDPageRouteKmsRoute = projectGroupDetailsByIDPageRouteKmsImport.update({ + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => kmsLayoutRoute +} as any); const projectRoleDetailsBySlugPageRouteCertManagerRoute = projectRoleDetailsBySlugPageRouteCertManagerImport.update({ - id: '/roles/$roleSlug', - path: '/roles/$roleSlug', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/roles/$roleSlug", + path: "/roles/$roleSlug", + getParentRoute: () => certManagerLayoutRoute + } as any); const certManagerPkiCollectionDetailsByIDPageRoutesRoute = certManagerPkiCollectionDetailsByIDPageRoutesImport.update({ - id: '/pki-collections/$collectionId', - path: '/pki-collections/$collectionId', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/pki-collections/$collectionId", + path: "/pki-collections/$collectionId", + getParentRoute: () => certManagerLayoutRoute + } as any); const projectMemberDetailsByIDPageRouteCertManagerRoute = projectMemberDetailsByIDPageRouteCertManagerImport.update({ - id: '/members/$membershipId', - path: '/members/$membershipId', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/members/$membershipId", + path: "/members/$membershipId", + getParentRoute: () => certManagerLayoutRoute + } as any); const projectIdentityDetailsByIDPageRouteCertManagerRoute = projectIdentityDetailsByIDPageRouteCertManagerImport.update({ - id: '/identities/$identityId', - path: '/identities/$identityId', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/identities/$identityId", + path: "/identities/$identityId", + getParentRoute: () => certManagerLayoutRoute + } as any); const projectGroupDetailsByIDPageRouteCertManagerRoute = projectGroupDetailsByIDPageRouteCertManagerImport.update({ - id: '/groups/$groupId', - path: '/groups/$groupId', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/groups/$groupId", + path: "/groups/$groupId", + getParentRoute: () => certManagerLayoutRoute + } as any); -const sshSshHostGroupDetailsByIDPageRouteRoute = - sshSshHostGroupDetailsByIDPageRouteImport.update({ - id: '/ssh-host-groups/$sshHostGroupId', - path: '/ssh-host-groups/$sshHostGroupId', - getParentRoute: () => sshLayoutRoute, - } as any) +const sshSshHostGroupDetailsByIDPageRouteRoute = sshSshHostGroupDetailsByIDPageRouteImport.update({ + id: "/ssh-host-groups/$sshHostGroupId", + path: "/ssh-host-groups/$sshHostGroupId", + getParentRoute: () => sshLayoutRoute +} as any); const sshSshCaByIDPageRouteRoute = sshSshCaByIDPageRouteImport.update({ - id: '/ca/$caId', - path: '/ca/$caId', - getParentRoute: () => sshLayoutRoute, -} as any) + id: "/ca/$caId", + path: "/ca/$caId", + getParentRoute: () => sshLayoutRoute +} as any); const secretManagerSecretDashboardPageRouteRoute = secretManagerSecretDashboardPageRouteImport.update({ - id: '/secrets/$envSlug', - path: '/secrets/$envSlug', - getParentRoute: () => secretManagerLayoutRoute, - } as any) + id: "/secrets/$envSlug", + path: "/secrets/$envSlug", + getParentRoute: () => secretManagerLayoutRoute + } as any); const secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute = secretManagerIntegrationsSelectIntegrationAuthPageRouteImport.update({ - id: '/select-integration-auth', - path: '/select-integration-auth', + id: "/select-integration-auth", + path: "/select-integration-auth", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsDetailsByIDPageRouteRoute = secretManagerIntegrationsDetailsByIDPageRouteImport.update({ - id: '/$integrationId', - path: '/$integrationId', + id: "/$integrationId", + path: "/$integrationId", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); -const pamPamSessionsByIDPageRouteRoute = - pamPamSessionsByIDPageRouteImport.update({ - id: '/$sessionId', - path: '/$sessionId', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute, - } as any) +const pamPamSessionsByIDPageRouteRoute = pamPamSessionsByIDPageRouteImport.update({ + id: "/$sessionId", + path: "/$sessionId", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute +} as any); -const pamApprovalRequestDetailPageRouteRoute = - pamApprovalRequestDetailPageRouteImport.update({ - id: '/approval-requests/$approvalRequestId', - path: '/approval-requests/$approvalRequestId', - getParentRoute: () => pamLayoutRoute, - } as any) +const pamApprovalRequestDetailPageRouteRoute = pamApprovalRequestDetailPageRouteImport.update({ + id: "/approval-requests/$approvalRequestId", + path: "/approval-requests/$approvalRequestId", + getParentRoute: () => pamLayoutRoute +} as any); const certManagerPkiSubscriberDetailsByIDPageRouteRoute = certManagerPkiSubscriberDetailsByIDPageRouteImport.update({ - id: '/$subscriberName', - path: '/$subscriberName', + id: "/$subscriberName", + path: "/$subscriberName", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute + } as any); const certManagerPkiSyncDetailsByIDPageRouteRoute = certManagerPkiSyncDetailsByIDPageRouteImport.update({ - id: '/$syncId', - path: '/$syncId', + id: "/$syncId", + path: "/$syncId", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute + } as any); const certManagerCertAuthDetailsByIDPageRouteRoute = certManagerCertAuthDetailsByIDPageRouteImport.update({ - id: '/ca/$caId', - path: '/ca/$caId', - getParentRoute: () => certManagerLayoutRoute, - } as any) + id: "/ca/$caId", + path: "/ca/$caId", + getParentRoute: () => certManagerLayoutRoute + } as any); const secretScanningSecretScanningDataSourcesPageRouteRoute = secretScanningSecretScanningDataSourcesPageRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute + } as any); const secretManagerIntegrationsListPageRouteRoute = secretManagerIntegrationsListPageRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const pamPamSessionsPageRouteRoute = pamPamSessionsPageRouteImport.update({ - id: '/', - path: '/', + id: "/", + path: "/", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute, -} as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute +} as any); -const certManagerPkiSubscribersPageRouteRoute = - certManagerPkiSubscribersPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute, - } as any) +const certManagerPkiSubscribersPageRouteRoute = certManagerPkiSubscribersPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute +} as any); -const certManagerIntegrationsListPageRouteRoute = - certManagerIntegrationsListPageRouteImport.update({ - id: '/', - path: '/', +const certManagerIntegrationsListPageRouteRoute = certManagerIntegrationsListPageRouteImport.update( + { + id: "/", + path: "/", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute + } as any +); -const certManagerPkiTemplateListPageRouteRoute = - certManagerPkiTemplateListPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute, - } as any) +const certManagerPkiTemplateListPageRouteRoute = certManagerPkiTemplateListPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRoute +} as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport.update( { - id: '/commits/$environment/$folderId', - path: '/commits/$environment/$folderId', - getParentRoute: () => secretManagerLayoutRoute, - } as any, - ) + id: "/commits/$environment/$folderId", + path: "/commits/$environment/$folderId", + getParentRoute: () => secretManagerLayoutRoute + } as any + ); const secretScanningSecretScanningDataSourceByIdPageRouteRoute = secretScanningSecretScanningDataSourceByIdPageRouteImport.update({ - id: '/$type/$dataSourceId', - path: '/$type/$dataSourceId', + id: "/$type/$dataSourceId", + path: "/$type/$dataSourceId", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute + } as any); const secretManagerIntegrationsWindmillConfigurePageRouteRoute = secretManagerIntegrationsWindmillConfigurePageRouteImport.update({ - id: '/windmill/create', - path: '/windmill/create', + id: "/windmill/create", + path: "/windmill/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsWindmillAuthorizePageRouteRoute = secretManagerIntegrationsWindmillAuthorizePageRouteImport.update({ - id: '/windmill/authorize', - path: '/windmill/authorize', + id: "/windmill/authorize", + path: "/windmill/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsVercelConfigurePageRouteRoute = secretManagerIntegrationsVercelConfigurePageRouteImport.update({ - id: '/vercel/create', - path: '/vercel/create', + id: "/vercel/create", + path: "/vercel/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTravisCIConfigurePageRouteRoute = secretManagerIntegrationsTravisCIConfigurePageRouteImport.update({ - id: '/travisci/create', - path: '/travisci/create', + id: "/travisci/create", + path: "/travisci/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTravisCIAuthorizePageRouteRoute = secretManagerIntegrationsTravisCIAuthorizePageRouteImport.update({ - id: '/travisci/authorize', - path: '/travisci/authorize', + id: "/travisci/authorize", + path: "/travisci/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute = secretManagerIntegrationsTerraformCloudConfigurePageRouteImport.update({ - id: '/terraform-cloud/create', - path: '/terraform-cloud/create', + id: "/terraform-cloud/create", + path: "/terraform-cloud/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute = secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport.update({ - id: '/terraform-cloud/authorize', - path: '/terraform-cloud/authorize', + id: "/terraform-cloud/authorize", + path: "/terraform-cloud/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTeamcityConfigurePageRouteRoute = secretManagerIntegrationsTeamcityConfigurePageRouteImport.update({ - id: '/teamcity/create', - path: '/teamcity/create', + id: "/teamcity/create", + path: "/teamcity/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsTeamcityAuthorizePageRouteRoute = secretManagerIntegrationsTeamcityAuthorizePageRouteImport.update({ - id: '/teamcity/authorize', - path: '/teamcity/authorize', + id: "/teamcity/authorize", + path: "/teamcity/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsSupabaseConfigurePageRouteRoute = secretManagerIntegrationsSupabaseConfigurePageRouteImport.update({ - id: '/supabase/create', - path: '/supabase/create', + id: "/supabase/create", + path: "/supabase/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsSupabaseAuthorizePageRouteRoute = secretManagerIntegrationsSupabaseAuthorizePageRouteImport.update({ - id: '/supabase/authorize', - path: '/supabase/authorize', + id: "/supabase/authorize", + path: "/supabase/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRundeckConfigurePageRouteRoute = secretManagerIntegrationsRundeckConfigurePageRouteImport.update({ - id: '/rundeck/create', - path: '/rundeck/create', + id: "/rundeck/create", + path: "/rundeck/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRundeckAuthorizePageRouteRoute = secretManagerIntegrationsRundeckAuthorizePageRouteImport.update({ - id: '/rundeck/authorize', - path: '/rundeck/authorize', + id: "/rundeck/authorize", + path: "/rundeck/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRenderConfigurePageRouteRoute = secretManagerIntegrationsRenderConfigurePageRouteImport.update({ - id: '/render/create', - path: '/render/create', + id: "/render/create", + path: "/render/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRenderAuthorizePageRouteRoute = secretManagerIntegrationsRenderAuthorizePageRouteImport.update({ - id: '/render/authorize', - path: '/render/authorize', + id: "/render/authorize", + path: "/render/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRailwayConfigurePageRouteRoute = secretManagerIntegrationsRailwayConfigurePageRouteImport.update({ - id: '/railway/create', - path: '/railway/create', + id: "/railway/create", + path: "/railway/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsRailwayAuthorizePageRouteRoute = secretManagerIntegrationsRailwayAuthorizePageRouteImport.update({ - id: '/railway/authorize', - path: '/railway/authorize', + id: "/railway/authorize", + path: "/railway/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsQoveryConfigurePageRouteRoute = secretManagerIntegrationsQoveryConfigurePageRouteImport.update({ - id: '/qovery/create', - path: '/qovery/create', + id: "/qovery/create", + path: "/qovery/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsQoveryAuthorizePageRouteRoute = secretManagerIntegrationsQoveryAuthorizePageRouteImport.update({ - id: '/qovery/authorize', - path: '/qovery/authorize', + id: "/qovery/authorize", + path: "/qovery/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute = secretManagerIntegrationsOctopusDeployConfigurePageRouteImport.update({ - id: '/octopus-deploy/create', - path: '/octopus-deploy/create', + id: "/octopus-deploy/create", + path: "/octopus-deploy/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute = secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport.update({ - id: '/octopus-deploy/authorize', - path: '/octopus-deploy/authorize', + id: "/octopus-deploy/authorize", + path: "/octopus-deploy/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsNorthflankConfigurePageRouteRoute = secretManagerIntegrationsNorthflankConfigurePageRouteImport.update({ - id: '/northflank/create', - path: '/northflank/create', + id: "/northflank/create", + path: "/northflank/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsNorthflankAuthorizePageRouteRoute = secretManagerIntegrationsNorthflankAuthorizePageRouteImport.update({ - id: '/northflank/authorize', - path: '/northflank/authorize', + id: "/northflank/authorize", + path: "/northflank/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsNetlifyConfigurePageRouteRoute = secretManagerIntegrationsNetlifyConfigurePageRouteImport.update({ - id: '/netlify/create', - path: '/netlify/create', + id: "/netlify/create", + path: "/netlify/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute = secretManagerIntegrationsLaravelForgeConfigurePageRouteImport.update({ - id: '/laravel-forge/create', - path: '/laravel-forge/create', + id: "/laravel-forge/create", + path: "/laravel-forge/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute = secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport.update({ - id: '/laravel-forge/authorize', - path: '/laravel-forge/authorize', + id: "/laravel-forge/authorize", + path: "/laravel-forge/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHerokuConfigurePageRouteRoute = secretManagerIntegrationsHerokuConfigurePageRouteImport.update({ - id: '/heroku/create', - path: '/heroku/create', + id: "/heroku/create", + path: "/heroku/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute = secretManagerIntegrationsHasuraCloudConfigurePageRouteImport.update({ - id: '/hasura-cloud/create', - path: '/hasura-cloud/create', + id: "/hasura-cloud/create", + path: "/hasura-cloud/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute = secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport.update({ - id: '/hasura-cloud/authorize', - path: '/hasura-cloud/authorize', + id: "/hasura-cloud/authorize", + path: "/hasura-cloud/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute = secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport.update({ - id: '/hashicorp-vault/create', - path: '/hashicorp-vault/create', + id: "/hashicorp-vault/create", + path: "/hashicorp-vault/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute = secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport.update({ - id: '/hashicorp-vault/authorize', - path: '/hashicorp-vault/authorize', + id: "/hashicorp-vault/authorize", + path: "/hashicorp-vault/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGitlabConfigurePageRouteRoute = secretManagerIntegrationsGitlabConfigurePageRouteImport.update({ - id: '/gitlab/create', - path: '/gitlab/create', + id: "/gitlab/create", + path: "/gitlab/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGitlabAuthorizePageRouteRoute = secretManagerIntegrationsGitlabAuthorizePageRouteImport.update({ - id: '/gitlab/authorize', - path: '/gitlab/authorize', + id: "/gitlab/authorize", + path: "/gitlab/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGithubConfigurePageRouteRoute = secretManagerIntegrationsGithubConfigurePageRouteImport.update({ - id: '/github/create', - path: '/github/create', + id: "/github/create", + path: "/github/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGithubAuthorizePageRouteRoute = secretManagerIntegrationsGithubAuthorizePageRouteImport.update({ - id: '/github/auth-mode-selection', - path: '/github/auth-mode-selection', + id: "/github/auth-mode-selection", + path: "/github/auth-mode-selection", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute = secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport.update({ - id: '/gcp-secret-manager/create', - path: '/gcp-secret-manager/create', + id: "/gcp-secret-manager/create", + path: "/gcp-secret-manager/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute = secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport.update({ - id: '/gcp-secret-manager/authorize', - path: '/gcp-secret-manager/authorize', + id: "/gcp-secret-manager/authorize", + path: "/gcp-secret-manager/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsFlyioConfigurePageRouteRoute = secretManagerIntegrationsFlyioConfigurePageRouteImport.update({ - id: '/flyio/create', - path: '/flyio/create', + id: "/flyio/create", + path: "/flyio/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsFlyioAuthorizePageRouteRoute = secretManagerIntegrationsFlyioAuthorizePageRouteImport.update({ - id: '/flyio/authorize', - path: '/flyio/authorize', + id: "/flyio/authorize", + path: "/flyio/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute = - secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport.update( - { - id: '/digital-ocean-app-platform/create', - path: '/digital-ocean-app-platform/create', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any, - ) + secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport.update({ + id: "/digital-ocean-app-platform/create", + path: "/digital-ocean-app-platform/create", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute = - secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport.update( - { - id: '/digital-ocean-app-platform/authorize', - path: '/digital-ocean-app-platform/authorize', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any, - ) + secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport.update({ + id: "/digital-ocean-app-platform/authorize", + path: "/digital-ocean-app-platform/authorize", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsDatabricksConfigurePageRouteRoute = secretManagerIntegrationsDatabricksConfigurePageRouteImport.update({ - id: '/databricks/create', - path: '/databricks/create', + id: "/databricks/create", + path: "/databricks/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsDatabricksAuthorizePageRouteRoute = secretManagerIntegrationsDatabricksAuthorizePageRouteImport.update({ - id: '/databricks/authorize', - path: '/databricks/authorize', + id: "/databricks/authorize", + path: "/databricks/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCodefreshConfigurePageRouteRoute = secretManagerIntegrationsCodefreshConfigurePageRouteImport.update({ - id: '/codefresh/create', - path: '/codefresh/create', + id: "/codefresh/create", + path: "/codefresh/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCodefreshAuthorizePageRouteRoute = secretManagerIntegrationsCodefreshAuthorizePageRouteImport.update({ - id: '/codefresh/authorize', - path: '/codefresh/authorize', + id: "/codefresh/authorize", + path: "/codefresh/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute = secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport.update({ - id: '/cloudflare-workers/create', - path: '/cloudflare-workers/create', + id: "/cloudflare-workers/create", + path: "/cloudflare-workers/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute = secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport.update({ - id: '/cloudflare-workers/authorize', - path: '/cloudflare-workers/authorize', + id: "/cloudflare-workers/authorize", + path: "/cloudflare-workers/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute = secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport.update({ - id: '/cloudflare-pages/create', - path: '/cloudflare-pages/create', + id: "/cloudflare-pages/create", + path: "/cloudflare-pages/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute = secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport.update({ - id: '/cloudflare-pages/authorize', - path: '/cloudflare-pages/authorize', + id: "/cloudflare-pages/authorize", + path: "/cloudflare-pages/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloud66ConfigurePageRouteRoute = secretManagerIntegrationsCloud66ConfigurePageRouteImport.update({ - id: '/cloud-66/create', - path: '/cloud-66/create', + id: "/cloud-66/create", + path: "/cloud-66/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCloud66AuthorizePageRouteRoute = secretManagerIntegrationsCloud66AuthorizePageRouteImport.update({ - id: '/cloud-66/authorize', - path: '/cloud-66/authorize', + id: "/cloud-66/authorize", + path: "/cloud-66/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCircleCIConfigurePageRouteRoute = secretManagerIntegrationsCircleCIConfigurePageRouteImport.update({ - id: '/circleci/create', - path: '/circleci/create', + id: "/circleci/create", + path: "/circleci/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsCircleCIAuthorizePageRouteRoute = secretManagerIntegrationsCircleCIAuthorizePageRouteImport.update({ - id: '/circleci/authorize', - path: '/circleci/authorize', + id: "/circleci/authorize", + path: "/circleci/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsChecklyConfigurePageRouteRoute = secretManagerIntegrationsChecklyConfigurePageRouteImport.update({ - id: '/checkly/create', - path: '/checkly/create', + id: "/checkly/create", + path: "/checkly/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsChecklyAuthorizePageRouteRoute = secretManagerIntegrationsChecklyAuthorizePageRouteImport.update({ - id: '/checkly/authorize', - path: '/checkly/authorize', + id: "/checkly/authorize", + path: "/checkly/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsBitbucketConfigurePageRouteRoute = secretManagerIntegrationsBitbucketConfigurePageRouteImport.update({ - id: '/bitbucket/create', - path: '/bitbucket/create', + id: "/bitbucket/create", + path: "/bitbucket/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute = secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport.update({ - id: '/azure-key-vault/create', - path: '/azure-key-vault/create', + id: "/azure-key-vault/create", + path: "/azure-key-vault/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute = secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport.update({ - id: '/azure-key-vault/authorize', - path: '/azure-key-vault/authorize', + id: "/azure-key-vault/authorize", + path: "/azure-key-vault/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute = secretManagerIntegrationsAzureDevopsConfigurePageRouteImport.update({ - id: '/azure-devops/create', - path: '/azure-devops/create', + id: "/azure-devops/create", + path: "/azure-devops/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute = secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport.update({ - id: '/azure-devops/authorize', - path: '/azure-devops/authorize', + id: "/azure-devops/authorize", + path: "/azure-devops/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute = - secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport.update( - { - id: '/azure-app-configuration/create', - path: '/azure-app-configuration/create', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any, - ) + secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport.update({ + id: "/azure-app-configuration/create", + path: "/azure-app-configuration/create", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute = secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport.update({ - id: '/aws-secret-manager/create', - path: '/aws-secret-manager/create', + id: "/aws-secret-manager/create", + path: "/aws-secret-manager/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute = secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport.update({ - id: '/aws-secret-manager/authorize', - path: '/aws-secret-manager/authorize', + id: "/aws-secret-manager/authorize", + path: "/aws-secret-manager/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute = secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport.update({ - id: '/aws-parameter-store/create', - path: '/aws-parameter-store/create', + id: "/aws-parameter-store/create", + path: "/aws-parameter-store/create", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute = secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport.update({ - id: '/aws-parameter-store/authorize', - path: '/aws-parameter-store/authorize', + id: "/aws-parameter-store/authorize", + path: "/aws-parameter-store/authorize", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport.update( { - id: '/$commitId', - path: '/$commitId', + id: "/$commitId", + path: "/$commitId", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute, - } as any, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute + } as any + ); const secretManagerIntegrationsVercelOauthCallbackPageRouteRoute = secretManagerIntegrationsVercelOauthCallbackPageRouteImport.update({ - id: '/vercel/oauth2/callback', - path: '/vercel/oauth2/callback', + id: "/vercel/oauth2/callback", + path: "/vercel/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerSecretSyncDetailsByIDPageRouteRoute = secretManagerSecretSyncDetailsByIDPageRouteImport.update({ - id: '/secret-syncs/$destination/$syncId', - path: '/secret-syncs/$destination/$syncId', + id: "/secret-syncs/$destination/$syncId", + path: "/secret-syncs/$destination/$syncId", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute = secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport.update({ - id: '/netlify/oauth2/callback', - path: '/netlify/oauth2/callback', + id: "/netlify/oauth2/callback", + path: "/netlify/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute = secretManagerIntegrationsHerokuOauthCallbackPageRouteImport.update({ - id: '/heroku/oauth2/callback', - path: '/heroku/oauth2/callback', + id: "/heroku/oauth2/callback", + path: "/heroku/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute = secretManagerIntegrationsGitlabOauthCallbackPageRouteImport.update({ - id: '/gitlab/oauth2/callback', - path: '/gitlab/oauth2/callback', + id: "/gitlab/oauth2/callback", + path: "/gitlab/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGithubOauthCallbackPageRouteRoute = secretManagerIntegrationsGithubOauthCallbackPageRouteImport.update({ - id: '/github/oauth2/callback', - path: '/github/oauth2/callback', + id: "/github/oauth2/callback", + path: "/github/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute = secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport.update({ - id: '/gcp-secret-manager/oauth2/callback', - path: '/gcp-secret-manager/oauth2/callback', + id: "/gcp-secret-manager/oauth2/callback", + path: "/gcp-secret-manager/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute = secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport.update({ - id: '/bitbucket/oauth2/callback', - path: '/bitbucket/oauth2/callback', + id: "/bitbucket/oauth2/callback", + path: "/bitbucket/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute = secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport.update({ - id: '/azure-key-vault/oauth2/callback', - path: '/azure-key-vault/oauth2/callback', + id: "/azure-key-vault/oauth2/callback", + path: "/azure-key-vault/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); const secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute = - secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport.update( - { - id: '/azure-app-configuration/oauth2/callback', - path: '/azure-app-configuration/oauth2/callback', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute, - } as any, - ) - -const secretManagerCommitsPageRouteRoute = - secretManagerCommitsPageRouteImport.update({ - id: '/', - path: '/', + secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport.update({ + id: "/azure-app-configuration/oauth2/callback", + path: "/azure-app-configuration/oauth2/callback", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute + } as any); + +const secretManagerCommitsPageRouteRoute = secretManagerCommitsPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute +} as any); const secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute = secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport.update({ - id: '/restore', - path: '/restore', + id: "/restore", + path: "/restore", getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, - } as any) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute + } as any); -const secretManagerCommitDetailsPageRouteRoute = - secretManagerCommitDetailsPageRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute, - } as any) +const secretManagerCommitDetailsPageRouteRoute = secretManagerCommitDetailsPageRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute +} as any); // Populate the FileRoutesByPath interface -declare module '@tanstack/react-router' { +declare module "@tanstack/react-router" { interface FileRoutesByPath { - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof indexImport - parentRoute: typeof rootRoute - } - '/cli-redirect': { - id: '/cli-redirect' - path: '/cli-redirect' - fullPath: '/cli-redirect' - preLoaderRoute: typeof authCliRedirectPageRouteImport - parentRoute: typeof rootRoute - } - '/share-secret': { - id: '/share-secret' - path: '/share-secret' - fullPath: '/share-secret' - preLoaderRoute: typeof publicShareSecretPageRouteImport - parentRoute: typeof rootRoute - } - '/upgrade-path': { - id: '/upgrade-path' - path: '/upgrade-path' - fullPath: '/upgrade-path' - preLoaderRoute: typeof publicUpgradePathPageRouteImport - parentRoute: typeof rootRoute - } - '/_authenticate': { - id: '/_authenticate' - path: '' - fullPath: '' - preLoaderRoute: typeof middlewaresAuthenticateImport - parentRoute: typeof rootRoute - } - '/_restrict-login-signup': { - id: '/_restrict-login-signup' - path: '' - fullPath: '' - preLoaderRoute: typeof middlewaresRestrictLoginSignupImport - parentRoute: typeof rootRoute - } - '/_authenticate/password-setup': { - id: '/_authenticate/password-setup' - path: '/password-setup' - fullPath: '/password-setup' - preLoaderRoute: typeof authPasswordSetupPageRouteImport - parentRoute: typeof middlewaresAuthenticateImport - } - '/_restrict-login-signup/email-not-verified': { - id: '/_restrict-login-signup/email-not-verified' - path: '/email-not-verified' - fullPath: '/email-not-verified' - preLoaderRoute: typeof authEmailNotVerifiedPageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/password-reset': { - id: '/_restrict-login-signup/password-reset' - path: '/password-reset' - fullPath: '/password-reset' - preLoaderRoute: typeof authPasswordResetPageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/requestnewinvite': { - id: '/_restrict-login-signup/requestnewinvite' - path: '/requestnewinvite' - fullPath: '/requestnewinvite' - preLoaderRoute: typeof authRequestNewInvitePageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/signupinvite': { - id: '/_restrict-login-signup/signupinvite' - path: '/signupinvite' - fullPath: '/signupinvite' - preLoaderRoute: typeof authSignUpInvitePageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/verify-email': { - id: '/_restrict-login-signup/verify-email' - path: '/verify-email' - fullPath: '/verify-email' - preLoaderRoute: typeof authVerifyEmailPageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_authenticate/_inject-org-details': { - id: '/_authenticate/_inject-org-details' - path: '' - fullPath: '' - preLoaderRoute: typeof middlewaresInjectOrgDetailsImport - parentRoute: typeof middlewaresAuthenticateImport - } - '/_authenticate/personal-settings': { - id: '/_authenticate/personal-settings' - path: '/personal-settings' - fullPath: '/personal-settings' - preLoaderRoute: typeof AuthenticatePersonalSettingsImport - parentRoute: typeof middlewaresAuthenticateImport - } - '/_restrict-login-signup/login': { - id: '/_restrict-login-signup/login' - path: '/login' - fullPath: '/login' - preLoaderRoute: typeof RestrictLoginSignupLoginImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/signup': { - id: '/_restrict-login-signup/signup' - path: '/signup' - fullPath: '/signup' - preLoaderRoute: typeof RestrictLoginSignupSignupImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/login/': { - id: '/_restrict-login-signup/login/' - path: '/' - fullPath: '/login/' - preLoaderRoute: typeof authLoginPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/signup/': { - id: '/_restrict-login-signup/signup/' - path: '/' - fullPath: '/signup/' - preLoaderRoute: typeof authSignUpPageRouteImport - parentRoute: typeof RestrictLoginSignupSignupImport - } - '/_authenticate/organizations/none': { - id: '/_authenticate/organizations/none' - path: '/organizations/none' - fullPath: '/organizations/none' - preLoaderRoute: typeof organizationNoOrgPageRouteImport - parentRoute: typeof middlewaresAuthenticateImport - } - '/_restrict-login-signup/admin/signup': { - id: '/_restrict-login-signup/admin/signup' - path: '/admin/signup' - fullPath: '/admin/signup' - preLoaderRoute: typeof adminSignUpPageRouteImport - parentRoute: typeof middlewaresRestrictLoginSignupImport - } - '/_restrict-login-signup/login/admin': { - id: '/_restrict-login-signup/login/admin' - path: '/admin' - fullPath: '/login/admin' - preLoaderRoute: typeof authAdminLoginPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/login/ldap': { - id: '/_restrict-login-signup/login/ldap' - path: '/ldap' - fullPath: '/login/ldap' - preLoaderRoute: typeof authLoginLdapPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/login/select-organization': { - id: '/_restrict-login-signup/login/select-organization' - path: '/select-organization' - fullPath: '/login/select-organization' - preLoaderRoute: typeof authSelectOrgPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/login/sso': { - id: '/_restrict-login-signup/login/sso' - path: '/sso' - fullPath: '/login/sso' - preLoaderRoute: typeof authLoginSsoPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/signup/sso': { - id: '/_restrict-login-signup/signup/sso' - path: '/sso' - fullPath: '/signup/sso' - preLoaderRoute: typeof authSignUpSsoPageRouteImport - parentRoute: typeof RestrictLoginSignupSignupImport - } - '/secret-request/secret/$secretRequestId': { - id: '/secret-request/secret/$secretRequestId' - path: '/secret-request/secret/$secretRequestId' - fullPath: '/secret-request/secret/$secretRequestId' - preLoaderRoute: typeof publicViewSecretRequestByIDPageRouteImport - parentRoute: typeof rootRoute - } - '/shared/secret/$secretId': { - id: '/shared/secret/$secretId' - path: '/shared/secret/$secretId' - fullPath: '/shared/secret/$secretId' - preLoaderRoute: typeof publicViewSharedSecretByIDPageRouteImport - parentRoute: typeof rootRoute - } - '/_authenticate/_inject-org-details/_org-layout': { - id: '/_authenticate/_inject-org-details/_org-layout' - path: '' - fullPath: '' - preLoaderRoute: typeof organizationLayoutImport - parentRoute: typeof middlewaresInjectOrgDetailsImport - } - '/_authenticate/_inject-org-details/admin': { - id: '/_authenticate/_inject-org-details/admin' - path: '/admin' - fullPath: '/admin' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsAdminImport - parentRoute: typeof middlewaresInjectOrgDetailsImport - } - '/_authenticate/personal-settings/_layout': { - id: '/_authenticate/personal-settings/_layout' - path: '' - fullPath: '/personal-settings' - preLoaderRoute: typeof userLayoutImport - parentRoute: typeof AuthenticatePersonalSettingsImport - } - '/_authenticate/personal-settings/_layout/': { - id: '/_authenticate/personal-settings/_layout/' - path: '/' - fullPath: '/personal-settings/' - preLoaderRoute: typeof userPersonalSettingsPageRouteImport - parentRoute: typeof userLayoutImport - } - '/_restrict-login-signup/login/provider/error': { - id: '/_restrict-login-signup/login/provider/error' - path: '/provider/error' - fullPath: '/login/provider/error' - preLoaderRoute: typeof authProviderErrorPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_restrict-login-signup/login/provider/success': { - id: '/_restrict-login-signup/login/provider/success' - path: '/provider/success' - fullPath: '/login/provider/success' - preLoaderRoute: typeof authProviderSuccessPageRouteImport - parentRoute: typeof RestrictLoginSignupLoginImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations' - path: '/integrations' - fullPath: '/integrations' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - parentRoute: typeof organizationLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout' - path: '' - fullPath: '/admin' - preLoaderRoute: typeof adminLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsAdminImport - } - '/_authenticate/_inject-org-details/organization/$': { - id: '/_authenticate/_inject-org-details/organization/$' - path: '/organization/$' - fullPath: '/organization/$' - preLoaderRoute: typeof redirectsOrganizationRedirectImport - parentRoute: typeof middlewaresInjectOrgDetailsImport - } - '/_authenticate/_inject-org-details/projects/$': { - id: '/_authenticate/_inject-org-details/projects/$' - path: '/projects/$' - fullPath: '/projects/$' - preLoaderRoute: typeof redirectsProjectRedirectImport - parentRoute: typeof middlewaresInjectOrgDetailsImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/' - path: '/' - fullPath: '/admin/' - preLoaderRoute: typeof adminGeneralPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/access-management': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/access-management' - path: '/access-management' - fullPath: '/admin/access-management' - preLoaderRoute: typeof adminAccessManagementPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/authentication': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/authentication' - path: '/authentication' - fullPath: '/admin/authentication' - preLoaderRoute: typeof adminAuthenticationPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/caching': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/caching' - path: '/caching' - fullPath: '/admin/caching' - preLoaderRoute: typeof adminCachingPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/encryption': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/encryption' - path: '/encryption' - fullPath: '/admin/encryption' - preLoaderRoute: typeof adminEncryptionPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/environment': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/environment' - path: '/environment' - fullPath: '/admin/environment' - preLoaderRoute: typeof adminEnvironmentPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/integrations': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/integrations' - path: '/integrations' - fullPath: '/admin/integrations' - preLoaderRoute: typeof adminIntegrationsPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId' - path: '/organizations/$orgId' - fullPath: '/organizations/$orgId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - parentRoute: typeof organizationLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/access-management' - preLoaderRoute: typeof organizationAccessManagementPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/audit-logs' - preLoaderRoute: typeof organizationAuditLogsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing' - path: '/billing' - fullPath: '/organizations/$orgId/billing' - preLoaderRoute: typeof organizationBillingPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking' - path: '/networking' - fullPath: '/organizations/$orgId/networking' - preLoaderRoute: typeof organizationNetworkingPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects' - path: '/projects' - fullPath: '/organizations/$orgId/projects' - preLoaderRoute: typeof organizationProjectsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview': { - id: '/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview' - path: '/resources/overview' - fullPath: '/admin/resources/overview' - preLoaderRoute: typeof adminResourceOverviewPageRouteImport - parentRoute: typeof adminLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$' - path: '/$' - fullPath: '/organizations/$orgId/$' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections' - path: '/app-connections' - fullPath: '/organizations/$orgId/app-connections' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing' - path: '/secret-sharing' - fullPath: '/organizations/$orgId/secret-sharing' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings' - path: '/settings' - fullPath: '/organizations/$orgId/settings' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/' - path: '/' - fullPath: '/organizations/$orgId/app-connections/' - preLoaderRoute: typeof organizationAppConnectionsAppConnectionsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/' - path: '/' - fullPath: '/organizations/$orgId/secret-sharing/' - preLoaderRoute: typeof organizationSecretSharingPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/' - path: '/' - fullPath: '/organizations/$orgId/settings/' - preLoaderRoute: typeof organizationSettingsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/groups/$groupId' - preLoaderRoute: typeof organizationGroupDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/identities/$identityId' - preLoaderRoute: typeof organizationIdentityDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/members/$membershipId' - preLoaderRoute: typeof organizationUserDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId' - path: '/roles/$roleId' - fullPath: '/organizations/$orgId/roles/$roleId' - preLoaderRoute: typeof organizationRoleByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback' - path: '/azure-app-configuration/oauth2/callback' - fullPath: '/integrations/azure-app-configuration/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback' - path: '/azure-key-vault/oauth2/callback' - fullPath: '/integrations/azure-key-vault/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback' - path: '/bitbucket/oauth2/callback' - fullPath: '/integrations/bitbucket/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback' - path: '/gcp-secret-manager/oauth2/callback' - fullPath: '/integrations/gcp-secret-manager/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback' - path: '/github/oauth2/callback' - fullPath: '/integrations/github/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback' - path: '/gitlab/oauth2/callback' - fullPath: '/integrations/gitlab/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback' - path: '/heroku/oauth2/callback' - fullPath: '/integrations/heroku/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback' - path: '/netlify/oauth2/callback' - fullPath: '/integrations/netlify/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback' - path: '/vercel/oauth2/callback' - fullPath: '/integrations/vercel/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$' - path: '/$' - fullPath: '/organizations/$orgId/projects/$' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId' - path: '/secret-manager/$projectId' - fullPath: '/organizations/$orgId/secret-manager/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback' - path: '/oauth/callback' - fullPath: '/organizations/$orgId/settings/oauth/callback' - preLoaderRoute: typeof organizationSettingsPageOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId' - path: '/cert-management/$projectId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId' - path: '/kms/$projectId' - fullPath: '/organizations/$orgId/projects/kms/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId' - path: '/pam/$projectId' - fullPath: '/organizations/$orgId/projects/pam/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId' - path: '/secret-management/$projectId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId' - path: '/secret-scanning/$projectId' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId' - path: '/ssh/$projectId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport - parentRoute: typeof organizationProjectsPageRouteImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval' - path: '/approval' - fullPath: '/organizations/$orgId/secret-manager/$projectId/approval' - preLoaderRoute: typeof secretManagerRedirectsRedirectApprovalPageImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback' - path: '/$appConnection/oauth/callback' - fullPath: '/organizations/$orgId/app-connections/$appConnection/oauth/callback' - preLoaderRoute: typeof organizationAppConnectionsOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout' - path: '' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId' - preLoaderRoute: typeof certManagerLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout' - path: '' - fullPath: '/organizations/$orgId/projects/kms/$projectId' - preLoaderRoute: typeof kmsLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout' - path: '' - fullPath: '/organizations/$orgId/projects/pam/$projectId' - preLoaderRoute: typeof pamLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout' - path: '' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId' - preLoaderRoute: typeof secretManagerLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout' - path: '' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId' - preLoaderRoute: typeof secretScanningLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout' - path: '' - fullPath: '/organizations/$orgId/projects/ssh/$projectId' - preLoaderRoute: typeof sshLayoutImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting' - path: '/alerting' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/alerting' - preLoaderRoute: typeof certManagerAlertingPageRouteImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities' - path: '/certificate-authorities' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities' - preLoaderRoute: typeof certManagerCertificateAuthoritiesPageRouteImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies' - path: '/policies' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/policies' - preLoaderRoute: typeof certManagerPoliciesPageRouteImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/settings' - preLoaderRoute: typeof certManagerSettingsPageRouteImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip' - path: '/kmip' - fullPath: '/organizations/$orgId/projects/kms/$projectId/kmip' - preLoaderRoute: typeof kmsKmipPageRouteImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview' - path: '/overview' - fullPath: '/organizations/$orgId/projects/kms/$projectId/overview' - preLoaderRoute: typeof kmsOverviewPageRouteImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/kms/$projectId/settings' - preLoaderRoute: typeof kmsSettingsPageRouteImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts' - path: '/accounts' - fullPath: '/organizations/$orgId/projects/pam/$projectId/accounts' - preLoaderRoute: typeof pamPamAccountsPageRouteImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals' - path: '/approvals' - fullPath: '/organizations/$orgId/projects/pam/$projectId/approvals' - preLoaderRoute: typeof pamApprovalsPageRouteImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources' - path: '/resources' - fullPath: '/organizations/$orgId/projects/pam/$projectId/resources' - preLoaderRoute: typeof pamPamResourcesPageRouteImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/pam/$projectId/settings' - preLoaderRoute: typeof pamSettingsPageRouteImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist' - path: '/allowlist' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/allowlist' - preLoaderRoute: typeof secretManagerIPAllowlistPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval' - path: '/approval' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/approval' - preLoaderRoute: typeof secretManagerSecretApprovalsPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview' - path: '/overview' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/overview' - preLoaderRoute: typeof secretManagerOverviewPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation' - path: '/secret-rotation' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/secret-rotation' - preLoaderRoute: typeof secretManagerSecretRotationPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/settings' - preLoaderRoute: typeof secretManagerSettingsPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings' - path: '/findings' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/findings' - preLoaderRoute: typeof secretScanningSecretScanningFindingsPageRouteImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/settings' - preLoaderRoute: typeof secretScanningSettingsPageRouteImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas' - path: '/cas' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/cas' - preLoaderRoute: typeof sshSshCasPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates' - path: '/certificates' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/certificates' - preLoaderRoute: typeof sshSshCertsPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview' - path: '/overview' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/overview' - preLoaderRoute: typeof sshSshHostsPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings' - path: '/settings' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/settings' - preLoaderRoute: typeof sshSettingsPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections' - path: '/app-connections' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/app-connections' - preLoaderRoute: typeof projectAppConnectionsPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates' - path: '/certificate-templates' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations' - path: '/integrations' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/integrations' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers' - path: '/subscribers' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/subscribers' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/kms/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/kms/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/pam/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/pam/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions' - path: '/sessions' - fullPath: '/organizations/$orgId/projects/pam/$projectId/sessions' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections' - path: '/app-connections' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/app-connections' - preLoaderRoute: typeof projectAppConnectionsPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations' - path: '/integrations' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections' - path: '/app-connections' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/app-connections' - preLoaderRoute: typeof projectAppConnectionsPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources' - path: '/data-sources' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management' - path: '/access-management' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/access-management' - preLoaderRoute: typeof projectAccessControlPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs' - path: '/audit-logs' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/audit-logs' - preLoaderRoute: typeof projectAuditLogsPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/' - path: '/' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates/' - preLoaderRoute: typeof certManagerPkiTemplateListPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/' - path: '/' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/integrations/' - preLoaderRoute: typeof certManagerIntegrationsListPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/' - path: '/' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/subscribers/' - preLoaderRoute: typeof certManagerPkiSubscribersPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/' - path: '/' - fullPath: '/organizations/$orgId/projects/pam/$projectId/sessions/' - preLoaderRoute: typeof pamPamSessionsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/' - path: '/' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/' - preLoaderRoute: typeof secretManagerIntegrationsListPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/' - path: '/' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/' - preLoaderRoute: typeof secretScanningSecretScanningDataSourcesPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId' - path: '/ca/$caId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/ca/$caId' - preLoaderRoute: typeof certManagerCertAuthDetailsByIDPageRouteImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId' - path: '/$syncId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/integrations/$syncId' - preLoaderRoute: typeof certManagerPkiSyncDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName' - path: '/$subscriberName' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName' - preLoaderRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId' - path: '/approval-requests/$approvalRequestId' - fullPath: '/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId' - preLoaderRoute: typeof pamApprovalRequestDetailPageRouteImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId' - path: '/$sessionId' - fullPath: '/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId' - preLoaderRoute: typeof pamPamSessionsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId' - path: '/$integrationId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId' - preLoaderRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth' - path: '/select-integration-auth' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth' - preLoaderRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug' - path: '/secrets/$envSlug' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug' - preLoaderRoute: typeof secretManagerSecretDashboardPageRouteImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId' - path: '/ca/$caId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/ca/$caId' - preLoaderRoute: typeof sshSshCaByIDPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId' - path: '/ssh-host-groups/$sshHostGroupId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' - preLoaderRoute: typeof sshSshHostGroupDetailsByIDPageRouteImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId' - path: '/pki-collections/$collectionId' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId' - preLoaderRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/cert-management/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerImport - parentRoute: typeof certManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/kms/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/kms/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/kms/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteKmsImport - parentRoute: typeof kmsLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/pam/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/pam/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/pam/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRoutePamImport - parentRoute: typeof pamLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningImport - parentRoute: typeof secretScanningLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId' - path: '/groups/$groupId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/groups/$groupId' - preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId' - path: '/identities/$identityId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/identities/$identityId' - preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId' - path: '/members/$membershipId' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/members/$membershipId' - preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug' - path: '/roles/$roleSlug' - fullPath: '/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug' - preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSshImport - parentRoute: typeof sshLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize' - path: '/aws-parameter-store/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create' - path: '/aws-parameter-store/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create' - preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize' - path: '/aws-secret-manager/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create' - path: '/aws-secret-manager/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create' - preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create' - path: '/azure-app-configuration/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize' - path: '/azure-devops/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create' - path: '/azure-devops/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' - path: '/azure-key-vault/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' - preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' - path: '/azure-key-vault/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create' - preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create' - path: '/bitbucket/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create' - preLoaderRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize' - path: '/checkly/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize' - preLoaderRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create' - path: '/checkly/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create' - preLoaderRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize' - path: '/circleci/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create' - path: '/circleci/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create' - preLoaderRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize' - path: '/cloud-66/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create' - path: '/cloud-66/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create' - preLoaderRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize' - path: '/cloudflare-pages/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create' - path: '/cloudflare-pages/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create' - preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize' - path: '/cloudflare-workers/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create' - path: '/cloudflare-workers/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create' - preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize' - path: '/codefresh/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize' - preLoaderRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create' - path: '/codefresh/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create' - preLoaderRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize' - path: '/databricks/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize' - preLoaderRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create' - path: '/databricks/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create' - preLoaderRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' - path: '/digital-ocean-app-platform/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' - preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create' - path: '/digital-ocean-app-platform/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' - preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize' - path: '/flyio/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize' - preLoaderRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create' - path: '/flyio/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create' - preLoaderRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize' - path: '/gcp-secret-manager/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' - preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create' - path: '/gcp-secret-manager/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' - preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection' - path: '/github/auth-mode-selection' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection' - preLoaderRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create' - path: '/github/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create' - preLoaderRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize' - path: '/gitlab/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize' - preLoaderRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create' - path: '/gitlab/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create' - preLoaderRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize' - path: '/hashicorp-vault/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' - preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create' - path: '/hashicorp-vault/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create' - preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize' - path: '/hasura-cloud/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' - preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create' - path: '/hasura-cloud/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create' - preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create' - path: '/heroku/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create' - preLoaderRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize' - path: '/laravel-forge/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize' - preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create' - path: '/laravel-forge/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create' - preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create' - path: '/netlify/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create' - preLoaderRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize' - path: '/northflank/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize' - preLoaderRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create' - path: '/northflank/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create' - preLoaderRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize' - path: '/octopus-deploy/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' - preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create' - path: '/octopus-deploy/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create' - preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize' - path: '/qovery/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize' - preLoaderRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create' - path: '/qovery/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create' - preLoaderRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize' - path: '/railway/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create' - path: '/railway/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create' - preLoaderRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize' - path: '/render/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create' - path: '/render/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create' - preLoaderRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize' - path: '/rundeck/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize' - preLoaderRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create' - path: '/rundeck/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create' - preLoaderRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize' - path: '/supabase/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize' - preLoaderRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create' - path: '/supabase/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create' - preLoaderRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize' - path: '/teamcity/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create' - path: '/teamcity/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create' - preLoaderRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize' - path: '/terraform-cloud/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create' - path: '/terraform-cloud/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create' - preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize' - path: '/travisci/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize' - preLoaderRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create' - path: '/travisci/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create' - preLoaderRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create' - path: '/vercel/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create' - preLoaderRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize' - path: '/windmill/authorize' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize' - preLoaderRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create' - path: '/windmill/create' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create' - preLoaderRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId' - path: '/$type/$dataSourceId' - fullPath: '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' - preLoaderRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId' - path: '/commits/$environment/$folderId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport - parentRoute: typeof secretManagerLayoutImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/' - path: '/' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/' - preLoaderRoute: typeof secretManagerCommitsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' - path: '/azure-app-configuration/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' - path: '/azure-key-vault/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback' - path: '/bitbucket/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' - path: '/gcp-secret-manager/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback' - path: '/github/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsGithubOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback' - path: '/gitlab/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback' - path: '/heroku/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback' - path: '/netlify/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' - path: '/secret-syncs/$destination/$syncId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' - preLoaderRoute: typeof secretManagerSecretSyncDetailsByIDPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback' - path: '/vercel/oauth2/callback' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' - preLoaderRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId' - path: '/$commitId' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' - preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/' - path: '/' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/' - preLoaderRoute: typeof secretManagerCommitDetailsPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport - } - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': { - id: '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' - path: '/restore' - fullPath: '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' - preLoaderRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport - } + "/": { + id: "/"; + path: "/"; + fullPath: "/"; + preLoaderRoute: typeof indexImport; + parentRoute: typeof rootRoute; + }; + "/cli-redirect": { + id: "/cli-redirect"; + path: "/cli-redirect"; + fullPath: "/cli-redirect"; + preLoaderRoute: typeof authCliRedirectPageRouteImport; + parentRoute: typeof rootRoute; + }; + "/share-secret": { + id: "/share-secret"; + path: "/share-secret"; + fullPath: "/share-secret"; + preLoaderRoute: typeof publicShareSecretPageRouteImport; + parentRoute: typeof rootRoute; + }; + "/upgrade-path": { + id: "/upgrade-path"; + path: "/upgrade-path"; + fullPath: "/upgrade-path"; + preLoaderRoute: typeof publicUpgradePathPageRouteImport; + parentRoute: typeof rootRoute; + }; + "/_authenticate": { + id: "/_authenticate"; + path: ""; + fullPath: ""; + preLoaderRoute: typeof middlewaresAuthenticateImport; + parentRoute: typeof rootRoute; + }; + "/_restrict-login-signup": { + id: "/_restrict-login-signup"; + path: ""; + fullPath: ""; + preLoaderRoute: typeof middlewaresRestrictLoginSignupImport; + parentRoute: typeof rootRoute; + }; + "/_authenticate/password-setup": { + id: "/_authenticate/password-setup"; + path: "/password-setup"; + fullPath: "/password-setup"; + preLoaderRoute: typeof authPasswordSetupPageRouteImport; + parentRoute: typeof middlewaresAuthenticateImport; + }; + "/_restrict-login-signup/email-not-verified": { + id: "/_restrict-login-signup/email-not-verified"; + path: "/email-not-verified"; + fullPath: "/email-not-verified"; + preLoaderRoute: typeof authEmailNotVerifiedPageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/password-reset": { + id: "/_restrict-login-signup/password-reset"; + path: "/password-reset"; + fullPath: "/password-reset"; + preLoaderRoute: typeof authPasswordResetPageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/requestnewinvite": { + id: "/_restrict-login-signup/requestnewinvite"; + path: "/requestnewinvite"; + fullPath: "/requestnewinvite"; + preLoaderRoute: typeof authRequestNewInvitePageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/signupinvite": { + id: "/_restrict-login-signup/signupinvite"; + path: "/signupinvite"; + fullPath: "/signupinvite"; + preLoaderRoute: typeof authSignUpInvitePageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/verify-email": { + id: "/_restrict-login-signup/verify-email"; + path: "/verify-email"; + fullPath: "/verify-email"; + preLoaderRoute: typeof authVerifyEmailPageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_authenticate/_inject-org-details": { + id: "/_authenticate/_inject-org-details"; + path: ""; + fullPath: ""; + preLoaderRoute: typeof middlewaresInjectOrgDetailsImport; + parentRoute: typeof middlewaresAuthenticateImport; + }; + "/_authenticate/personal-settings": { + id: "/_authenticate/personal-settings"; + path: "/personal-settings"; + fullPath: "/personal-settings"; + preLoaderRoute: typeof AuthenticatePersonalSettingsImport; + parentRoute: typeof middlewaresAuthenticateImport; + }; + "/_restrict-login-signup/login": { + id: "/_restrict-login-signup/login"; + path: "/login"; + fullPath: "/login"; + preLoaderRoute: typeof RestrictLoginSignupLoginImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/signup": { + id: "/_restrict-login-signup/signup"; + path: "/signup"; + fullPath: "/signup"; + preLoaderRoute: typeof RestrictLoginSignupSignupImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/login/": { + id: "/_restrict-login-signup/login/"; + path: "/"; + fullPath: "/login/"; + preLoaderRoute: typeof authLoginPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/signup/": { + id: "/_restrict-login-signup/signup/"; + path: "/"; + fullPath: "/signup/"; + preLoaderRoute: typeof authSignUpPageRouteImport; + parentRoute: typeof RestrictLoginSignupSignupImport; + }; + "/_authenticate/organizations/none": { + id: "/_authenticate/organizations/none"; + path: "/organizations/none"; + fullPath: "/organizations/none"; + preLoaderRoute: typeof organizationNoOrgPageRouteImport; + parentRoute: typeof middlewaresAuthenticateImport; + }; + "/_restrict-login-signup/admin/signup": { + id: "/_restrict-login-signup/admin/signup"; + path: "/admin/signup"; + fullPath: "/admin/signup"; + preLoaderRoute: typeof adminSignUpPageRouteImport; + parentRoute: typeof middlewaresRestrictLoginSignupImport; + }; + "/_restrict-login-signup/login/admin": { + id: "/_restrict-login-signup/login/admin"; + path: "/admin"; + fullPath: "/login/admin"; + preLoaderRoute: typeof authAdminLoginPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/login/ldap": { + id: "/_restrict-login-signup/login/ldap"; + path: "/ldap"; + fullPath: "/login/ldap"; + preLoaderRoute: typeof authLoginLdapPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/login/select-organization": { + id: "/_restrict-login-signup/login/select-organization"; + path: "/select-organization"; + fullPath: "/login/select-organization"; + preLoaderRoute: typeof authSelectOrgPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/login/sso": { + id: "/_restrict-login-signup/login/sso"; + path: "/sso"; + fullPath: "/login/sso"; + preLoaderRoute: typeof authLoginSsoPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/signup/sso": { + id: "/_restrict-login-signup/signup/sso"; + path: "/sso"; + fullPath: "/signup/sso"; + preLoaderRoute: typeof authSignUpSsoPageRouteImport; + parentRoute: typeof RestrictLoginSignupSignupImport; + }; + "/secret-request/secret/$secretRequestId": { + id: "/secret-request/secret/$secretRequestId"; + path: "/secret-request/secret/$secretRequestId"; + fullPath: "/secret-request/secret/$secretRequestId"; + preLoaderRoute: typeof publicViewSecretRequestByIDPageRouteImport; + parentRoute: typeof rootRoute; + }; + "/shared/secret/$secretId": { + id: "/shared/secret/$secretId"; + path: "/shared/secret/$secretId"; + fullPath: "/shared/secret/$secretId"; + preLoaderRoute: typeof publicViewSharedSecretByIDPageRouteImport; + parentRoute: typeof rootRoute; + }; + "/_authenticate/_inject-org-details/_org-layout": { + id: "/_authenticate/_inject-org-details/_org-layout"; + path: ""; + fullPath: ""; + preLoaderRoute: typeof organizationLayoutImport; + parentRoute: typeof middlewaresInjectOrgDetailsImport; + }; + "/_authenticate/_inject-org-details/admin": { + id: "/_authenticate/_inject-org-details/admin"; + path: "/admin"; + fullPath: "/admin"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsAdminImport; + parentRoute: typeof middlewaresInjectOrgDetailsImport; + }; + "/_authenticate/personal-settings/_layout": { + id: "/_authenticate/personal-settings/_layout"; + path: ""; + fullPath: "/personal-settings"; + preLoaderRoute: typeof userLayoutImport; + parentRoute: typeof AuthenticatePersonalSettingsImport; + }; + "/_authenticate/personal-settings/_layout/": { + id: "/_authenticate/personal-settings/_layout/"; + path: "/"; + fullPath: "/personal-settings/"; + preLoaderRoute: typeof userPersonalSettingsPageRouteImport; + parentRoute: typeof userLayoutImport; + }; + "/_restrict-login-signup/login/provider/error": { + id: "/_restrict-login-signup/login/provider/error"; + path: "/provider/error"; + fullPath: "/login/provider/error"; + preLoaderRoute: typeof authProviderErrorPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_restrict-login-signup/login/provider/success": { + id: "/_restrict-login-signup/login/provider/success"; + path: "/provider/success"; + fullPath: "/login/provider/success"; + preLoaderRoute: typeof authProviderSuccessPageRouteImport; + parentRoute: typeof RestrictLoginSignupLoginImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations"; + path: "/integrations"; + fullPath: "/integrations"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + parentRoute: typeof organizationLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout"; + path: ""; + fullPath: "/admin"; + preLoaderRoute: typeof adminLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsAdminImport; + }; + "/_authenticate/_inject-org-details/organization/$": { + id: "/_authenticate/_inject-org-details/organization/$"; + path: "/organization/$"; + fullPath: "/organization/$"; + preLoaderRoute: typeof redirectsOrganizationRedirectImport; + parentRoute: typeof middlewaresInjectOrgDetailsImport; + }; + "/_authenticate/_inject-org-details/projects/$": { + id: "/_authenticate/_inject-org-details/projects/$"; + path: "/projects/$"; + fullPath: "/projects/$"; + preLoaderRoute: typeof redirectsProjectRedirectImport; + parentRoute: typeof middlewaresInjectOrgDetailsImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/"; + path: "/"; + fullPath: "/admin/"; + preLoaderRoute: typeof adminGeneralPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/access-management": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/access-management"; + path: "/access-management"; + fullPath: "/admin/access-management"; + preLoaderRoute: typeof adminAccessManagementPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/authentication": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/authentication"; + path: "/authentication"; + fullPath: "/admin/authentication"; + preLoaderRoute: typeof adminAuthenticationPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/caching": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/caching"; + path: "/caching"; + fullPath: "/admin/caching"; + preLoaderRoute: typeof adminCachingPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/encryption": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/encryption"; + path: "/encryption"; + fullPath: "/admin/encryption"; + preLoaderRoute: typeof adminEncryptionPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/environment": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/environment"; + path: "/environment"; + fullPath: "/admin/environment"; + preLoaderRoute: typeof adminEnvironmentPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/integrations": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/integrations"; + path: "/integrations"; + fullPath: "/admin/integrations"; + preLoaderRoute: typeof adminIntegrationsPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId"; + path: "/organizations/$orgId"; + fullPath: "/organizations/$orgId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + parentRoute: typeof organizationLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/access-management"; + preLoaderRoute: typeof organizationAccessManagementPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/audit-logs"; + preLoaderRoute: typeof organizationAuditLogsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing"; + path: "/billing"; + fullPath: "/organizations/$orgId/billing"; + preLoaderRoute: typeof organizationBillingPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking"; + path: "/networking"; + fullPath: "/organizations/$orgId/networking"; + preLoaderRoute: typeof organizationNetworkingPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects"; + path: "/projects"; + fullPath: "/organizations/$orgId/projects"; + preLoaderRoute: typeof organizationProjectsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview": { + id: "/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview"; + path: "/resources/overview"; + fullPath: "/admin/resources/overview"; + preLoaderRoute: typeof adminResourceOverviewPageRouteImport; + parentRoute: typeof adminLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$"; + path: "/$"; + fullPath: "/organizations/$orgId/$"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections"; + path: "/app-connections"; + fullPath: "/organizations/$orgId/app-connections"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing"; + path: "/secret-sharing"; + fullPath: "/organizations/$orgId/secret-sharing"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/settings"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/"; + path: "/"; + fullPath: "/organizations/$orgId/app-connections/"; + preLoaderRoute: typeof organizationAppConnectionsAppConnectionsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/"; + path: "/"; + fullPath: "/organizations/$orgId/secret-sharing/"; + preLoaderRoute: typeof organizationSecretSharingPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/"; + path: "/"; + fullPath: "/organizations/$orgId/settings/"; + preLoaderRoute: typeof organizationSettingsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/groups/$groupId"; + preLoaderRoute: typeof organizationGroupDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/identities/$identityId"; + preLoaderRoute: typeof organizationIdentityDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/members/$membershipId"; + preLoaderRoute: typeof organizationUserDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId"; + path: "/roles/$roleId"; + fullPath: "/organizations/$orgId/roles/$roleId"; + preLoaderRoute: typeof organizationRoleByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback"; + path: "/azure-app-configuration/oauth2/callback"; + fullPath: "/integrations/azure-app-configuration/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback"; + path: "/azure-key-vault/oauth2/callback"; + fullPath: "/integrations/azure-key-vault/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback"; + path: "/bitbucket/oauth2/callback"; + fullPath: "/integrations/bitbucket/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback"; + path: "/gcp-secret-manager/oauth2/callback"; + fullPath: "/integrations/gcp-secret-manager/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback"; + path: "/github/oauth2/callback"; + fullPath: "/integrations/github/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback"; + path: "/gitlab/oauth2/callback"; + fullPath: "/integrations/gitlab/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback"; + path: "/heroku/oauth2/callback"; + fullPath: "/integrations/heroku/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback"; + path: "/netlify/oauth2/callback"; + fullPath: "/integrations/netlify/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback"; + path: "/vercel/oauth2/callback"; + fullPath: "/integrations/vercel/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$"; + path: "/$"; + fullPath: "/organizations/$orgId/projects/$"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId"; + path: "/secret-manager/$projectId"; + fullPath: "/organizations/$orgId/secret-manager/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback"; + path: "/oauth/callback"; + fullPath: "/organizations/$orgId/settings/oauth/callback"; + preLoaderRoute: typeof organizationSettingsPageOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId"; + path: "/cert-manager/$projectId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId"; + path: "/kms/$projectId"; + fullPath: "/organizations/$orgId/projects/kms/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId"; + path: "/pam/$projectId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId"; + path: "/secret-management/$projectId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId"; + path: "/secret-scanning/$projectId"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId"; + path: "/ssh/$projectId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport; + parentRoute: typeof organizationProjectsPageRouteImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval"; + path: "/approval"; + fullPath: "/organizations/$orgId/secret-manager/$projectId/approval"; + preLoaderRoute: typeof secretManagerRedirectsRedirectApprovalPageImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback"; + path: "/$appConnection/oauth/callback"; + fullPath: "/organizations/$orgId/app-connections/$appConnection/oauth/callback"; + preLoaderRoute: typeof organizationAppConnectionsOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId"; + preLoaderRoute: typeof certManagerLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/kms/$projectId"; + preLoaderRoute: typeof kmsLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/pam/$projectId"; + preLoaderRoute: typeof pamLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId"; + preLoaderRoute: typeof secretManagerLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId"; + preLoaderRoute: typeof secretScanningLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout"; + path: ""; + fullPath: "/organizations/$orgId/projects/ssh/$projectId"; + preLoaderRoute: typeof sshLayoutImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting"; + path: "/alerting"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/alerting"; + preLoaderRoute: typeof certManagerAlertingPageRouteImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities"; + path: "/certificate-authorities"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities"; + preLoaderRoute: typeof certManagerCertificateAuthoritiesPageRouteImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies"; + path: "/policies"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/policies"; + preLoaderRoute: typeof certManagerPoliciesPageRouteImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/settings"; + preLoaderRoute: typeof certManagerSettingsPageRouteImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip"; + path: "/kmip"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/kmip"; + preLoaderRoute: typeof kmsKmipPageRouteImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview"; + path: "/overview"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/overview"; + preLoaderRoute: typeof kmsOverviewPageRouteImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/settings"; + preLoaderRoute: typeof kmsSettingsPageRouteImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts"; + path: "/accounts"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/accounts"; + preLoaderRoute: typeof pamPamAccountsPageRouteImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals"; + path: "/approvals"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/approvals"; + preLoaderRoute: typeof pamApprovalsPageRouteImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources"; + path: "/resources"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/resources"; + preLoaderRoute: typeof pamPamResourcesPageRouteImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/settings"; + preLoaderRoute: typeof pamSettingsPageRouteImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist"; + path: "/allowlist"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/allowlist"; + preLoaderRoute: typeof secretManagerIPAllowlistPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval"; + path: "/approval"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/approval"; + preLoaderRoute: typeof secretManagerSecretApprovalsPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview"; + path: "/overview"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/overview"; + preLoaderRoute: typeof secretManagerOverviewPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation"; + path: "/secret-rotation"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/secret-rotation"; + preLoaderRoute: typeof secretManagerSecretRotationPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/settings"; + preLoaderRoute: typeof secretManagerSettingsPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings"; + path: "/findings"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/findings"; + preLoaderRoute: typeof secretScanningSecretScanningFindingsPageRouteImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/settings"; + preLoaderRoute: typeof secretScanningSettingsPageRouteImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas"; + path: "/cas"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/cas"; + preLoaderRoute: typeof sshSshCasPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates"; + path: "/certificates"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/certificates"; + preLoaderRoute: typeof sshSshCertsPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview"; + path: "/overview"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/overview"; + preLoaderRoute: typeof sshSshHostsPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings"; + path: "/settings"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/settings"; + preLoaderRoute: typeof sshSettingsPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections"; + path: "/app-connections"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/app-connections"; + preLoaderRoute: typeof projectAppConnectionsPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates"; + path: "/certificate-templates"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations"; + path: "/integrations"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/integrations"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers"; + path: "/subscribers"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions"; + path: "/sessions"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/sessions"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections"; + path: "/app-connections"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/app-connections"; + preLoaderRoute: typeof projectAppConnectionsPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations"; + path: "/integrations"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections"; + path: "/app-connections"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/app-connections"; + preLoaderRoute: typeof projectAppConnectionsPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources"; + path: "/data-sources"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management"; + path: "/access-management"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/access-management"; + preLoaderRoute: typeof projectAccessControlPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs"; + path: "/audit-logs"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/audit-logs"; + preLoaderRoute: typeof projectAuditLogsPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates/"; + preLoaderRoute: typeof certManagerPkiTemplateListPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/integrations/"; + preLoaderRoute: typeof certManagerIntegrationsListPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/"; + preLoaderRoute: typeof certManagerPkiSubscribersPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/sessions/"; + preLoaderRoute: typeof pamPamSessionsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/"; + preLoaderRoute: typeof secretManagerIntegrationsListPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/"; + preLoaderRoute: typeof secretScanningSecretScanningDataSourcesPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId"; + path: "/ca/$caId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId"; + preLoaderRoute: typeof certManagerCertAuthDetailsByIDPageRouteImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId"; + path: "/$syncId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/integrations/$syncId"; + preLoaderRoute: typeof certManagerPkiSyncDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName"; + path: "/$subscriberName"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName"; + preLoaderRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId"; + path: "/approval-requests/$approvalRequestId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId"; + preLoaderRoute: typeof pamApprovalRequestDetailPageRouteImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId"; + path: "/$sessionId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId"; + preLoaderRoute: typeof pamPamSessionsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId"; + path: "/$integrationId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId"; + preLoaderRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth"; + path: "/select-integration-auth"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth"; + preLoaderRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug"; + path: "/secrets/$envSlug"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug"; + preLoaderRoute: typeof secretManagerSecretDashboardPageRouteImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId"; + path: "/ca/$caId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/ca/$caId"; + preLoaderRoute: typeof sshSshCaByIDPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId"; + path: "/ssh-host-groups/$sshHostGroupId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId"; + preLoaderRoute: typeof sshSshHostGroupDetailsByIDPageRouteImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId"; + path: "/pki-collections/$collectionId"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId"; + preLoaderRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/cert-manager/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerImport; + parentRoute: typeof certManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteKmsImport; + parentRoute: typeof kmsLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRoutePamImport; + parentRoute: typeof pamLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningImport; + parentRoute: typeof secretScanningLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId"; + path: "/groups/$groupId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/groups/$groupId"; + preLoaderRoute: typeof projectGroupDetailsByIDPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId"; + path: "/identities/$identityId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/identities/$identityId"; + preLoaderRoute: typeof projectIdentityDetailsByIDPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId"; + path: "/members/$membershipId"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/members/$membershipId"; + preLoaderRoute: typeof projectMemberDetailsByIDPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug"; + path: "/roles/$roleSlug"; + fullPath: "/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug"; + preLoaderRoute: typeof projectRoleDetailsBySlugPageRouteSshImport; + parentRoute: typeof sshLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize"; + path: "/aws-parameter-store/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create"; + path: "/aws-parameter-store/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create"; + preLoaderRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize"; + path: "/aws-secret-manager/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create"; + path: "/aws-secret-manager/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create"; + preLoaderRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create"; + path: "/azure-app-configuration/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create"; + preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize"; + path: "/azure-devops/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create"; + path: "/azure-devops/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create"; + preLoaderRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize"; + path: "/azure-key-vault/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create"; + path: "/azure-key-vault/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create"; + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create"; + path: "/bitbucket/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create"; + preLoaderRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize"; + path: "/checkly/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create"; + path: "/checkly/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create"; + preLoaderRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize"; + path: "/circleci/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create"; + path: "/circleci/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create"; + preLoaderRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize"; + path: "/cloud-66/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create"; + path: "/cloud-66/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create"; + preLoaderRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize"; + path: "/cloudflare-pages/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create"; + path: "/cloudflare-pages/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create"; + preLoaderRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize"; + path: "/cloudflare-workers/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create"; + path: "/cloudflare-workers/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create"; + preLoaderRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize"; + path: "/codefresh/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create"; + path: "/codefresh/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create"; + preLoaderRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize"; + path: "/databricks/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create"; + path: "/databricks/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create"; + preLoaderRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize"; + path: "/digital-ocean-app-platform/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create"; + path: "/digital-ocean-app-platform/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create"; + preLoaderRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize"; + path: "/flyio/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create"; + path: "/flyio/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create"; + preLoaderRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize"; + path: "/gcp-secret-manager/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create"; + path: "/gcp-secret-manager/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create"; + preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection"; + path: "/github/auth-mode-selection"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection"; + preLoaderRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create"; + path: "/github/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create"; + preLoaderRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize"; + path: "/gitlab/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create"; + path: "/gitlab/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create"; + preLoaderRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize"; + path: "/hashicorp-vault/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create"; + path: "/hashicorp-vault/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create"; + preLoaderRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize"; + path: "/hasura-cloud/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create"; + path: "/hasura-cloud/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create"; + preLoaderRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create"; + path: "/heroku/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create"; + preLoaderRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize"; + path: "/laravel-forge/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create"; + path: "/laravel-forge/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create"; + preLoaderRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create"; + path: "/netlify/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create"; + preLoaderRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize"; + path: "/northflank/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create"; + path: "/northflank/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create"; + preLoaderRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize"; + path: "/octopus-deploy/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create"; + path: "/octopus-deploy/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create"; + preLoaderRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize"; + path: "/qovery/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create"; + path: "/qovery/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create"; + preLoaderRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize"; + path: "/railway/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create"; + path: "/railway/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create"; + preLoaderRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize"; + path: "/render/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create"; + path: "/render/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create"; + preLoaderRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize"; + path: "/rundeck/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create"; + path: "/rundeck/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create"; + preLoaderRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize"; + path: "/supabase/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create"; + path: "/supabase/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create"; + preLoaderRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize"; + path: "/teamcity/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create"; + path: "/teamcity/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create"; + preLoaderRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize"; + path: "/terraform-cloud/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create"; + path: "/terraform-cloud/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create"; + preLoaderRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize"; + path: "/travisci/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create"; + path: "/travisci/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create"; + preLoaderRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create"; + path: "/vercel/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create"; + preLoaderRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize"; + path: "/windmill/authorize"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize"; + preLoaderRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create"; + path: "/windmill/create"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create"; + preLoaderRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId"; + path: "/$type/$dataSourceId"; + fullPath: "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId"; + preLoaderRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId"; + path: "/commits/$environment/$folderId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport; + parentRoute: typeof secretManagerLayoutImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/"; + preLoaderRoute: typeof secretManagerCommitsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback"; + path: "/azure-app-configuration/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback"; + path: "/azure-key-vault/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback"; + path: "/bitbucket/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback"; + path: "/gcp-secret-manager/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback"; + path: "/github/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsGithubOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback"; + path: "/gitlab/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback"; + path: "/heroku/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback"; + path: "/netlify/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId"; + path: "/secret-syncs/$destination/$syncId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId"; + preLoaderRoute: typeof secretManagerSecretSyncDetailsByIDPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback"; + path: "/vercel/oauth2/callback"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback"; + preLoaderRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId"; + path: "/$commitId"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId"; + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/"; + path: "/"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/"; + preLoaderRoute: typeof secretManagerCommitDetailsPageRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport; + }; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore": { + id: "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore"; + path: "/restore"; + fullPath: "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore"; + preLoaderRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteImport; + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdImport; + }; } } // Create and export the route tree interface AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren { - secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - secretManagerIntegrationsRouteGcpOauthRedirectRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - secretManagerIntegrationsRouteGithubOauthRedirectRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - secretManagerIntegrationsRouteGitlabOauthRedirectRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - secretManagerIntegrationsRouteHerokuOauthRedirectRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - secretManagerIntegrationsRouteVercelOauthRedirectRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute + secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute; + secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute: typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute; + secretManagerIntegrationsRouteBitbucketOauthRedirectRoute: typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute; + secretManagerIntegrationsRouteGcpOauthRedirectRoute: typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute; + secretManagerIntegrationsRouteGithubOauthRedirectRoute: typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute; + secretManagerIntegrationsRouteGitlabOauthRedirectRoute: typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute; + secretManagerIntegrationsRouteHerokuOauthRedirectRoute: typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute; + secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute; + secretManagerIntegrationsRouteVercelOauthRedirectRoute: typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute; } const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren = @@ -4052,104 +3940,95 @@ const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren: Authentica secretManagerIntegrationsRouteNetlifyOauthRedirectRoute: secretManagerIntegrationsRouteNetlifyOauthRedirectRoute, secretManagerIntegrationsRouteVercelOauthRedirectRoute: - secretManagerIntegrationsRouteVercelOauthRedirectRoute, - } + secretManagerIntegrationsRouteVercelOauthRedirectRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteChildren + ); -interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren { - certManagerPkiTemplateListPageRouteRoute: typeof certManagerPkiTemplateListPageRouteRoute +interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteChildren { + certManagerPkiTemplateListPageRouteRoute: typeof certManagerPkiTemplateListPageRouteRoute; } -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteChildren = { - certManagerPkiTemplateListPageRouteRoute: - certManagerPkiTemplateListPageRouteRoute, - } + certManagerPkiTemplateListPageRouteRoute: certManagerPkiTemplateListPageRouteRoute + }; -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteChildren, - ) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteChildren + ); -interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteChildren { - certManagerIntegrationsListPageRouteRoute: typeof certManagerIntegrationsListPageRouteRoute - certManagerPkiSyncDetailsByIDPageRouteRoute: typeof certManagerPkiSyncDetailsByIDPageRouteRoute +interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteChildren { + certManagerIntegrationsListPageRouteRoute: typeof certManagerIntegrationsListPageRouteRoute; + certManagerPkiSyncDetailsByIDPageRouteRoute: typeof certManagerPkiSyncDetailsByIDPageRouteRoute; } -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteChildren = { - certManagerIntegrationsListPageRouteRoute: - certManagerIntegrationsListPageRouteRoute, - certManagerPkiSyncDetailsByIDPageRouteRoute: - certManagerPkiSyncDetailsByIDPageRouteRoute, - } + certManagerIntegrationsListPageRouteRoute: certManagerIntegrationsListPageRouteRoute, + certManagerPkiSyncDetailsByIDPageRouteRoute: certManagerPkiSyncDetailsByIDPageRouteRoute + }; -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteChildren, - ) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteChildren + ); -interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren { - certManagerPkiSubscribersPageRouteRoute: typeof certManagerPkiSubscribersPageRouteRoute - certManagerPkiSubscriberDetailsByIDPageRouteRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute +interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteChildren { + certManagerPkiSubscribersPageRouteRoute: typeof certManagerPkiSubscribersPageRouteRoute; + certManagerPkiSubscriberDetailsByIDPageRouteRoute: typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute; } -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteChildren = { - certManagerPkiSubscribersPageRouteRoute: - certManagerPkiSubscribersPageRouteRoute, + certManagerPkiSubscribersPageRouteRoute: certManagerPkiSubscribersPageRouteRoute, certManagerPkiSubscriberDetailsByIDPageRouteRoute: - certManagerPkiSubscriberDetailsByIDPageRouteRoute, - } + certManagerPkiSubscriberDetailsByIDPageRouteRoute + }; -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteChildren, - ) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteChildren + ); interface certManagerLayoutRouteChildren { - certManagerAlertingPageRouteRoute: typeof certManagerAlertingPageRouteRoute - certManagerCertificateAuthoritiesPageRouteRoute: typeof certManagerCertificateAuthoritiesPageRouteRoute - certManagerPoliciesPageRouteRoute: typeof certManagerPoliciesPageRouteRoute - certManagerSettingsPageRouteRoute: typeof certManagerSettingsPageRouteRoute - projectAccessControlPageRouteCertManagerRoute: typeof projectAccessControlPageRouteCertManagerRoute - projectAppConnectionsPageRouteCertManagerRoute: typeof projectAppConnectionsPageRouteCertManagerRoute - projectAuditLogsPageRouteCertManagerRoute: typeof projectAuditLogsPageRouteCertManagerRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren - certManagerCertAuthDetailsByIDPageRouteRoute: typeof certManagerCertAuthDetailsByIDPageRouteRoute - projectGroupDetailsByIDPageRouteCertManagerRoute: typeof projectGroupDetailsByIDPageRouteCertManagerRoute - projectIdentityDetailsByIDPageRouteCertManagerRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerRoute - projectMemberDetailsByIDPageRouteCertManagerRoute: typeof projectMemberDetailsByIDPageRouteCertManagerRoute - certManagerPkiCollectionDetailsByIDPageRoutesRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - projectRoleDetailsBySlugPageRouteCertManagerRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerRoute + certManagerAlertingPageRouteRoute: typeof certManagerAlertingPageRouteRoute; + certManagerCertificateAuthoritiesPageRouteRoute: typeof certManagerCertificateAuthoritiesPageRouteRoute; + certManagerPoliciesPageRouteRoute: typeof certManagerPoliciesPageRouteRoute; + certManagerSettingsPageRouteRoute: typeof certManagerSettingsPageRouteRoute; + projectAccessControlPageRouteCertManagerRoute: typeof projectAccessControlPageRouteCertManagerRoute; + projectAppConnectionsPageRouteCertManagerRoute: typeof projectAppConnectionsPageRouteCertManagerRoute; + projectAuditLogsPageRouteCertManagerRoute: typeof projectAuditLogsPageRouteCertManagerRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteWithChildren; + certManagerCertAuthDetailsByIDPageRouteRoute: typeof certManagerCertAuthDetailsByIDPageRouteRoute; + projectGroupDetailsByIDPageRouteCertManagerRoute: typeof projectGroupDetailsByIDPageRouteCertManagerRoute; + projectIdentityDetailsByIDPageRouteCertManagerRoute: typeof projectIdentityDetailsByIDPageRouteCertManagerRoute; + projectMemberDetailsByIDPageRouteCertManagerRoute: typeof projectMemberDetailsByIDPageRouteCertManagerRoute; + certManagerPkiCollectionDetailsByIDPageRoutesRoute: typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute; + projectRoleDetailsBySlugPageRouteCertManagerRoute: typeof projectRoleDetailsBySlugPageRouteCertManagerRoute; } const certManagerLayoutRouteChildren: certManagerLayoutRouteChildren = { certManagerAlertingPageRouteRoute: certManagerAlertingPageRouteRoute, - certManagerCertificateAuthoritiesPageRouteRoute: - certManagerCertificateAuthoritiesPageRouteRoute, + certManagerCertificateAuthoritiesPageRouteRoute: certManagerCertificateAuthoritiesPageRouteRoute, certManagerPoliciesPageRouteRoute: certManagerPoliciesPageRouteRoute, certManagerSettingsPageRouteRoute: certManagerSettingsPageRouteRoute, - projectAccessControlPageRouteCertManagerRoute: - projectAccessControlPageRouteCertManagerRoute, - projectAppConnectionsPageRouteCertManagerRoute: - projectAppConnectionsPageRouteCertManagerRoute, - projectAuditLogsPageRouteCertManagerRoute: - projectAuditLogsPageRouteCertManagerRoute, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren, - certManagerCertAuthDetailsByIDPageRouteRoute: - certManagerCertAuthDetailsByIDPageRouteRoute, + projectAccessControlPageRouteCertManagerRoute: projectAccessControlPageRouteCertManagerRoute, + projectAppConnectionsPageRouteCertManagerRoute: projectAppConnectionsPageRouteCertManagerRoute, + projectAuditLogsPageRouteCertManagerRoute: projectAuditLogsPageRouteCertManagerRoute, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteWithChildren, + certManagerCertAuthDetailsByIDPageRouteRoute: certManagerCertAuthDetailsByIDPageRouteRoute, projectGroupDetailsByIDPageRouteCertManagerRoute: projectGroupDetailsByIDPageRouteCertManagerRoute, projectIdentityDetailsByIDPageRouteCertManagerRoute: @@ -4159,36 +4038,37 @@ const certManagerLayoutRouteChildren: certManagerLayoutRouteChildren = { certManagerPkiCollectionDetailsByIDPageRoutesRoute: certManagerPkiCollectionDetailsByIDPageRoutesRoute, projectRoleDetailsBySlugPageRouteCertManagerRoute: - projectRoleDetailsBySlugPageRouteCertManagerRoute, + projectRoleDetailsBySlugPageRouteCertManagerRoute +}; + +const certManagerLayoutRouteWithChildren = certManagerLayoutRoute._addFileChildren( + certManagerLayoutRouteChildren +); + +interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteChildren { + certManagerLayoutRoute: typeof certManagerLayoutRouteWithChildren; } -const certManagerLayoutRouteWithChildren = - certManagerLayoutRoute._addFileChildren(certManagerLayoutRouteChildren) - -interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteChildren { - certManagerLayoutRoute: typeof certManagerLayoutRouteWithChildren -} - -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteChildren = +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteChildren = { - certManagerLayoutRoute: certManagerLayoutRouteWithChildren, - } + certManagerLayoutRoute: certManagerLayoutRouteWithChildren + }; -const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteWithChildren = - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteChildren, - ) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteChildren + ); interface kmsLayoutRouteChildren { - kmsKmipPageRouteRoute: typeof kmsKmipPageRouteRoute - kmsOverviewPageRouteRoute: typeof kmsOverviewPageRouteRoute - kmsSettingsPageRouteRoute: typeof kmsSettingsPageRouteRoute - projectAccessControlPageRouteKmsRoute: typeof projectAccessControlPageRouteKmsRoute - projectAuditLogsPageRouteKmsRoute: typeof projectAuditLogsPageRouteKmsRoute - projectGroupDetailsByIDPageRouteKmsRoute: typeof projectGroupDetailsByIDPageRouteKmsRoute - projectIdentityDetailsByIDPageRouteKmsRoute: typeof projectIdentityDetailsByIDPageRouteKmsRoute - projectMemberDetailsByIDPageRouteKmsRoute: typeof projectMemberDetailsByIDPageRouteKmsRoute - projectRoleDetailsBySlugPageRouteKmsRoute: typeof projectRoleDetailsBySlugPageRouteKmsRoute + kmsKmipPageRouteRoute: typeof kmsKmipPageRouteRoute; + kmsOverviewPageRouteRoute: typeof kmsOverviewPageRouteRoute; + kmsSettingsPageRouteRoute: typeof kmsSettingsPageRouteRoute; + projectAccessControlPageRouteKmsRoute: typeof projectAccessControlPageRouteKmsRoute; + projectAuditLogsPageRouteKmsRoute: typeof projectAuditLogsPageRouteKmsRoute; + projectGroupDetailsByIDPageRouteKmsRoute: typeof projectGroupDetailsByIDPageRouteKmsRoute; + projectIdentityDetailsByIDPageRouteKmsRoute: typeof projectIdentityDetailsByIDPageRouteKmsRoute; + projectMemberDetailsByIDPageRouteKmsRoute: typeof projectMemberDetailsByIDPageRouteKmsRoute; + projectRoleDetailsBySlugPageRouteKmsRoute: typeof projectRoleDetailsBySlugPageRouteKmsRoute; } const kmsLayoutRouteChildren: kmsLayoutRouteChildren = { @@ -4197,63 +4077,57 @@ const kmsLayoutRouteChildren: kmsLayoutRouteChildren = { kmsSettingsPageRouteRoute: kmsSettingsPageRouteRoute, projectAccessControlPageRouteKmsRoute: projectAccessControlPageRouteKmsRoute, projectAuditLogsPageRouteKmsRoute: projectAuditLogsPageRouteKmsRoute, - projectGroupDetailsByIDPageRouteKmsRoute: - projectGroupDetailsByIDPageRouteKmsRoute, - projectIdentityDetailsByIDPageRouteKmsRoute: - projectIdentityDetailsByIDPageRouteKmsRoute, - projectMemberDetailsByIDPageRouteKmsRoute: - projectMemberDetailsByIDPageRouteKmsRoute, - projectRoleDetailsBySlugPageRouteKmsRoute: - projectRoleDetailsBySlugPageRouteKmsRoute, -} + projectGroupDetailsByIDPageRouteKmsRoute: projectGroupDetailsByIDPageRouteKmsRoute, + projectIdentityDetailsByIDPageRouteKmsRoute: projectIdentityDetailsByIDPageRouteKmsRoute, + projectMemberDetailsByIDPageRouteKmsRoute: projectMemberDetailsByIDPageRouteKmsRoute, + projectRoleDetailsBySlugPageRouteKmsRoute: projectRoleDetailsBySlugPageRouteKmsRoute +}; -const kmsLayoutRouteWithChildren = kmsLayoutRoute._addFileChildren( - kmsLayoutRouteChildren, -) +const kmsLayoutRouteWithChildren = kmsLayoutRoute._addFileChildren(kmsLayoutRouteChildren); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteChildren { - kmsLayoutRoute: typeof kmsLayoutRouteWithChildren + kmsLayoutRoute: typeof kmsLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteChildren = { - kmsLayoutRoute: kmsLayoutRouteWithChildren, - } + kmsLayoutRoute: kmsLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteChildren { - pamPamSessionsPageRouteRoute: typeof pamPamSessionsPageRouteRoute - pamPamSessionsByIDPageRouteRoute: typeof pamPamSessionsByIDPageRouteRoute + pamPamSessionsPageRouteRoute: typeof pamPamSessionsPageRouteRoute; + pamPamSessionsByIDPageRouteRoute: typeof pamPamSessionsByIDPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteChildren = { pamPamSessionsPageRouteRoute: pamPamSessionsPageRouteRoute, - pamPamSessionsByIDPageRouteRoute: pamPamSessionsByIDPageRouteRoute, - } + pamPamSessionsByIDPageRouteRoute: pamPamSessionsByIDPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteChildren + ); interface pamLayoutRouteChildren { - pamPamAccountsPageRouteRoute: typeof pamPamAccountsPageRouteRoute - pamApprovalsPageRouteRoute: typeof pamApprovalsPageRouteRoute - pamPamResourcesPageRouteRoute: typeof pamPamResourcesPageRouteRoute - pamSettingsPageRouteRoute: typeof pamSettingsPageRouteRoute - projectAccessControlPageRoutePamRoute: typeof projectAccessControlPageRoutePamRoute - projectAuditLogsPageRoutePamRoute: typeof projectAuditLogsPageRoutePamRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren - pamApprovalRequestDetailPageRouteRoute: typeof pamApprovalRequestDetailPageRouteRoute - projectGroupDetailsByIDPageRoutePamRoute: typeof projectGroupDetailsByIDPageRoutePamRoute - projectIdentityDetailsByIDPageRoutePamRoute: typeof projectIdentityDetailsByIDPageRoutePamRoute - projectMemberDetailsByIDPageRoutePamRoute: typeof projectMemberDetailsByIDPageRoutePamRoute - projectRoleDetailsBySlugPageRoutePamRoute: typeof projectRoleDetailsBySlugPageRoutePamRoute + pamPamAccountsPageRouteRoute: typeof pamPamAccountsPageRouteRoute; + pamApprovalsPageRouteRoute: typeof pamApprovalsPageRouteRoute; + pamPamResourcesPageRouteRoute: typeof pamPamResourcesPageRouteRoute; + pamSettingsPageRouteRoute: typeof pamSettingsPageRouteRoute; + projectAccessControlPageRoutePamRoute: typeof projectAccessControlPageRoutePamRoute; + projectAuditLogsPageRoutePamRoute: typeof projectAuditLogsPageRoutePamRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren; + pamApprovalRequestDetailPageRouteRoute: typeof pamApprovalRequestDetailPageRouteRoute; + projectGroupDetailsByIDPageRoutePamRoute: typeof projectGroupDetailsByIDPageRoutePamRoute; + projectIdentityDetailsByIDPageRoutePamRoute: typeof projectIdentityDetailsByIDPageRoutePamRoute; + projectMemberDetailsByIDPageRoutePamRoute: typeof projectMemberDetailsByIDPageRoutePamRoute; + projectRoleDetailsBySlugPageRoutePamRoute: typeof projectRoleDetailsBySlugPageRoutePamRoute; } const pamLayoutRouteChildren: pamLayoutRouteChildren = { @@ -4265,121 +4139,113 @@ const pamLayoutRouteChildren: pamLayoutRouteChildren = { projectAuditLogsPageRoutePamRoute: projectAuditLogsPageRoutePamRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren, - pamApprovalRequestDetailPageRouteRoute: - pamApprovalRequestDetailPageRouteRoute, - projectGroupDetailsByIDPageRoutePamRoute: - projectGroupDetailsByIDPageRoutePamRoute, - projectIdentityDetailsByIDPageRoutePamRoute: - projectIdentityDetailsByIDPageRoutePamRoute, - projectMemberDetailsByIDPageRoutePamRoute: - projectMemberDetailsByIDPageRoutePamRoute, - projectRoleDetailsBySlugPageRoutePamRoute: - projectRoleDetailsBySlugPageRoutePamRoute, -} + pamApprovalRequestDetailPageRouteRoute: pamApprovalRequestDetailPageRouteRoute, + projectGroupDetailsByIDPageRoutePamRoute: projectGroupDetailsByIDPageRoutePamRoute, + projectIdentityDetailsByIDPageRoutePamRoute: projectIdentityDetailsByIDPageRoutePamRoute, + projectMemberDetailsByIDPageRoutePamRoute: projectMemberDetailsByIDPageRoutePamRoute, + projectRoleDetailsBySlugPageRoutePamRoute: projectRoleDetailsBySlugPageRoutePamRoute +}; -const pamLayoutRouteWithChildren = pamLayoutRoute._addFileChildren( - pamLayoutRouteChildren, -) +const pamLayoutRouteWithChildren = pamLayoutRoute._addFileChildren(pamLayoutRouteChildren); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteChildren { - pamLayoutRoute: typeof pamLayoutRouteWithChildren + pamLayoutRoute: typeof pamLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteChildren = { - pamLayoutRoute: pamLayoutRouteWithChildren, - } + pamLayoutRoute: pamLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren { - secretManagerIntegrationsListPageRouteRoute: typeof secretManagerIntegrationsListPageRouteRoute - secretManagerIntegrationsDetailsByIDPageRouteRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - secretManagerIntegrationsBitbucketConfigurePageRouteRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - secretManagerIntegrationsChecklyAuthorizePageRouteRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - secretManagerIntegrationsChecklyConfigurePageRouteRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - secretManagerIntegrationsCircleCIAuthorizePageRouteRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - secretManagerIntegrationsCircleCIConfigurePageRouteRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - secretManagerIntegrationsCloud66AuthorizePageRouteRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - secretManagerIntegrationsCloud66ConfigurePageRouteRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - secretManagerIntegrationsCodefreshAuthorizePageRouteRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - secretManagerIntegrationsCodefreshConfigurePageRouteRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - secretManagerIntegrationsDatabricksAuthorizePageRouteRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - secretManagerIntegrationsDatabricksConfigurePageRouteRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - secretManagerIntegrationsFlyioAuthorizePageRouteRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - secretManagerIntegrationsFlyioConfigurePageRouteRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - secretManagerIntegrationsGithubAuthorizePageRouteRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - secretManagerIntegrationsGithubConfigurePageRouteRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - secretManagerIntegrationsGitlabAuthorizePageRouteRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - secretManagerIntegrationsGitlabConfigurePageRouteRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - secretManagerIntegrationsHerokuConfigurePageRouteRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - secretManagerIntegrationsNetlifyConfigurePageRouteRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - secretManagerIntegrationsNorthflankAuthorizePageRouteRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - secretManagerIntegrationsNorthflankConfigurePageRouteRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - secretManagerIntegrationsQoveryAuthorizePageRouteRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - secretManagerIntegrationsQoveryConfigurePageRouteRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - secretManagerIntegrationsRailwayAuthorizePageRouteRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - secretManagerIntegrationsRailwayConfigurePageRouteRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - secretManagerIntegrationsRenderAuthorizePageRouteRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - secretManagerIntegrationsRenderConfigurePageRouteRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - secretManagerIntegrationsRundeckAuthorizePageRouteRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - secretManagerIntegrationsRundeckConfigurePageRouteRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - secretManagerIntegrationsSupabaseAuthorizePageRouteRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - secretManagerIntegrationsSupabaseConfigurePageRouteRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - secretManagerIntegrationsTeamcityAuthorizePageRouteRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - secretManagerIntegrationsTeamcityConfigurePageRouteRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - secretManagerIntegrationsTravisCIAuthorizePageRouteRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - secretManagerIntegrationsTravisCIConfigurePageRouteRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - secretManagerIntegrationsVercelConfigurePageRouteRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - secretManagerIntegrationsWindmillAuthorizePageRouteRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - secretManagerIntegrationsWindmillConfigurePageRouteRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - secretManagerIntegrationsGithubOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - secretManagerSecretSyncDetailsByIDPageRouteRoute: typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - secretManagerIntegrationsVercelOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute + secretManagerIntegrationsListPageRouteRoute: typeof secretManagerIntegrationsListPageRouteRoute; + secretManagerIntegrationsDetailsByIDPageRouteRoute: typeof secretManagerIntegrationsDetailsByIDPageRouteRoute; + secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute: typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute; + secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute: typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute; + secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute: typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute; + secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute: typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute; + secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute: typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute; + secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute; + secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute; + secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute; + secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute; + secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute; + secretManagerIntegrationsBitbucketConfigurePageRouteRoute: typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute; + secretManagerIntegrationsChecklyAuthorizePageRouteRoute: typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute; + secretManagerIntegrationsChecklyConfigurePageRouteRoute: typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute; + secretManagerIntegrationsCircleCIAuthorizePageRouteRoute: typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute; + secretManagerIntegrationsCircleCIConfigurePageRouteRoute: typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute; + secretManagerIntegrationsCloud66AuthorizePageRouteRoute: typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute; + secretManagerIntegrationsCloud66ConfigurePageRouteRoute: typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute; + secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute: typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute; + secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute: typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute; + secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute: typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute; + secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute: typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute; + secretManagerIntegrationsCodefreshAuthorizePageRouteRoute: typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute; + secretManagerIntegrationsCodefreshConfigurePageRouteRoute: typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute; + secretManagerIntegrationsDatabricksAuthorizePageRouteRoute: typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute; + secretManagerIntegrationsDatabricksConfigurePageRouteRoute: typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute; + secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute; + secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute: typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute; + secretManagerIntegrationsFlyioAuthorizePageRouteRoute: typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute; + secretManagerIntegrationsFlyioConfigurePageRouteRoute: typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute; + secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute; + secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute; + secretManagerIntegrationsGithubAuthorizePageRouteRoute: typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute; + secretManagerIntegrationsGithubConfigurePageRouteRoute: typeof secretManagerIntegrationsGithubConfigurePageRouteRoute; + secretManagerIntegrationsGitlabAuthorizePageRouteRoute: typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute; + secretManagerIntegrationsGitlabConfigurePageRouteRoute: typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute; + secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute: typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute; + secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute: typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute; + secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute: typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute; + secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute: typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute; + secretManagerIntegrationsHerokuConfigurePageRouteRoute: typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute; + secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute: typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute; + secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute: typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute; + secretManagerIntegrationsNetlifyConfigurePageRouteRoute: typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute; + secretManagerIntegrationsNorthflankAuthorizePageRouteRoute: typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute; + secretManagerIntegrationsNorthflankConfigurePageRouteRoute: typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute; + secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute: typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute; + secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute: typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute; + secretManagerIntegrationsQoveryAuthorizePageRouteRoute: typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute; + secretManagerIntegrationsQoveryConfigurePageRouteRoute: typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute; + secretManagerIntegrationsRailwayAuthorizePageRouteRoute: typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute; + secretManagerIntegrationsRailwayConfigurePageRouteRoute: typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute; + secretManagerIntegrationsRenderAuthorizePageRouteRoute: typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute; + secretManagerIntegrationsRenderConfigurePageRouteRoute: typeof secretManagerIntegrationsRenderConfigurePageRouteRoute; + secretManagerIntegrationsRundeckAuthorizePageRouteRoute: typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute; + secretManagerIntegrationsRundeckConfigurePageRouteRoute: typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute; + secretManagerIntegrationsSupabaseAuthorizePageRouteRoute: typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute; + secretManagerIntegrationsSupabaseConfigurePageRouteRoute: typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute; + secretManagerIntegrationsTeamcityAuthorizePageRouteRoute: typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute; + secretManagerIntegrationsTeamcityConfigurePageRouteRoute: typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute; + secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute: typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute; + secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute: typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute; + secretManagerIntegrationsTravisCIAuthorizePageRouteRoute: typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute; + secretManagerIntegrationsTravisCIConfigurePageRouteRoute: typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute; + secretManagerIntegrationsVercelConfigurePageRouteRoute: typeof secretManagerIntegrationsVercelConfigurePageRouteRoute; + secretManagerIntegrationsWindmillAuthorizePageRouteRoute: typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute; + secretManagerIntegrationsWindmillConfigurePageRouteRoute: typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute; + secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute; + secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute; + secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute; + secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute; + secretManagerIntegrationsGithubOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute; + secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute; + secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute; + secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute; + secretManagerSecretSyncDetailsByIDPageRouteRoute: typeof secretManagerSecretSyncDetailsByIDPageRouteRoute; + secretManagerIntegrationsVercelOauthCallbackPageRouteRoute: typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren = { - secretManagerIntegrationsListPageRouteRoute: - secretManagerIntegrationsListPageRouteRoute, + secretManagerIntegrationsListPageRouteRoute: secretManagerIntegrationsListPageRouteRoute, secretManagerIntegrationsDetailsByIDPageRouteRoute: secretManagerIntegrationsDetailsByIDPageRouteRoute, secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute: @@ -4533,86 +4399,79 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManag secretManagerSecretSyncDetailsByIDPageRouteRoute: secretManagerSecretSyncDetailsByIDPageRouteRoute, secretManagerIntegrationsVercelOauthCallbackPageRouteRoute: - secretManagerIntegrationsVercelOauthCallbackPageRouteRoute, - } + secretManagerIntegrationsVercelOauthCallbackPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren { - secretManagerCommitDetailsPageRouteRoute: typeof secretManagerCommitDetailsPageRouteRoute - secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + secretManagerCommitDetailsPageRouteRoute: typeof secretManagerCommitDetailsPageRouteRoute; + secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute: typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren = { - secretManagerCommitDetailsPageRouteRoute: - secretManagerCommitDetailsPageRouteRoute, + secretManagerCommitDetailsPageRouteRoute: secretManagerCommitDetailsPageRouteRoute, secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute: - secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute, - } + secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren { - secretManagerCommitsPageRouteRoute: typeof secretManagerCommitsPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren + secretManagerCommitsPageRouteRoute: typeof secretManagerCommitsPageRouteRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren = { secretManagerCommitsPageRouteRoute: secretManagerCommitsPageRouteRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren, - } + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteChildren + ); interface secretManagerLayoutRouteChildren { - secretManagerIPAllowlistPageRouteRoute: typeof secretManagerIPAllowlistPageRouteRoute - secretManagerSecretApprovalsPageRouteRoute: typeof secretManagerSecretApprovalsPageRouteRoute - secretManagerOverviewPageRouteRoute: typeof secretManagerOverviewPageRouteRoute - secretManagerSecretRotationPageRouteRoute: typeof secretManagerSecretRotationPageRouteRoute - secretManagerSettingsPageRouteRoute: typeof secretManagerSettingsPageRouteRoute - projectAccessControlPageRouteSecretManagerRoute: typeof projectAccessControlPageRouteSecretManagerRoute - projectAppConnectionsPageRouteSecretManagerRoute: typeof projectAppConnectionsPageRouteSecretManagerRoute - projectAuditLogsPageRouteSecretManagerRoute: typeof projectAuditLogsPageRouteSecretManagerRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren - secretManagerSecretDashboardPageRouteRoute: typeof secretManagerSecretDashboardPageRouteRoute - projectGroupDetailsByIDPageRouteSecretManagerRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerRoute - projectIdentityDetailsByIDPageRouteSecretManagerRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute - projectMemberDetailsByIDPageRouteSecretManagerRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerRoute - projectRoleDetailsBySlugPageRouteSecretManagerRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren + secretManagerIPAllowlistPageRouteRoute: typeof secretManagerIPAllowlistPageRouteRoute; + secretManagerSecretApprovalsPageRouteRoute: typeof secretManagerSecretApprovalsPageRouteRoute; + secretManagerOverviewPageRouteRoute: typeof secretManagerOverviewPageRouteRoute; + secretManagerSecretRotationPageRouteRoute: typeof secretManagerSecretRotationPageRouteRoute; + secretManagerSettingsPageRouteRoute: typeof secretManagerSettingsPageRouteRoute; + projectAccessControlPageRouteSecretManagerRoute: typeof projectAccessControlPageRouteSecretManagerRoute; + projectAppConnectionsPageRouteSecretManagerRoute: typeof projectAppConnectionsPageRouteSecretManagerRoute; + projectAuditLogsPageRouteSecretManagerRoute: typeof projectAuditLogsPageRouteSecretManagerRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren; + secretManagerSecretDashboardPageRouteRoute: typeof secretManagerSecretDashboardPageRouteRoute; + projectGroupDetailsByIDPageRouteSecretManagerRoute: typeof projectGroupDetailsByIDPageRouteSecretManagerRoute; + projectIdentityDetailsByIDPageRouteSecretManagerRoute: typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute; + projectMemberDetailsByIDPageRouteSecretManagerRoute: typeof projectMemberDetailsByIDPageRouteSecretManagerRoute; + projectRoleDetailsBySlugPageRouteSecretManagerRoute: typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren; } const secretManagerLayoutRouteChildren: secretManagerLayoutRouteChildren = { - secretManagerIPAllowlistPageRouteRoute: - secretManagerIPAllowlistPageRouteRoute, - secretManagerSecretApprovalsPageRouteRoute: - secretManagerSecretApprovalsPageRouteRoute, + secretManagerIPAllowlistPageRouteRoute: secretManagerIPAllowlistPageRouteRoute, + secretManagerSecretApprovalsPageRouteRoute: secretManagerSecretApprovalsPageRouteRoute, secretManagerOverviewPageRouteRoute: secretManagerOverviewPageRouteRoute, - secretManagerSecretRotationPageRouteRoute: - secretManagerSecretRotationPageRouteRoute, + secretManagerSecretRotationPageRouteRoute: secretManagerSecretRotationPageRouteRoute, secretManagerSettingsPageRouteRoute: secretManagerSettingsPageRouteRoute, - projectAccessControlPageRouteSecretManagerRoute: - projectAccessControlPageRouteSecretManagerRoute, + projectAccessControlPageRouteSecretManagerRoute: projectAccessControlPageRouteSecretManagerRoute, projectAppConnectionsPageRouteSecretManagerRoute: projectAppConnectionsPageRouteSecretManagerRoute, - projectAuditLogsPageRouteSecretManagerRoute: - projectAuditLogsPageRouteSecretManagerRoute, + projectAuditLogsPageRouteSecretManagerRoute: projectAuditLogsPageRouteSecretManagerRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren, - secretManagerSecretDashboardPageRouteRoute: - secretManagerSecretDashboardPageRouteRoute, + secretManagerSecretDashboardPageRouteRoute: secretManagerSecretDashboardPageRouteRoute, projectGroupDetailsByIDPageRouteSecretManagerRoute: projectGroupDetailsByIDPageRouteSecretManagerRoute, projectIdentityDetailsByIDPageRouteSecretManagerRoute: @@ -4622,29 +4481,30 @@ const secretManagerLayoutRouteChildren: secretManagerLayoutRouteChildren = { projectRoleDetailsBySlugPageRouteSecretManagerRoute: projectRoleDetailsBySlugPageRouteSecretManagerRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren, -} + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren +}; -const secretManagerLayoutRouteWithChildren = - secretManagerLayoutRoute._addFileChildren(secretManagerLayoutRouteChildren) +const secretManagerLayoutRouteWithChildren = secretManagerLayoutRoute._addFileChildren( + secretManagerLayoutRouteChildren +); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteChildren { - secretManagerLayoutRoute: typeof secretManagerLayoutRouteWithChildren + secretManagerLayoutRoute: typeof secretManagerLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteChildren = { - secretManagerLayoutRoute: secretManagerLayoutRouteWithChildren, - } + secretManagerLayoutRoute: secretManagerLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren { - secretScanningSecretScanningDataSourcesPageRouteRoute: typeof secretScanningSecretScanningDataSourcesPageRouteRoute - secretScanningSecretScanningDataSourceByIdPageRouteRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute + secretScanningSecretScanningDataSourcesPageRouteRoute: typeof secretScanningSecretScanningDataSourcesPageRouteRoute; + secretScanningSecretScanningDataSourceByIdPageRouteRoute: typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren = @@ -4652,25 +4512,25 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScann secretScanningSecretScanningDataSourcesPageRouteRoute: secretScanningSecretScanningDataSourcesPageRouteRoute, secretScanningSecretScanningDataSourceByIdPageRouteRoute: - secretScanningSecretScanningDataSourceByIdPageRouteRoute, - } + secretScanningSecretScanningDataSourceByIdPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteChildren + ); interface secretScanningLayoutRouteChildren { - secretScanningSecretScanningFindingsPageRouteRoute: typeof secretScanningSecretScanningFindingsPageRouteRoute - secretScanningSettingsPageRouteRoute: typeof secretScanningSettingsPageRouteRoute - projectAccessControlPageRouteSecretScanningRoute: typeof projectAccessControlPageRouteSecretScanningRoute - projectAppConnectionsPageRouteSecretScanningRoute: typeof projectAppConnectionsPageRouteSecretScanningRoute - projectAuditLogsPageRouteSecretScanningRoute: typeof projectAuditLogsPageRouteSecretScanningRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren - projectGroupDetailsByIDPageRouteSecretScanningRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningRoute - projectIdentityDetailsByIDPageRouteSecretScanningRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute - projectMemberDetailsByIDPageRouteSecretScanningRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningRoute - projectRoleDetailsBySlugPageRouteSecretScanningRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute + secretScanningSecretScanningFindingsPageRouteRoute: typeof secretScanningSecretScanningFindingsPageRouteRoute; + secretScanningSettingsPageRouteRoute: typeof secretScanningSettingsPageRouteRoute; + projectAccessControlPageRouteSecretScanningRoute: typeof projectAccessControlPageRouteSecretScanningRoute; + projectAppConnectionsPageRouteSecretScanningRoute: typeof projectAppConnectionsPageRouteSecretScanningRoute; + projectAuditLogsPageRouteSecretScanningRoute: typeof projectAuditLogsPageRouteSecretScanningRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren; + projectGroupDetailsByIDPageRouteSecretScanningRoute: typeof projectGroupDetailsByIDPageRouteSecretScanningRoute; + projectIdentityDetailsByIDPageRouteSecretScanningRoute: typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute; + projectMemberDetailsByIDPageRouteSecretScanningRoute: typeof projectMemberDetailsByIDPageRouteSecretScanningRoute; + projectRoleDetailsBySlugPageRouteSecretScanningRoute: typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute; } const secretScanningLayoutRouteChildren: secretScanningLayoutRouteChildren = { @@ -4681,8 +4541,7 @@ const secretScanningLayoutRouteChildren: secretScanningLayoutRouteChildren = { projectAccessControlPageRouteSecretScanningRoute, projectAppConnectionsPageRouteSecretScanningRoute: projectAppConnectionsPageRouteSecretScanningRoute, - projectAuditLogsPageRouteSecretScanningRoute: - projectAuditLogsPageRouteSecretScanningRoute, + projectAuditLogsPageRouteSecretScanningRoute: projectAuditLogsPageRouteSecretScanningRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren, projectGroupDetailsByIDPageRouteSecretScanningRoute: @@ -4692,39 +4551,40 @@ const secretScanningLayoutRouteChildren: secretScanningLayoutRouteChildren = { projectMemberDetailsByIDPageRouteSecretScanningRoute: projectMemberDetailsByIDPageRouteSecretScanningRoute, projectRoleDetailsBySlugPageRouteSecretScanningRoute: - projectRoleDetailsBySlugPageRouteSecretScanningRoute, -} + projectRoleDetailsBySlugPageRouteSecretScanningRoute +}; -const secretScanningLayoutRouteWithChildren = - secretScanningLayoutRoute._addFileChildren(secretScanningLayoutRouteChildren) +const secretScanningLayoutRouteWithChildren = secretScanningLayoutRoute._addFileChildren( + secretScanningLayoutRouteChildren +); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteChildren { - secretScanningLayoutRoute: typeof secretScanningLayoutRouteWithChildren + secretScanningLayoutRoute: typeof secretScanningLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteChildren = { - secretScanningLayoutRoute: secretScanningLayoutRouteWithChildren, - } + secretScanningLayoutRoute: secretScanningLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteChildren + ); interface sshLayoutRouteChildren { - sshSshCasPageRouteRoute: typeof sshSshCasPageRouteRoute - sshSshCertsPageRouteRoute: typeof sshSshCertsPageRouteRoute - sshSshHostsPageRouteRoute: typeof sshSshHostsPageRouteRoute - sshSettingsPageRouteRoute: typeof sshSettingsPageRouteRoute - projectAccessControlPageRouteSshRoute: typeof projectAccessControlPageRouteSshRoute - projectAuditLogsPageRouteSshRoute: typeof projectAuditLogsPageRouteSshRoute - sshSshCaByIDPageRouteRoute: typeof sshSshCaByIDPageRouteRoute - sshSshHostGroupDetailsByIDPageRouteRoute: typeof sshSshHostGroupDetailsByIDPageRouteRoute - projectGroupDetailsByIDPageRouteSshRoute: typeof projectGroupDetailsByIDPageRouteSshRoute - projectIdentityDetailsByIDPageRouteSshRoute: typeof projectIdentityDetailsByIDPageRouteSshRoute - projectMemberDetailsByIDPageRouteSshRoute: typeof projectMemberDetailsByIDPageRouteSshRoute - projectRoleDetailsBySlugPageRouteSshRoute: typeof projectRoleDetailsBySlugPageRouteSshRoute + sshSshCasPageRouteRoute: typeof sshSshCasPageRouteRoute; + sshSshCertsPageRouteRoute: typeof sshSshCertsPageRouteRoute; + sshSshHostsPageRouteRoute: typeof sshSshHostsPageRouteRoute; + sshSettingsPageRouteRoute: typeof sshSettingsPageRouteRoute; + projectAccessControlPageRouteSshRoute: typeof projectAccessControlPageRouteSshRoute; + projectAuditLogsPageRouteSshRoute: typeof projectAuditLogsPageRouteSshRoute; + sshSshCaByIDPageRouteRoute: typeof sshSshCaByIDPageRouteRoute; + sshSshHostGroupDetailsByIDPageRouteRoute: typeof sshSshHostGroupDetailsByIDPageRouteRoute; + projectGroupDetailsByIDPageRouteSshRoute: typeof projectGroupDetailsByIDPageRouteSshRoute; + projectIdentityDetailsByIDPageRouteSshRoute: typeof projectIdentityDetailsByIDPageRouteSshRoute; + projectMemberDetailsByIDPageRouteSshRoute: typeof projectMemberDetailsByIDPageRouteSshRoute; + projectRoleDetailsBySlugPageRouteSshRoute: typeof projectRoleDetailsBySlugPageRouteSshRoute; } const sshLayoutRouteChildren: sshLayoutRouteChildren = { @@ -4735,72 +4595,62 @@ const sshLayoutRouteChildren: sshLayoutRouteChildren = { projectAccessControlPageRouteSshRoute: projectAccessControlPageRouteSshRoute, projectAuditLogsPageRouteSshRoute: projectAuditLogsPageRouteSshRoute, sshSshCaByIDPageRouteRoute: sshSshCaByIDPageRouteRoute, - sshSshHostGroupDetailsByIDPageRouteRoute: - sshSshHostGroupDetailsByIDPageRouteRoute, - projectGroupDetailsByIDPageRouteSshRoute: - projectGroupDetailsByIDPageRouteSshRoute, - projectIdentityDetailsByIDPageRouteSshRoute: - projectIdentityDetailsByIDPageRouteSshRoute, - projectMemberDetailsByIDPageRouteSshRoute: - projectMemberDetailsByIDPageRouteSshRoute, - projectRoleDetailsBySlugPageRouteSshRoute: - projectRoleDetailsBySlugPageRouteSshRoute, -} + sshSshHostGroupDetailsByIDPageRouteRoute: sshSshHostGroupDetailsByIDPageRouteRoute, + projectGroupDetailsByIDPageRouteSshRoute: projectGroupDetailsByIDPageRouteSshRoute, + projectIdentityDetailsByIDPageRouteSshRoute: projectIdentityDetailsByIDPageRouteSshRoute, + projectMemberDetailsByIDPageRouteSshRoute: projectMemberDetailsByIDPageRouteSshRoute, + projectRoleDetailsBySlugPageRouteSshRoute: projectRoleDetailsBySlugPageRouteSshRoute +}; -const sshLayoutRouteWithChildren = sshLayoutRoute._addFileChildren( - sshLayoutRouteChildren, -) +const sshLayoutRouteWithChildren = sshLayoutRoute._addFileChildren(sshLayoutRouteChildren); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteChildren { - sshLayoutRoute: typeof sshLayoutRouteWithChildren + sshLayoutRoute: typeof sshLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteChildren = { - sshLayoutRoute: sshLayoutRouteWithChildren, - } + sshLayoutRoute: sshLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteChildren + ); interface organizationProjectsPageRouteRouteChildren { - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren; } -const organizationProjectsPageRouteRouteChildren: organizationProjectsPageRouteRouteChildren = - { - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren, - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren, - } +const organizationProjectsPageRouteRouteChildren: organizationProjectsPageRouteRouteChildren = { + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren +}; const organizationProjectsPageRouteRouteWithChildren = - organizationProjectsPageRouteRoute._addFileChildren( - organizationProjectsPageRouteRouteChildren, - ) + organizationProjectsPageRouteRoute._addFileChildren(organizationProjectsPageRouteRouteChildren); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteChildren { - organizationAppConnectionsAppConnectionsPageRouteRoute: typeof organizationAppConnectionsAppConnectionsPageRouteRoute - organizationAppConnectionsOauthCallbackPageRouteRoute: typeof organizationAppConnectionsOauthCallbackPageRouteRoute + organizationAppConnectionsAppConnectionsPageRouteRoute: typeof organizationAppConnectionsAppConnectionsPageRouteRoute; + organizationAppConnectionsOauthCallbackPageRouteRoute: typeof organizationAppConnectionsOauthCallbackPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteChildren = @@ -4808,87 +4658,83 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute organizationAppConnectionsAppConnectionsPageRouteRoute: organizationAppConnectionsAppConnectionsPageRouteRoute, organizationAppConnectionsOauthCallbackPageRouteRoute: - organizationAppConnectionsOauthCallbackPageRouteRoute, - } + organizationAppConnectionsOauthCallbackPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteChildren { - organizationSecretSharingPageRouteRoute: typeof organizationSecretSharingPageRouteRoute + organizationSecretSharingPageRouteRoute: typeof organizationSecretSharingPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteChildren = { - organizationSecretSharingPageRouteRoute: - organizationSecretSharingPageRouteRoute, - } + organizationSecretSharingPageRouteRoute: organizationSecretSharingPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteChildren { - organizationSettingsPageRouteRoute: typeof organizationSettingsPageRouteRoute - organizationSettingsPageOauthCallbackPageRouteRoute: typeof organizationSettingsPageOauthCallbackPageRouteRoute + organizationSettingsPageRouteRoute: typeof organizationSettingsPageRouteRoute; + organizationSettingsPageOauthCallbackPageRouteRoute: typeof organizationSettingsPageOauthCallbackPageRouteRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteChildren = { organizationSettingsPageRouteRoute: organizationSettingsPageRouteRoute, organizationSettingsPageOauthCallbackPageRouteRoute: - organizationSettingsPageOauthCallbackPageRouteRoute, - } + organizationSettingsPageOauthCallbackPageRouteRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteChildren { - secretManagerRedirectsRedirectApprovalPageRoute: typeof secretManagerRedirectsRedirectApprovalPageRoute + secretManagerRedirectsRedirectApprovalPageRoute: typeof secretManagerRedirectsRedirectApprovalPageRoute; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteChildren = { - secretManagerRedirectsRedirectApprovalPageRoute: - secretManagerRedirectsRedirectApprovalPageRoute, - } + secretManagerRedirectsRedirectApprovalPageRoute: secretManagerRedirectsRedirectApprovalPageRoute + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteChildren + ); interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren { - organizationAccessManagementPageRouteRoute: typeof organizationAccessManagementPageRouteRoute - organizationAuditLogsPageRouteRoute: typeof organizationAuditLogsPageRouteRoute - organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute - organizationNetworkingPageRouteRoute: typeof organizationNetworkingPageRouteRoute - organizationProjectsPageRouteRoute: typeof organizationProjectsPageRouteRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren - organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute - organizationIdentityDetailsByIDPageRouteRoute: typeof organizationIdentityDetailsByIDPageRouteRoute - organizationUserDetailsByIDPageRouteRoute: typeof organizationUserDetailsByIDPageRouteRoute - organizationRoleByIDPageRouteRoute: typeof organizationRoleByIDPageRouteRoute - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren + organizationAccessManagementPageRouteRoute: typeof organizationAccessManagementPageRouteRoute; + organizationAuditLogsPageRouteRoute: typeof organizationAuditLogsPageRouteRoute; + organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute; + organizationNetworkingPageRouteRoute: typeof organizationNetworkingPageRouteRoute; + organizationProjectsPageRouteRoute: typeof organizationProjectsPageRouteRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren; + organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute; + organizationIdentityDetailsByIDPageRouteRoute: typeof organizationIdentityDetailsByIDPageRouteRoute; + organizationUserDetailsByIDPageRouteRoute: typeof organizationUserDetailsByIDPageRouteRoute; + organizationRoleByIDPageRouteRoute: typeof organizationRoleByIDPageRouteRoute; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren; } const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren = { - organizationAccessManagementPageRouteRoute: - organizationAccessManagementPageRouteRoute, + organizationAccessManagementPageRouteRoute: organizationAccessManagementPageRouteRoute, organizationAuditLogsPageRouteRoute: organizationAuditLogsPageRouteRoute, organizationBillingPageRouteRoute: organizationBillingPageRouteRoute, organizationNetworkingPageRouteRoute: organizationNetworkingPageRouteRoute, - organizationProjectsPageRouteRoute: - organizationProjectsPageRouteRouteWithChildren, + organizationProjectsPageRouteRoute: organizationProjectsPageRouteRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRoute: @@ -4897,46 +4743,44 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren: Auth AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren, - organizationGroupDetailsByIDPageRouteRoute: - organizationGroupDetailsByIDPageRouteRoute, - organizationIdentityDetailsByIDPageRouteRoute: - organizationIdentityDetailsByIDPageRouteRoute, - organizationUserDetailsByIDPageRouteRoute: - organizationUserDetailsByIDPageRouteRoute, + organizationGroupDetailsByIDPageRouteRoute: organizationGroupDetailsByIDPageRouteRoute, + organizationIdentityDetailsByIDPageRouteRoute: organizationIdentityDetailsByIDPageRouteRoute, + organizationUserDetailsByIDPageRouteRoute: organizationUserDetailsByIDPageRouteRoute, organizationRoleByIDPageRouteRoute: organizationRoleByIDPageRouteRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren, - } + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren + }; const AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren = AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute._addFileChildren( - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren, - ) + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteChildren + ); interface organizationLayoutRouteChildren { - AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren; + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren; } const organizationLayoutRouteChildren: organizationLayoutRouteChildren = { AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRoute: AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRoute: - AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren, -} + AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren +}; -const organizationLayoutRouteWithChildren = - organizationLayoutRoute._addFileChildren(organizationLayoutRouteChildren) +const organizationLayoutRouteWithChildren = organizationLayoutRoute._addFileChildren( + organizationLayoutRouteChildren +); interface adminLayoutRouteChildren { - adminGeneralPageRouteRoute: typeof adminGeneralPageRouteRoute - adminAccessManagementPageRouteRoute: typeof adminAccessManagementPageRouteRoute - adminAuthenticationPageRouteRoute: typeof adminAuthenticationPageRouteRoute - adminCachingPageRouteRoute: typeof adminCachingPageRouteRoute - adminEncryptionPageRouteRoute: typeof adminEncryptionPageRouteRoute - adminEnvironmentPageRouteRoute: typeof adminEnvironmentPageRouteRoute - adminIntegrationsPageRouteRoute: typeof adminIntegrationsPageRouteRoute - adminResourceOverviewPageRouteRoute: typeof adminResourceOverviewPageRouteRoute + adminGeneralPageRouteRoute: typeof adminGeneralPageRouteRoute; + adminAccessManagementPageRouteRoute: typeof adminAccessManagementPageRouteRoute; + adminAuthenticationPageRouteRoute: typeof adminAuthenticationPageRouteRoute; + adminCachingPageRouteRoute: typeof adminCachingPageRouteRoute; + adminEncryptionPageRouteRoute: typeof adminEncryptionPageRouteRoute; + adminEnvironmentPageRouteRoute: typeof adminEnvironmentPageRouteRoute; + adminIntegrationsPageRouteRoute: typeof adminIntegrationsPageRouteRoute; + adminResourceOverviewPageRouteRoute: typeof adminResourceOverviewPageRouteRoute; } const adminLayoutRouteChildren: adminLayoutRouteChildren = { @@ -4947,1639 +4791,1617 @@ const adminLayoutRouteChildren: adminLayoutRouteChildren = { adminEncryptionPageRouteRoute: adminEncryptionPageRouteRoute, adminEnvironmentPageRouteRoute: adminEnvironmentPageRouteRoute, adminIntegrationsPageRouteRoute: adminIntegrationsPageRouteRoute, - adminResourceOverviewPageRouteRoute: adminResourceOverviewPageRouteRoute, -} + adminResourceOverviewPageRouteRoute: adminResourceOverviewPageRouteRoute +}; -const adminLayoutRouteWithChildren = adminLayoutRoute._addFileChildren( - adminLayoutRouteChildren, -) +const adminLayoutRouteWithChildren = adminLayoutRoute._addFileChildren(adminLayoutRouteChildren); interface AuthenticateInjectOrgDetailsAdminRouteChildren { - adminLayoutRoute: typeof adminLayoutRouteWithChildren + adminLayoutRoute: typeof adminLayoutRouteWithChildren; } const AuthenticateInjectOrgDetailsAdminRouteChildren: AuthenticateInjectOrgDetailsAdminRouteChildren = { - adminLayoutRoute: adminLayoutRouteWithChildren, - } + adminLayoutRoute: adminLayoutRouteWithChildren + }; const AuthenticateInjectOrgDetailsAdminRouteWithChildren = AuthenticateInjectOrgDetailsAdminRoute._addFileChildren( - AuthenticateInjectOrgDetailsAdminRouteChildren, - ) + AuthenticateInjectOrgDetailsAdminRouteChildren + ); interface middlewaresInjectOrgDetailsRouteChildren { - organizationLayoutRoute: typeof organizationLayoutRouteWithChildren - AuthenticateInjectOrgDetailsAdminRoute: typeof AuthenticateInjectOrgDetailsAdminRouteWithChildren - redirectsOrganizationRedirectRoute: typeof redirectsOrganizationRedirectRoute - redirectsProjectRedirectRoute: typeof redirectsProjectRedirectRoute + organizationLayoutRoute: typeof organizationLayoutRouteWithChildren; + AuthenticateInjectOrgDetailsAdminRoute: typeof AuthenticateInjectOrgDetailsAdminRouteWithChildren; + redirectsOrganizationRedirectRoute: typeof redirectsOrganizationRedirectRoute; + redirectsProjectRedirectRoute: typeof redirectsProjectRedirectRoute; } -const middlewaresInjectOrgDetailsRouteChildren: middlewaresInjectOrgDetailsRouteChildren = - { - organizationLayoutRoute: organizationLayoutRouteWithChildren, - AuthenticateInjectOrgDetailsAdminRoute: - AuthenticateInjectOrgDetailsAdminRouteWithChildren, - redirectsOrganizationRedirectRoute: redirectsOrganizationRedirectRoute, - redirectsProjectRedirectRoute: redirectsProjectRedirectRoute, - } +const middlewaresInjectOrgDetailsRouteChildren: middlewaresInjectOrgDetailsRouteChildren = { + organizationLayoutRoute: organizationLayoutRouteWithChildren, + AuthenticateInjectOrgDetailsAdminRoute: AuthenticateInjectOrgDetailsAdminRouteWithChildren, + redirectsOrganizationRedirectRoute: redirectsOrganizationRedirectRoute, + redirectsProjectRedirectRoute: redirectsProjectRedirectRoute +}; const middlewaresInjectOrgDetailsRouteWithChildren = - middlewaresInjectOrgDetailsRoute._addFileChildren( - middlewaresInjectOrgDetailsRouteChildren, - ) + middlewaresInjectOrgDetailsRoute._addFileChildren(middlewaresInjectOrgDetailsRouteChildren); interface userLayoutRouteChildren { - userPersonalSettingsPageRouteRoute: typeof userPersonalSettingsPageRouteRoute + userPersonalSettingsPageRouteRoute: typeof userPersonalSettingsPageRouteRoute; } const userLayoutRouteChildren: userLayoutRouteChildren = { - userPersonalSettingsPageRouteRoute: userPersonalSettingsPageRouteRoute, -} + userPersonalSettingsPageRouteRoute: userPersonalSettingsPageRouteRoute +}; -const userLayoutRouteWithChildren = userLayoutRoute._addFileChildren( - userLayoutRouteChildren, -) +const userLayoutRouteWithChildren = userLayoutRoute._addFileChildren(userLayoutRouteChildren); interface AuthenticatePersonalSettingsRouteChildren { - userLayoutRoute: typeof userLayoutRouteWithChildren + userLayoutRoute: typeof userLayoutRouteWithChildren; } -const AuthenticatePersonalSettingsRouteChildren: AuthenticatePersonalSettingsRouteChildren = - { - userLayoutRoute: userLayoutRouteWithChildren, - } +const AuthenticatePersonalSettingsRouteChildren: AuthenticatePersonalSettingsRouteChildren = { + userLayoutRoute: userLayoutRouteWithChildren +}; const AuthenticatePersonalSettingsRouteWithChildren = - AuthenticatePersonalSettingsRoute._addFileChildren( - AuthenticatePersonalSettingsRouteChildren, - ) + AuthenticatePersonalSettingsRoute._addFileChildren(AuthenticatePersonalSettingsRouteChildren); interface middlewaresAuthenticateRouteChildren { - authPasswordSetupPageRouteRoute: typeof authPasswordSetupPageRouteRoute - middlewaresInjectOrgDetailsRoute: typeof middlewaresInjectOrgDetailsRouteWithChildren - AuthenticatePersonalSettingsRoute: typeof AuthenticatePersonalSettingsRouteWithChildren - organizationNoOrgPageRouteRoute: typeof organizationNoOrgPageRouteRoute + authPasswordSetupPageRouteRoute: typeof authPasswordSetupPageRouteRoute; + middlewaresInjectOrgDetailsRoute: typeof middlewaresInjectOrgDetailsRouteWithChildren; + AuthenticatePersonalSettingsRoute: typeof AuthenticatePersonalSettingsRouteWithChildren; + organizationNoOrgPageRouteRoute: typeof organizationNoOrgPageRouteRoute; } -const middlewaresAuthenticateRouteChildren: middlewaresAuthenticateRouteChildren = - { - authPasswordSetupPageRouteRoute: authPasswordSetupPageRouteRoute, - middlewaresInjectOrgDetailsRoute: - middlewaresInjectOrgDetailsRouteWithChildren, - AuthenticatePersonalSettingsRoute: - AuthenticatePersonalSettingsRouteWithChildren, - organizationNoOrgPageRouteRoute: organizationNoOrgPageRouteRoute, - } +const middlewaresAuthenticateRouteChildren: middlewaresAuthenticateRouteChildren = { + authPasswordSetupPageRouteRoute: authPasswordSetupPageRouteRoute, + middlewaresInjectOrgDetailsRoute: middlewaresInjectOrgDetailsRouteWithChildren, + AuthenticatePersonalSettingsRoute: AuthenticatePersonalSettingsRouteWithChildren, + organizationNoOrgPageRouteRoute: organizationNoOrgPageRouteRoute +}; -const middlewaresAuthenticateRouteWithChildren = - middlewaresAuthenticateRoute._addFileChildren( - middlewaresAuthenticateRouteChildren, - ) +const middlewaresAuthenticateRouteWithChildren = middlewaresAuthenticateRoute._addFileChildren( + middlewaresAuthenticateRouteChildren +); interface RestrictLoginSignupLoginRouteChildren { - authLoginPageRouteRoute: typeof authLoginPageRouteRoute - authAdminLoginPageRouteRoute: typeof authAdminLoginPageRouteRoute - authLoginLdapPageRouteRoute: typeof authLoginLdapPageRouteRoute - authSelectOrgPageRouteRoute: typeof authSelectOrgPageRouteRoute - authLoginSsoPageRouteRoute: typeof authLoginSsoPageRouteRoute - authProviderErrorPageRouteRoute: typeof authProviderErrorPageRouteRoute - authProviderSuccessPageRouteRoute: typeof authProviderSuccessPageRouteRoute + authLoginPageRouteRoute: typeof authLoginPageRouteRoute; + authAdminLoginPageRouteRoute: typeof authAdminLoginPageRouteRoute; + authLoginLdapPageRouteRoute: typeof authLoginLdapPageRouteRoute; + authSelectOrgPageRouteRoute: typeof authSelectOrgPageRouteRoute; + authLoginSsoPageRouteRoute: typeof authLoginSsoPageRouteRoute; + authProviderErrorPageRouteRoute: typeof authProviderErrorPageRouteRoute; + authProviderSuccessPageRouteRoute: typeof authProviderSuccessPageRouteRoute; } -const RestrictLoginSignupLoginRouteChildren: RestrictLoginSignupLoginRouteChildren = - { - authLoginPageRouteRoute: authLoginPageRouteRoute, - authAdminLoginPageRouteRoute: authAdminLoginPageRouteRoute, - authLoginLdapPageRouteRoute: authLoginLdapPageRouteRoute, - authSelectOrgPageRouteRoute: authSelectOrgPageRouteRoute, - authLoginSsoPageRouteRoute: authLoginSsoPageRouteRoute, - authProviderErrorPageRouteRoute: authProviderErrorPageRouteRoute, - authProviderSuccessPageRouteRoute: authProviderSuccessPageRouteRoute, - } +const RestrictLoginSignupLoginRouteChildren: RestrictLoginSignupLoginRouteChildren = { + authLoginPageRouteRoute: authLoginPageRouteRoute, + authAdminLoginPageRouteRoute: authAdminLoginPageRouteRoute, + authLoginLdapPageRouteRoute: authLoginLdapPageRouteRoute, + authSelectOrgPageRouteRoute: authSelectOrgPageRouteRoute, + authLoginSsoPageRouteRoute: authLoginSsoPageRouteRoute, + authProviderErrorPageRouteRoute: authProviderErrorPageRouteRoute, + authProviderSuccessPageRouteRoute: authProviderSuccessPageRouteRoute +}; -const RestrictLoginSignupLoginRouteWithChildren = - RestrictLoginSignupLoginRoute._addFileChildren( - RestrictLoginSignupLoginRouteChildren, - ) +const RestrictLoginSignupLoginRouteWithChildren = RestrictLoginSignupLoginRoute._addFileChildren( + RestrictLoginSignupLoginRouteChildren +); interface RestrictLoginSignupSignupRouteChildren { - authSignUpPageRouteRoute: typeof authSignUpPageRouteRoute - authSignUpSsoPageRouteRoute: typeof authSignUpSsoPageRouteRoute + authSignUpPageRouteRoute: typeof authSignUpPageRouteRoute; + authSignUpSsoPageRouteRoute: typeof authSignUpSsoPageRouteRoute; } -const RestrictLoginSignupSignupRouteChildren: RestrictLoginSignupSignupRouteChildren = - { - authSignUpPageRouteRoute: authSignUpPageRouteRoute, - authSignUpSsoPageRouteRoute: authSignUpSsoPageRouteRoute, - } +const RestrictLoginSignupSignupRouteChildren: RestrictLoginSignupSignupRouteChildren = { + authSignUpPageRouteRoute: authSignUpPageRouteRoute, + authSignUpSsoPageRouteRoute: authSignUpSsoPageRouteRoute +}; -const RestrictLoginSignupSignupRouteWithChildren = - RestrictLoginSignupSignupRoute._addFileChildren( - RestrictLoginSignupSignupRouteChildren, - ) +const RestrictLoginSignupSignupRouteWithChildren = RestrictLoginSignupSignupRoute._addFileChildren( + RestrictLoginSignupSignupRouteChildren +); interface middlewaresRestrictLoginSignupRouteChildren { - authEmailNotVerifiedPageRouteRoute: typeof authEmailNotVerifiedPageRouteRoute - authPasswordResetPageRouteRoute: typeof authPasswordResetPageRouteRoute - authRequestNewInvitePageRouteRoute: typeof authRequestNewInvitePageRouteRoute - authSignUpInvitePageRouteRoute: typeof authSignUpInvitePageRouteRoute - authVerifyEmailPageRouteRoute: typeof authVerifyEmailPageRouteRoute - RestrictLoginSignupLoginRoute: typeof RestrictLoginSignupLoginRouteWithChildren - RestrictLoginSignupSignupRoute: typeof RestrictLoginSignupSignupRouteWithChildren - adminSignUpPageRouteRoute: typeof adminSignUpPageRouteRoute + authEmailNotVerifiedPageRouteRoute: typeof authEmailNotVerifiedPageRouteRoute; + authPasswordResetPageRouteRoute: typeof authPasswordResetPageRouteRoute; + authRequestNewInvitePageRouteRoute: typeof authRequestNewInvitePageRouteRoute; + authSignUpInvitePageRouteRoute: typeof authSignUpInvitePageRouteRoute; + authVerifyEmailPageRouteRoute: typeof authVerifyEmailPageRouteRoute; + RestrictLoginSignupLoginRoute: typeof RestrictLoginSignupLoginRouteWithChildren; + RestrictLoginSignupSignupRoute: typeof RestrictLoginSignupSignupRouteWithChildren; + adminSignUpPageRouteRoute: typeof adminSignUpPageRouteRoute; } -const middlewaresRestrictLoginSignupRouteChildren: middlewaresRestrictLoginSignupRouteChildren = - { - authEmailNotVerifiedPageRouteRoute: authEmailNotVerifiedPageRouteRoute, - authPasswordResetPageRouteRoute: authPasswordResetPageRouteRoute, - authRequestNewInvitePageRouteRoute: authRequestNewInvitePageRouteRoute, - authSignUpInvitePageRouteRoute: authSignUpInvitePageRouteRoute, - authVerifyEmailPageRouteRoute: authVerifyEmailPageRouteRoute, - RestrictLoginSignupLoginRoute: RestrictLoginSignupLoginRouteWithChildren, - RestrictLoginSignupSignupRoute: RestrictLoginSignupSignupRouteWithChildren, - adminSignUpPageRouteRoute: adminSignUpPageRouteRoute, - } +const middlewaresRestrictLoginSignupRouteChildren: middlewaresRestrictLoginSignupRouteChildren = { + authEmailNotVerifiedPageRouteRoute: authEmailNotVerifiedPageRouteRoute, + authPasswordResetPageRouteRoute: authPasswordResetPageRouteRoute, + authRequestNewInvitePageRouteRoute: authRequestNewInvitePageRouteRoute, + authSignUpInvitePageRouteRoute: authSignUpInvitePageRouteRoute, + authVerifyEmailPageRouteRoute: authVerifyEmailPageRouteRoute, + RestrictLoginSignupLoginRoute: RestrictLoginSignupLoginRouteWithChildren, + RestrictLoginSignupSignupRoute: RestrictLoginSignupSignupRouteWithChildren, + adminSignUpPageRouteRoute: adminSignUpPageRouteRoute +}; const middlewaresRestrictLoginSignupRouteWithChildren = - middlewaresRestrictLoginSignupRoute._addFileChildren( - middlewaresRestrictLoginSignupRouteChildren, - ) + middlewaresRestrictLoginSignupRoute._addFileChildren(middlewaresRestrictLoginSignupRouteChildren); export interface FileRoutesByFullPath { - '/': typeof indexRoute - '/cli-redirect': typeof authCliRedirectPageRouteRoute - '/share-secret': typeof publicShareSecretPageRouteRoute - '/upgrade-path': typeof publicUpgradePathPageRouteRoute - '': typeof organizationLayoutRouteWithChildren - '/password-setup': typeof authPasswordSetupPageRouteRoute - '/email-not-verified': typeof authEmailNotVerifiedPageRouteRoute - '/password-reset': typeof authPasswordResetPageRouteRoute - '/requestnewinvite': typeof authRequestNewInvitePageRouteRoute - '/signupinvite': typeof authSignUpInvitePageRouteRoute - '/verify-email': typeof authVerifyEmailPageRouteRoute - '/personal-settings': typeof userLayoutRouteWithChildren - '/login': typeof RestrictLoginSignupLoginRouteWithChildren - '/signup': typeof RestrictLoginSignupSignupRouteWithChildren - '/login/': typeof authLoginPageRouteRoute - '/signup/': typeof authSignUpPageRouteRoute - '/organizations/none': typeof organizationNoOrgPageRouteRoute - '/admin/signup': typeof adminSignUpPageRouteRoute - '/login/admin': typeof authAdminLoginPageRouteRoute - '/login/ldap': typeof authLoginLdapPageRouteRoute - '/login/select-organization': typeof authSelectOrgPageRouteRoute - '/login/sso': typeof authLoginSsoPageRouteRoute - '/signup/sso': typeof authSignUpSsoPageRouteRoute - '/secret-request/secret/$secretRequestId': typeof publicViewSecretRequestByIDPageRouteRoute - '/shared/secret/$secretId': typeof publicViewSharedSecretByIDPageRouteRoute - '/admin': typeof adminLayoutRouteWithChildren - '/personal-settings/': typeof userPersonalSettingsPageRouteRoute - '/login/provider/error': typeof authProviderErrorPageRouteRoute - '/login/provider/success': typeof authProviderSuccessPageRouteRoute - '/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren - '/organization/$': typeof redirectsOrganizationRedirectRoute - '/projects/$': typeof redirectsProjectRedirectRoute - '/admin/': typeof adminGeneralPageRouteRoute - '/admin/access-management': typeof adminAccessManagementPageRouteRoute - '/admin/authentication': typeof adminAuthenticationPageRouteRoute - '/admin/caching': typeof adminCachingPageRouteRoute - '/admin/encryption': typeof adminEncryptionPageRouteRoute - '/admin/environment': typeof adminEnvironmentPageRouteRoute - '/admin/integrations': typeof adminIntegrationsPageRouteRoute - '/organizations/$orgId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren - '/organizations/$orgId/access-management': typeof organizationAccessManagementPageRouteRoute - '/organizations/$orgId/audit-logs': typeof organizationAuditLogsPageRouteRoute - '/organizations/$orgId/billing': typeof organizationBillingPageRouteRoute - '/organizations/$orgId/networking': typeof organizationNetworkingPageRouteRoute - '/organizations/$orgId/projects': typeof organizationProjectsPageRouteRouteWithChildren - '/admin/resources/overview': typeof adminResourceOverviewPageRouteRoute - '/organizations/$orgId/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute - '/organizations/$orgId/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren - '/organizations/$orgId/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren - '/organizations/$orgId/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren - '/organizations/$orgId/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/organizations/$orgId/secret-sharing/': typeof organizationSecretSharingPageRouteRoute - '/organizations/$orgId/settings/': typeof organizationSettingsPageRouteRoute - '/organizations/$orgId/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute - '/organizations/$orgId/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute - '/organizations/$orgId/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute - '/organizations/$orgId/roles/$roleId': typeof organizationRoleByIDPageRouteRoute - '/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/organizations/$orgId/projects/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute - '/organizations/$orgId/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren - '/organizations/$orgId/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId': typeof certManagerLayoutRouteWithChildren - '/organizations/$orgId/projects/kms/$projectId': typeof kmsLayoutRouteWithChildren - '/organizations/$orgId/projects/pam/$projectId': typeof pamLayoutRouteWithChildren - '/organizations/$orgId/projects/secret-management/$projectId': typeof secretManagerLayoutRouteWithChildren - '/organizations/$orgId/projects/secret-scanning/$projectId': typeof secretScanningLayoutRouteWithChildren - '/organizations/$orgId/projects/ssh/$projectId': typeof sshLayoutRouteWithChildren - '/organizations/$orgId/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute - '/organizations/$orgId/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/alerting': typeof certManagerAlertingPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/policies': typeof certManagerPoliciesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/settings': typeof certManagerSettingsPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/accounts': typeof pamPamAccountsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/approvals': typeof pamApprovalsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/resources': typeof pamPamResourcesPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/settings': typeof pamSettingsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/overview': typeof secretManagerOverviewPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/settings': typeof secretManagerSettingsPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/settings': typeof secretScanningSettingsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/cas': typeof sshSshCasPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/certificates': typeof sshSshCertsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/overview': typeof sshSshHostsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/settings': typeof sshSettingsPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/access-management': typeof projectAccessControlPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/app-connections': typeof projectAppConnectionsPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/audit-logs': typeof projectAuditLogsPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren - '/organizations/$orgId/projects/cert-management/$projectId/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteWithChildren - '/organizations/$orgId/projects/cert-management/$projectId/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren - '/organizations/$orgId/projects/kms/$projectId/access-management': typeof projectAccessControlPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/audit-logs': typeof projectAuditLogsPageRouteKmsRoute - '/organizations/$orgId/projects/pam/$projectId/access-management': typeof projectAccessControlPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/audit-logs': typeof projectAuditLogsPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/sessions': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren - '/organizations/$orgId/projects/secret-management/$projectId/access-management': typeof projectAccessControlPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/app-connections': typeof projectAppConnectionsPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/audit-logs': typeof projectAuditLogsPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren - '/organizations/$orgId/projects/secret-scanning/$projectId/access-management': typeof projectAccessControlPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/app-connections': typeof projectAppConnectionsPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs': typeof projectAuditLogsPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren - '/organizations/$orgId/projects/ssh/$projectId/access-management': typeof projectAccessControlPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/audit-logs': typeof projectAuditLogsPageRouteSshRoute - '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/integrations/': typeof certManagerIntegrationsListPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/sessions/': typeof pamPamSessionsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/': typeof secretManagerIntegrationsListPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/ca/$caId': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/integrations/$syncId': typeof certManagerPkiSyncDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId': typeof pamApprovalRequestDetailPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId': typeof pamPamSessionsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/organizations/$orgId/projects/cert-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute - '/organizations/$orgId/projects/kms/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute - '/organizations/$orgId/projects/pam/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRoutePamRoute - '/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute - '/organizations/$orgId/projects/ssh/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + "/": typeof indexRoute; + "/cli-redirect": typeof authCliRedirectPageRouteRoute; + "/share-secret": typeof publicShareSecretPageRouteRoute; + "/upgrade-path": typeof publicUpgradePathPageRouteRoute; + "": typeof organizationLayoutRouteWithChildren; + "/password-setup": typeof authPasswordSetupPageRouteRoute; + "/email-not-verified": typeof authEmailNotVerifiedPageRouteRoute; + "/password-reset": typeof authPasswordResetPageRouteRoute; + "/requestnewinvite": typeof authRequestNewInvitePageRouteRoute; + "/signupinvite": typeof authSignUpInvitePageRouteRoute; + "/verify-email": typeof authVerifyEmailPageRouteRoute; + "/personal-settings": typeof userLayoutRouteWithChildren; + "/login": typeof RestrictLoginSignupLoginRouteWithChildren; + "/signup": typeof RestrictLoginSignupSignupRouteWithChildren; + "/login/": typeof authLoginPageRouteRoute; + "/signup/": typeof authSignUpPageRouteRoute; + "/organizations/none": typeof organizationNoOrgPageRouteRoute; + "/admin/signup": typeof adminSignUpPageRouteRoute; + "/login/admin": typeof authAdminLoginPageRouteRoute; + "/login/ldap": typeof authLoginLdapPageRouteRoute; + "/login/select-organization": typeof authSelectOrgPageRouteRoute; + "/login/sso": typeof authLoginSsoPageRouteRoute; + "/signup/sso": typeof authSignUpSsoPageRouteRoute; + "/secret-request/secret/$secretRequestId": typeof publicViewSecretRequestByIDPageRouteRoute; + "/shared/secret/$secretId": typeof publicViewSharedSecretByIDPageRouteRoute; + "/admin": typeof adminLayoutRouteWithChildren; + "/personal-settings/": typeof userPersonalSettingsPageRouteRoute; + "/login/provider/error": typeof authProviderErrorPageRouteRoute; + "/login/provider/success": typeof authProviderSuccessPageRouteRoute; + "/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren; + "/organization/$": typeof redirectsOrganizationRedirectRoute; + "/projects/$": typeof redirectsProjectRedirectRoute; + "/admin/": typeof adminGeneralPageRouteRoute; + "/admin/access-management": typeof adminAccessManagementPageRouteRoute; + "/admin/authentication": typeof adminAuthenticationPageRouteRoute; + "/admin/caching": typeof adminCachingPageRouteRoute; + "/admin/encryption": typeof adminEncryptionPageRouteRoute; + "/admin/environment": typeof adminEnvironmentPageRouteRoute; + "/admin/integrations": typeof adminIntegrationsPageRouteRoute; + "/organizations/$orgId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren; + "/organizations/$orgId/access-management": typeof organizationAccessManagementPageRouteRoute; + "/organizations/$orgId/audit-logs": typeof organizationAuditLogsPageRouteRoute; + "/organizations/$orgId/billing": typeof organizationBillingPageRouteRoute; + "/organizations/$orgId/networking": typeof organizationNetworkingPageRouteRoute; + "/organizations/$orgId/projects": typeof organizationProjectsPageRouteRouteWithChildren; + "/admin/resources/overview": typeof adminResourceOverviewPageRouteRoute; + "/organizations/$orgId/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute; + "/organizations/$orgId/app-connections": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren; + "/organizations/$orgId/secret-sharing": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren; + "/organizations/$orgId/settings": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren; + "/organizations/$orgId/app-connections/": typeof organizationAppConnectionsAppConnectionsPageRouteRoute; + "/organizations/$orgId/secret-sharing/": typeof organizationSecretSharingPageRouteRoute; + "/organizations/$orgId/settings/": typeof organizationSettingsPageRouteRoute; + "/organizations/$orgId/groups/$groupId": typeof organizationGroupDetailsByIDPageRouteRoute; + "/organizations/$orgId/identities/$identityId": typeof organizationIdentityDetailsByIDPageRouteRoute; + "/organizations/$orgId/members/$membershipId": typeof organizationUserDetailsByIDPageRouteRoute; + "/organizations/$orgId/roles/$roleId": typeof organizationRoleByIDPageRouteRoute; + "/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute; + "/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute; + "/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute; + "/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute; + "/integrations/github/oauth2/callback": typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute; + "/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute; + "/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute; + "/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute; + "/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute; + "/organizations/$orgId/projects/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute; + "/organizations/$orgId/secret-manager/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren; + "/organizations/$orgId/settings/oauth/callback": typeof organizationSettingsPageOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId": typeof certManagerLayoutRouteWithChildren; + "/organizations/$orgId/projects/kms/$projectId": typeof kmsLayoutRouteWithChildren; + "/organizations/$orgId/projects/pam/$projectId": typeof pamLayoutRouteWithChildren; + "/organizations/$orgId/projects/secret-management/$projectId": typeof secretManagerLayoutRouteWithChildren; + "/organizations/$orgId/projects/secret-scanning/$projectId": typeof secretScanningLayoutRouteWithChildren; + "/organizations/$orgId/projects/ssh/$projectId": typeof sshLayoutRouteWithChildren; + "/organizations/$orgId/secret-manager/$projectId/approval": typeof secretManagerRedirectsRedirectApprovalPageRoute; + "/organizations/$orgId/app-connections/$appConnection/oauth/callback": typeof organizationAppConnectionsOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/alerting": typeof certManagerAlertingPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities": typeof certManagerCertificateAuthoritiesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/policies": typeof certManagerPoliciesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/settings": typeof certManagerSettingsPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/kmip": typeof kmsKmipPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/overview": typeof kmsOverviewPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/settings": typeof kmsSettingsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/accounts": typeof pamPamAccountsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/approvals": typeof pamApprovalsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/resources": typeof pamPamResourcesPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/settings": typeof pamSettingsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/allowlist": typeof secretManagerIPAllowlistPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/approval": typeof secretManagerSecretApprovalsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/overview": typeof secretManagerOverviewPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/secret-rotation": typeof secretManagerSecretRotationPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/settings": typeof secretManagerSettingsPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/findings": typeof secretScanningSecretScanningFindingsPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/settings": typeof secretScanningSettingsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/cas": typeof sshSshCasPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/certificates": typeof sshSshCertsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/overview": typeof sshSshHostsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/settings": typeof sshSettingsPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/access-management": typeof projectAccessControlPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/app-connections": typeof projectAppConnectionsPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/audit-logs": typeof projectAuditLogsPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren; + "/organizations/$orgId/projects/cert-manager/$projectId/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteWithChildren; + "/organizations/$orgId/projects/cert-manager/$projectId/subscribers": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteWithChildren; + "/organizations/$orgId/projects/kms/$projectId/access-management": typeof projectAccessControlPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/audit-logs": typeof projectAuditLogsPageRouteKmsRoute; + "/organizations/$orgId/projects/pam/$projectId/access-management": typeof projectAccessControlPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/audit-logs": typeof projectAuditLogsPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/sessions": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren; + "/organizations/$orgId/projects/secret-management/$projectId/access-management": typeof projectAccessControlPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/app-connections": typeof projectAppConnectionsPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/audit-logs": typeof projectAuditLogsPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren; + "/organizations/$orgId/projects/secret-scanning/$projectId/access-management": typeof projectAccessControlPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/app-connections": typeof projectAppConnectionsPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs": typeof projectAuditLogsPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren; + "/organizations/$orgId/projects/ssh/$projectId/access-management": typeof projectAccessControlPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/audit-logs": typeof projectAuditLogsPageRouteSshRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates/": typeof certManagerPkiTemplateListPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/integrations/": typeof certManagerIntegrationsListPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/": typeof certManagerPkiSubscribersPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/sessions/": typeof pamPamSessionsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/": typeof secretManagerIntegrationsListPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/": typeof secretScanningSecretScanningDataSourcesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId": typeof certManagerCertAuthDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/integrations/$syncId": typeof certManagerPkiSyncDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName": typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId": typeof pamApprovalRequestDetailPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId": typeof pamPamSessionsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId": typeof secretManagerIntegrationsDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth": typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug": typeof secretManagerSecretDashboardPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/ca/$caId": typeof sshSshCaByIDPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId": typeof sshSshHostGroupDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId": typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteCertManagerRoute; + "/organizations/$orgId/projects/kms/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteKmsRoute; + "/organizations/$orgId/projects/pam/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRoutePamRoute; + "/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/ssh/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSshRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize": typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create": typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize": typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create": typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create": typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize": typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create": typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize": typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create": typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create": typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize": typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create": typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize": typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create": typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize": typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create": typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize": typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create": typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize": typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create": typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize": typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create": typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize": typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create": typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize": typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create": typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize": typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create": typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize": typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create": typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection": typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create": typeof secretManagerIntegrationsGithubConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize": typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create": typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize": typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create": typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize": typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create": typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create": typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize": typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create": typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create": typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize": typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create": typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize": typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create": typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize": typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create": typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize": typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create": typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize": typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create": typeof secretManagerIntegrationsRenderConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize": typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create": typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize": typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create": typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize": typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create": typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize": typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create": typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize": typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create": typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create": typeof secretManagerIntegrationsVercelConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize": typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create": typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId": typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/": typeof secretManagerCommitsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback": typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId": typeof secretManagerSecretSyncDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/": typeof secretManagerCommitDetailsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore": typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute; } export interface FileRoutesByTo { - '/': typeof indexRoute - '/cli-redirect': typeof authCliRedirectPageRouteRoute - '/share-secret': typeof publicShareSecretPageRouteRoute - '/upgrade-path': typeof publicUpgradePathPageRouteRoute - '': typeof organizationLayoutRouteWithChildren - '/password-setup': typeof authPasswordSetupPageRouteRoute - '/email-not-verified': typeof authEmailNotVerifiedPageRouteRoute - '/password-reset': typeof authPasswordResetPageRouteRoute - '/requestnewinvite': typeof authRequestNewInvitePageRouteRoute - '/signupinvite': typeof authSignUpInvitePageRouteRoute - '/verify-email': typeof authVerifyEmailPageRouteRoute - '/personal-settings': typeof userPersonalSettingsPageRouteRoute - '/login': typeof authLoginPageRouteRoute - '/signup': typeof authSignUpPageRouteRoute - '/organizations/none': typeof organizationNoOrgPageRouteRoute - '/admin/signup': typeof adminSignUpPageRouteRoute - '/login/admin': typeof authAdminLoginPageRouteRoute - '/login/ldap': typeof authLoginLdapPageRouteRoute - '/login/select-organization': typeof authSelectOrgPageRouteRoute - '/login/sso': typeof authLoginSsoPageRouteRoute - '/signup/sso': typeof authSignUpSsoPageRouteRoute - '/secret-request/secret/$secretRequestId': typeof publicViewSecretRequestByIDPageRouteRoute - '/shared/secret/$secretId': typeof publicViewSharedSecretByIDPageRouteRoute - '/admin': typeof adminGeneralPageRouteRoute - '/login/provider/error': typeof authProviderErrorPageRouteRoute - '/login/provider/success': typeof authProviderSuccessPageRouteRoute - '/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren - '/organization/$': typeof redirectsOrganizationRedirectRoute - '/projects/$': typeof redirectsProjectRedirectRoute - '/admin/access-management': typeof adminAccessManagementPageRouteRoute - '/admin/authentication': typeof adminAuthenticationPageRouteRoute - '/admin/caching': typeof adminCachingPageRouteRoute - '/admin/encryption': typeof adminEncryptionPageRouteRoute - '/admin/environment': typeof adminEnvironmentPageRouteRoute - '/admin/integrations': typeof adminIntegrationsPageRouteRoute - '/organizations/$orgId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren - '/organizations/$orgId/access-management': typeof organizationAccessManagementPageRouteRoute - '/organizations/$orgId/audit-logs': typeof organizationAuditLogsPageRouteRoute - '/organizations/$orgId/billing': typeof organizationBillingPageRouteRoute - '/organizations/$orgId/networking': typeof organizationNetworkingPageRouteRoute - '/organizations/$orgId/projects': typeof organizationProjectsPageRouteRouteWithChildren - '/admin/resources/overview': typeof adminResourceOverviewPageRouteRoute - '/organizations/$orgId/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute - '/organizations/$orgId/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/organizations/$orgId/secret-sharing': typeof organizationSecretSharingPageRouteRoute - '/organizations/$orgId/settings': typeof organizationSettingsPageRouteRoute - '/organizations/$orgId/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute - '/organizations/$orgId/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute - '/organizations/$orgId/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute - '/organizations/$orgId/roles/$roleId': typeof organizationRoleByIDPageRouteRoute - '/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/organizations/$orgId/projects/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute - '/organizations/$orgId/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren - '/organizations/$orgId/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId': typeof certManagerLayoutRouteWithChildren - '/organizations/$orgId/projects/kms/$projectId': typeof kmsLayoutRouteWithChildren - '/organizations/$orgId/projects/pam/$projectId': typeof pamLayoutRouteWithChildren - '/organizations/$orgId/projects/secret-management/$projectId': typeof secretManagerLayoutRouteWithChildren - '/organizations/$orgId/projects/secret-scanning/$projectId': typeof secretScanningLayoutRouteWithChildren - '/organizations/$orgId/projects/ssh/$projectId': typeof sshLayoutRouteWithChildren - '/organizations/$orgId/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute - '/organizations/$orgId/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/alerting': typeof certManagerAlertingPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/policies': typeof certManagerPoliciesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/settings': typeof certManagerSettingsPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/kmip': typeof kmsKmipPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/overview': typeof kmsOverviewPageRouteRoute - '/organizations/$orgId/projects/kms/$projectId/settings': typeof kmsSettingsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/accounts': typeof pamPamAccountsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/approvals': typeof pamApprovalsPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/resources': typeof pamPamResourcesPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/settings': typeof pamSettingsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/overview': typeof secretManagerOverviewPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/settings': typeof secretManagerSettingsPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/settings': typeof secretScanningSettingsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/cas': typeof sshSshCasPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/certificates': typeof sshSshCertsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/overview': typeof sshSshHostsPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/settings': typeof sshSettingsPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/access-management': typeof projectAccessControlPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/app-connections': typeof projectAppConnectionsPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/audit-logs': typeof projectAuditLogsPageRouteCertManagerRoute - '/organizations/$orgId/projects/kms/$projectId/access-management': typeof projectAccessControlPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/audit-logs': typeof projectAuditLogsPageRouteKmsRoute - '/organizations/$orgId/projects/pam/$projectId/access-management': typeof projectAccessControlPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/audit-logs': typeof projectAuditLogsPageRoutePamRoute - '/organizations/$orgId/projects/secret-management/$projectId/access-management': typeof projectAccessControlPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/app-connections': typeof projectAppConnectionsPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/audit-logs': typeof projectAuditLogsPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/access-management': typeof projectAccessControlPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/app-connections': typeof projectAppConnectionsPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs': typeof projectAuditLogsPageRouteSecretScanningRoute - '/organizations/$orgId/projects/ssh/$projectId/access-management': typeof projectAccessControlPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/audit-logs': typeof projectAuditLogsPageRouteSshRoute - '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates': typeof certManagerPkiTemplateListPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/integrations': typeof certManagerIntegrationsListPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/subscribers': typeof certManagerPkiSubscribersPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/sessions': typeof pamPamSessionsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations': typeof secretManagerIntegrationsListPageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/ca/$caId': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/integrations/$syncId': typeof certManagerPkiSyncDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId': typeof pamApprovalRequestDetailPageRouteRoute - '/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId': typeof pamPamSessionsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/cert-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute - '/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/organizations/$orgId/projects/cert-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute - '/organizations/$orgId/projects/kms/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute - '/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute - '/organizations/$orgId/projects/pam/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRoutePamRoute - '/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRoutePamRoute - '/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute - '/organizations/$orgId/projects/ssh/$projectId/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute - '/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId': typeof secretManagerCommitsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId': typeof secretManagerCommitDetailsPageRouteRoute - '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + "/": typeof indexRoute; + "/cli-redirect": typeof authCliRedirectPageRouteRoute; + "/share-secret": typeof publicShareSecretPageRouteRoute; + "/upgrade-path": typeof publicUpgradePathPageRouteRoute; + "": typeof organizationLayoutRouteWithChildren; + "/password-setup": typeof authPasswordSetupPageRouteRoute; + "/email-not-verified": typeof authEmailNotVerifiedPageRouteRoute; + "/password-reset": typeof authPasswordResetPageRouteRoute; + "/requestnewinvite": typeof authRequestNewInvitePageRouteRoute; + "/signupinvite": typeof authSignUpInvitePageRouteRoute; + "/verify-email": typeof authVerifyEmailPageRouteRoute; + "/personal-settings": typeof userPersonalSettingsPageRouteRoute; + "/login": typeof authLoginPageRouteRoute; + "/signup": typeof authSignUpPageRouteRoute; + "/organizations/none": typeof organizationNoOrgPageRouteRoute; + "/admin/signup": typeof adminSignUpPageRouteRoute; + "/login/admin": typeof authAdminLoginPageRouteRoute; + "/login/ldap": typeof authLoginLdapPageRouteRoute; + "/login/select-organization": typeof authSelectOrgPageRouteRoute; + "/login/sso": typeof authLoginSsoPageRouteRoute; + "/signup/sso": typeof authSignUpSsoPageRouteRoute; + "/secret-request/secret/$secretRequestId": typeof publicViewSecretRequestByIDPageRouteRoute; + "/shared/secret/$secretId": typeof publicViewSharedSecretByIDPageRouteRoute; + "/admin": typeof adminGeneralPageRouteRoute; + "/login/provider/error": typeof authProviderErrorPageRouteRoute; + "/login/provider/success": typeof authProviderSuccessPageRouteRoute; + "/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren; + "/organization/$": typeof redirectsOrganizationRedirectRoute; + "/projects/$": typeof redirectsProjectRedirectRoute; + "/admin/access-management": typeof adminAccessManagementPageRouteRoute; + "/admin/authentication": typeof adminAuthenticationPageRouteRoute; + "/admin/caching": typeof adminCachingPageRouteRoute; + "/admin/encryption": typeof adminEncryptionPageRouteRoute; + "/admin/environment": typeof adminEnvironmentPageRouteRoute; + "/admin/integrations": typeof adminIntegrationsPageRouteRoute; + "/organizations/$orgId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren; + "/organizations/$orgId/access-management": typeof organizationAccessManagementPageRouteRoute; + "/organizations/$orgId/audit-logs": typeof organizationAuditLogsPageRouteRoute; + "/organizations/$orgId/billing": typeof organizationBillingPageRouteRoute; + "/organizations/$orgId/networking": typeof organizationNetworkingPageRouteRoute; + "/organizations/$orgId/projects": typeof organizationProjectsPageRouteRouteWithChildren; + "/admin/resources/overview": typeof adminResourceOverviewPageRouteRoute; + "/organizations/$orgId/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute; + "/organizations/$orgId/app-connections": typeof organizationAppConnectionsAppConnectionsPageRouteRoute; + "/organizations/$orgId/secret-sharing": typeof organizationSecretSharingPageRouteRoute; + "/organizations/$orgId/settings": typeof organizationSettingsPageRouteRoute; + "/organizations/$orgId/groups/$groupId": typeof organizationGroupDetailsByIDPageRouteRoute; + "/organizations/$orgId/identities/$identityId": typeof organizationIdentityDetailsByIDPageRouteRoute; + "/organizations/$orgId/members/$membershipId": typeof organizationUserDetailsByIDPageRouteRoute; + "/organizations/$orgId/roles/$roleId": typeof organizationRoleByIDPageRouteRoute; + "/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute; + "/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute; + "/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute; + "/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute; + "/integrations/github/oauth2/callback": typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute; + "/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute; + "/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute; + "/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute; + "/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute; + "/organizations/$orgId/projects/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute; + "/organizations/$orgId/secret-manager/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren; + "/organizations/$orgId/settings/oauth/callback": typeof organizationSettingsPageOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId": typeof certManagerLayoutRouteWithChildren; + "/organizations/$orgId/projects/kms/$projectId": typeof kmsLayoutRouteWithChildren; + "/organizations/$orgId/projects/pam/$projectId": typeof pamLayoutRouteWithChildren; + "/organizations/$orgId/projects/secret-management/$projectId": typeof secretManagerLayoutRouteWithChildren; + "/organizations/$orgId/projects/secret-scanning/$projectId": typeof secretScanningLayoutRouteWithChildren; + "/organizations/$orgId/projects/ssh/$projectId": typeof sshLayoutRouteWithChildren; + "/organizations/$orgId/secret-manager/$projectId/approval": typeof secretManagerRedirectsRedirectApprovalPageRoute; + "/organizations/$orgId/app-connections/$appConnection/oauth/callback": typeof organizationAppConnectionsOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/alerting": typeof certManagerAlertingPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities": typeof certManagerCertificateAuthoritiesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/policies": typeof certManagerPoliciesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/settings": typeof certManagerSettingsPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/kmip": typeof kmsKmipPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/overview": typeof kmsOverviewPageRouteRoute; + "/organizations/$orgId/projects/kms/$projectId/settings": typeof kmsSettingsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/accounts": typeof pamPamAccountsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/approvals": typeof pamApprovalsPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/resources": typeof pamPamResourcesPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/settings": typeof pamSettingsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/allowlist": typeof secretManagerIPAllowlistPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/approval": typeof secretManagerSecretApprovalsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/overview": typeof secretManagerOverviewPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/secret-rotation": typeof secretManagerSecretRotationPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/settings": typeof secretManagerSettingsPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/findings": typeof secretScanningSecretScanningFindingsPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/settings": typeof secretScanningSettingsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/cas": typeof sshSshCasPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/certificates": typeof sshSshCertsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/overview": typeof sshSshHostsPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/settings": typeof sshSettingsPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/access-management": typeof projectAccessControlPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/app-connections": typeof projectAppConnectionsPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/audit-logs": typeof projectAuditLogsPageRouteCertManagerRoute; + "/organizations/$orgId/projects/kms/$projectId/access-management": typeof projectAccessControlPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/audit-logs": typeof projectAuditLogsPageRouteKmsRoute; + "/organizations/$orgId/projects/pam/$projectId/access-management": typeof projectAccessControlPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/audit-logs": typeof projectAuditLogsPageRoutePamRoute; + "/organizations/$orgId/projects/secret-management/$projectId/access-management": typeof projectAccessControlPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/app-connections": typeof projectAppConnectionsPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/audit-logs": typeof projectAuditLogsPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/access-management": typeof projectAccessControlPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/app-connections": typeof projectAppConnectionsPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs": typeof projectAuditLogsPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/ssh/$projectId/access-management": typeof projectAccessControlPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/audit-logs": typeof projectAuditLogsPageRouteSshRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates": typeof certManagerPkiTemplateListPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/integrations": typeof certManagerIntegrationsListPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/subscribers": typeof certManagerPkiSubscribersPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/sessions": typeof pamPamSessionsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations": typeof secretManagerIntegrationsListPageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources": typeof secretScanningSecretScanningDataSourcesPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId": typeof certManagerCertAuthDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/integrations/$syncId": typeof certManagerPkiSyncDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName": typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId": typeof pamApprovalRequestDetailPageRouteRoute; + "/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId": typeof pamPamSessionsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId": typeof secretManagerIntegrationsDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth": typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug": typeof secretManagerSecretDashboardPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/ca/$caId": typeof sshSshCaByIDPageRouteRoute; + "/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId": typeof sshSshHostGroupDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteCertManagerRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId": typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute; + "/organizations/$orgId/projects/cert-manager/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteCertManagerRoute; + "/organizations/$orgId/projects/kms/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteKmsRoute; + "/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteKmsRoute; + "/organizations/$orgId/projects/pam/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRoutePamRoute; + "/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRoutePamRoute; + "/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute; + "/organizations/$orgId/projects/ssh/$projectId/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSshRoute; + "/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSshRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize": typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create": typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize": typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create": typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create": typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize": typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create": typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize": typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create": typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create": typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize": typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create": typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize": typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create": typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize": typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create": typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize": typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create": typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize": typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create": typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize": typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create": typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize": typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create": typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize": typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create": typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize": typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create": typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize": typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create": typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection": typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create": typeof secretManagerIntegrationsGithubConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize": typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create": typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize": typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create": typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize": typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create": typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create": typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize": typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create": typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create": typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize": typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create": typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize": typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create": typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize": typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create": typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize": typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create": typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize": typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create": typeof secretManagerIntegrationsRenderConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize": typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create": typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize": typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create": typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize": typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create": typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize": typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create": typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize": typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create": typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create": typeof secretManagerIntegrationsVercelConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize": typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create": typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute; + "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId": typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId": typeof secretManagerCommitsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback": typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId": typeof secretManagerSecretSyncDetailsByIDPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId": typeof secretManagerCommitDetailsPageRouteRoute; + "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore": typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute; } export interface FileRoutesById { - __root__: typeof rootRoute - '/': typeof indexRoute - '/cli-redirect': typeof authCliRedirectPageRouteRoute - '/share-secret': typeof publicShareSecretPageRouteRoute - '/upgrade-path': typeof publicUpgradePathPageRouteRoute - '/_authenticate': typeof middlewaresAuthenticateRouteWithChildren - '/_restrict-login-signup': typeof middlewaresRestrictLoginSignupRouteWithChildren - '/_authenticate/password-setup': typeof authPasswordSetupPageRouteRoute - '/_restrict-login-signup/email-not-verified': typeof authEmailNotVerifiedPageRouteRoute - '/_restrict-login-signup/password-reset': typeof authPasswordResetPageRouteRoute - '/_restrict-login-signup/requestnewinvite': typeof authRequestNewInvitePageRouteRoute - '/_restrict-login-signup/signupinvite': typeof authSignUpInvitePageRouteRoute - '/_restrict-login-signup/verify-email': typeof authVerifyEmailPageRouteRoute - '/_authenticate/_inject-org-details': typeof middlewaresInjectOrgDetailsRouteWithChildren - '/_authenticate/personal-settings': typeof AuthenticatePersonalSettingsRouteWithChildren - '/_restrict-login-signup/login': typeof RestrictLoginSignupLoginRouteWithChildren - '/_restrict-login-signup/signup': typeof RestrictLoginSignupSignupRouteWithChildren - '/_restrict-login-signup/login/': typeof authLoginPageRouteRoute - '/_restrict-login-signup/signup/': typeof authSignUpPageRouteRoute - '/_authenticate/organizations/none': typeof organizationNoOrgPageRouteRoute - '/_restrict-login-signup/admin/signup': typeof adminSignUpPageRouteRoute - '/_restrict-login-signup/login/admin': typeof authAdminLoginPageRouteRoute - '/_restrict-login-signup/login/ldap': typeof authLoginLdapPageRouteRoute - '/_restrict-login-signup/login/select-organization': typeof authSelectOrgPageRouteRoute - '/_restrict-login-signup/login/sso': typeof authLoginSsoPageRouteRoute - '/_restrict-login-signup/signup/sso': typeof authSignUpSsoPageRouteRoute - '/secret-request/secret/$secretRequestId': typeof publicViewSecretRequestByIDPageRouteRoute - '/shared/secret/$secretId': typeof publicViewSharedSecretByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout': typeof organizationLayoutRouteWithChildren - '/_authenticate/_inject-org-details/admin': typeof AuthenticateInjectOrgDetailsAdminRouteWithChildren - '/_authenticate/personal-settings/_layout': typeof userLayoutRouteWithChildren - '/_authenticate/personal-settings/_layout/': typeof userPersonalSettingsPageRouteRoute - '/_restrict-login-signup/login/provider/error': typeof authProviderErrorPageRouteRoute - '/_restrict-login-signup/login/provider/success': typeof authProviderSuccessPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren - '/_authenticate/_inject-org-details/admin/_admin-layout': typeof adminLayoutRouteWithChildren - '/_authenticate/_inject-org-details/organization/$': typeof redirectsOrganizationRedirectRoute - '/_authenticate/_inject-org-details/projects/$': typeof redirectsProjectRedirectRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/': typeof adminGeneralPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/access-management': typeof adminAccessManagementPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/authentication': typeof adminAuthenticationPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/caching': typeof adminCachingPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/encryption': typeof adminEncryptionPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/environment': typeof adminEnvironmentPageRouteRoute - '/_authenticate/_inject-org-details/admin/_admin-layout/integrations': typeof adminIntegrationsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management': typeof organizationAccessManagementPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs': typeof organizationAuditLogsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing': typeof organizationBillingPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking': typeof organizationNetworkingPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects': typeof organizationProjectsPageRouteRouteWithChildren - '/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview': typeof adminResourceOverviewPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/': typeof organizationSecretSharingPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/': typeof organizationSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId': typeof organizationRoleByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback': typeof organizationSettingsPageOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval': typeof secretManagerRedirectsRedirectApprovalPageRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback': typeof organizationAppConnectionsOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout': typeof certManagerLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout': typeof kmsLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout': typeof pamLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout': typeof secretManagerLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout': typeof secretScanningLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout': typeof sshLayoutRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting': typeof certManagerAlertingPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities': typeof certManagerCertificateAuthoritiesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies': typeof certManagerPoliciesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings': typeof certManagerSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip': typeof kmsKmipPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview': typeof kmsOverviewPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings': typeof kmsSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts': typeof pamPamAccountsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals': typeof pamApprovalsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources': typeof pamPamResourcesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings': typeof pamSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist': typeof secretManagerIPAllowlistPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval': typeof secretManagerSecretApprovalsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview': typeof secretManagerOverviewPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation': typeof secretManagerSecretRotationPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings': typeof secretManagerSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings': typeof secretScanningSecretScanningFindingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings': typeof secretScanningSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas': typeof sshSshCasPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates': typeof sshSshCertsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview': typeof sshSshHostsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings': typeof sshSettingsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management': typeof projectAccessControlPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections': typeof projectAppConnectionsPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs': typeof projectAuditLogsPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutIntegrationsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagementProjectIdCertManagerLayoutSubscribersRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management': typeof projectAccessControlPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs': typeof projectAuditLogsPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management': typeof projectAccessControlPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs': typeof projectAuditLogsPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management': typeof projectAccessControlPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections': typeof projectAppConnectionsPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs': typeof projectAuditLogsPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management': typeof projectAccessControlPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections': typeof projectAppConnectionsPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs': typeof projectAuditLogsPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management': typeof projectAccessControlPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs': typeof projectAuditLogsPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/': typeof certManagerPkiTemplateListPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/': typeof certManagerIntegrationsListPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/': typeof certManagerPkiSubscribersPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/': typeof pamPamSessionsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/': typeof secretManagerIntegrationsListPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/': typeof secretScanningSecretScanningDataSourcesPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId': typeof certManagerCertAuthDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId': typeof certManagerPkiSyncDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName': typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId': typeof pamApprovalRequestDetailPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId': typeof pamPamSessionsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId': typeof secretManagerIntegrationsDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth': typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug': typeof secretManagerSecretDashboardPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId': typeof sshSshCaByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId': typeof sshSshHostGroupDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId': typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteCertManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteKmsRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRoutePamRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId': typeof projectGroupDetailsByIDPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId': typeof projectIdentityDetailsByIDPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId': typeof projectMemberDetailsByIDPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug': typeof projectRoleDetailsBySlugPageRouteSshRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize': typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create': typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize': typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create': typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create': typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize': typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create': typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize': typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create': typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create': typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize': typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create': typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize': typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create': typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize': typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create': typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize': typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create': typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize': typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create': typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize': typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create': typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize': typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create': typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize': typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create': typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize': typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create': typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize': typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create': typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection': typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create': typeof secretManagerIntegrationsGithubConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize': typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create': typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize': typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create': typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize': typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create': typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create': typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize': typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create': typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create': typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize': typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create': typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize': typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create': typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize': typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create': typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize': typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create': typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize': typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create': typeof secretManagerIntegrationsRenderConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize': typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create': typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize': typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create': typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize': typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create': typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize': typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create': typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize': typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create': typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create': typeof secretManagerIntegrationsVercelConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize': typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create': typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId': typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/': typeof secretManagerCommitsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback': typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback': typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback': typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback': typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback': typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback': typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback': typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback': typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId': typeof secretManagerSecretSyncDetailsByIDPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback': typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/': typeof secretManagerCommitDetailsPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore': typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute + __root__: typeof rootRoute; + "/": typeof indexRoute; + "/cli-redirect": typeof authCliRedirectPageRouteRoute; + "/share-secret": typeof publicShareSecretPageRouteRoute; + "/upgrade-path": typeof publicUpgradePathPageRouteRoute; + "/_authenticate": typeof middlewaresAuthenticateRouteWithChildren; + "/_restrict-login-signup": typeof middlewaresRestrictLoginSignupRouteWithChildren; + "/_authenticate/password-setup": typeof authPasswordSetupPageRouteRoute; + "/_restrict-login-signup/email-not-verified": typeof authEmailNotVerifiedPageRouteRoute; + "/_restrict-login-signup/password-reset": typeof authPasswordResetPageRouteRoute; + "/_restrict-login-signup/requestnewinvite": typeof authRequestNewInvitePageRouteRoute; + "/_restrict-login-signup/signupinvite": typeof authSignUpInvitePageRouteRoute; + "/_restrict-login-signup/verify-email": typeof authVerifyEmailPageRouteRoute; + "/_authenticate/_inject-org-details": typeof middlewaresInjectOrgDetailsRouteWithChildren; + "/_authenticate/personal-settings": typeof AuthenticatePersonalSettingsRouteWithChildren; + "/_restrict-login-signup/login": typeof RestrictLoginSignupLoginRouteWithChildren; + "/_restrict-login-signup/signup": typeof RestrictLoginSignupSignupRouteWithChildren; + "/_restrict-login-signup/login/": typeof authLoginPageRouteRoute; + "/_restrict-login-signup/signup/": typeof authSignUpPageRouteRoute; + "/_authenticate/organizations/none": typeof organizationNoOrgPageRouteRoute; + "/_restrict-login-signup/admin/signup": typeof adminSignUpPageRouteRoute; + "/_restrict-login-signup/login/admin": typeof authAdminLoginPageRouteRoute; + "/_restrict-login-signup/login/ldap": typeof authLoginLdapPageRouteRoute; + "/_restrict-login-signup/login/select-organization": typeof authSelectOrgPageRouteRoute; + "/_restrict-login-signup/login/sso": typeof authLoginSsoPageRouteRoute; + "/_restrict-login-signup/signup/sso": typeof authSignUpSsoPageRouteRoute; + "/secret-request/secret/$secretRequestId": typeof publicViewSecretRequestByIDPageRouteRoute; + "/shared/secret/$secretId": typeof publicViewSharedSecretByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout": typeof organizationLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/admin": typeof AuthenticateInjectOrgDetailsAdminRouteWithChildren; + "/_authenticate/personal-settings/_layout": typeof userLayoutRouteWithChildren; + "/_authenticate/personal-settings/_layout/": typeof userPersonalSettingsPageRouteRoute; + "/_restrict-login-signup/login/provider/error": typeof authProviderErrorPageRouteRoute; + "/_restrict-login-signup/login/provider/success": typeof authProviderSuccessPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutIntegrationsRouteWithChildren; + "/_authenticate/_inject-org-details/admin/_admin-layout": typeof adminLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/organization/$": typeof redirectsOrganizationRedirectRoute; + "/_authenticate/_inject-org-details/projects/$": typeof redirectsProjectRedirectRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/": typeof adminGeneralPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/access-management": typeof adminAccessManagementPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/authentication": typeof adminAuthenticationPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/caching": typeof adminCachingPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/encryption": typeof adminEncryptionPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/environment": typeof adminEnvironmentPageRouteRoute; + "/_authenticate/_inject-org-details/admin/_admin-layout/integrations": typeof adminIntegrationsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management": typeof organizationAccessManagementPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs": typeof organizationAuditLogsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing": typeof organizationBillingPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking": typeof organizationNetworkingPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects": typeof organizationProjectsPageRouteRouteWithChildren; + "/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview": typeof adminResourceOverviewPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSplatRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdAppConnectionsRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretSharingRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSettingsRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/": typeof organizationAppConnectionsAppConnectionsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/": typeof organizationSecretSharingPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/": typeof organizationSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId": typeof organizationGroupDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId": typeof organizationIdentityDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId": typeof organizationUserDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId": typeof organizationRoleByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsRouteAzureAppConfigurationsOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsRouteAzureKeyVaultOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsRouteBitbucketOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsRouteGcpOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback": typeof secretManagerIntegrationsRouteGithubOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsRouteGitlabOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsRouteHerokuOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsRouteNetlifyOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsRouteVercelOauthRedirectRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSplatRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdSecretManagerProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback": typeof organizationSettingsPageOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsKmsProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSshProjectIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval": typeof secretManagerRedirectsRedirectApprovalPageRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback": typeof organizationAppConnectionsOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout": typeof certManagerLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout": typeof kmsLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout": typeof pamLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout": typeof secretManagerLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout": typeof secretScanningLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout": typeof sshLayoutRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting": typeof certManagerAlertingPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities": typeof certManagerCertificateAuthoritiesPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies": typeof certManagerPoliciesPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings": typeof certManagerSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip": typeof kmsKmipPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview": typeof kmsOverviewPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings": typeof kmsSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts": typeof pamPamAccountsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals": typeof pamApprovalsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources": typeof pamPamResourcesPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings": typeof pamSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist": typeof secretManagerIPAllowlistPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval": typeof secretManagerSecretApprovalsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview": typeof secretManagerOverviewPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation": typeof secretManagerSecretRotationPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings": typeof secretManagerSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings": typeof secretScanningSecretScanningFindingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings": typeof secretScanningSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas": typeof sshSshCasPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates": typeof sshSshCertsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview": typeof sshSshHostsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings": typeof sshSettingsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management": typeof projectAccessControlPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections": typeof projectAppConnectionsPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs": typeof projectAuditLogsPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutCertificateTemplatesRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutIntegrationsRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsCertManagerProjectIdCertManagerLayoutSubscribersRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management": typeof projectAccessControlPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs": typeof projectAuditLogsPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management": typeof projectAccessControlPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs": typeof projectAuditLogsPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsPamProjectIdPamLayoutSessionsRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management": typeof projectAccessControlPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections": typeof projectAppConnectionsPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs": typeof projectAuditLogsPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutIntegrationsRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management": typeof projectAccessControlPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections": typeof projectAppConnectionsPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs": typeof projectAuditLogsPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretScanningProjectIdSecretScanningLayoutDataSourcesRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management": typeof projectAccessControlPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs": typeof projectAuditLogsPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/": typeof certManagerPkiTemplateListPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/": typeof certManagerIntegrationsListPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/": typeof certManagerPkiSubscribersPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/": typeof pamPamSessionsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/": typeof secretManagerIntegrationsListPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/": typeof secretScanningSecretScanningDataSourcesPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId": typeof certManagerCertAuthDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId": typeof certManagerPkiSyncDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName": typeof certManagerPkiSubscriberDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId": typeof pamApprovalRequestDetailPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId": typeof pamPamSessionsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId": typeof secretManagerIntegrationsDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth": typeof secretManagerIntegrationsSelectIntegrationAuthPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug": typeof secretManagerSecretDashboardPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId": typeof sshSshCaByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId": typeof sshSshHostGroupDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId": typeof certManagerPkiCollectionDetailsByIDPageRoutesRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteCertManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteKmsRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRoutePamRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretManagerRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSecretScanningRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId": typeof projectGroupDetailsByIDPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId": typeof projectIdentityDetailsByIDPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId": typeof projectMemberDetailsByIDPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug": typeof projectRoleDetailsBySlugPageRouteSshRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize": typeof secretManagerIntegrationsAwsParameterStoreAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create": typeof secretManagerIntegrationsAwsParameterStoreConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize": typeof secretManagerIntegrationsAwsSecretManagerAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create": typeof secretManagerIntegrationsAwsSecretManagerConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create": typeof secretManagerIntegrationsAzureAppConfigurationConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize": typeof secretManagerIntegrationsAzureDevopsAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create": typeof secretManagerIntegrationsAzureDevopsConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize": typeof secretManagerIntegrationsAzureKeyVaultAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create": typeof secretManagerIntegrationsAzureKeyVaultConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create": typeof secretManagerIntegrationsBitbucketConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize": typeof secretManagerIntegrationsChecklyAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create": typeof secretManagerIntegrationsChecklyConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize": typeof secretManagerIntegrationsCircleCIAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create": typeof secretManagerIntegrationsCircleCIConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize": typeof secretManagerIntegrationsCloud66AuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create": typeof secretManagerIntegrationsCloud66ConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize": typeof secretManagerIntegrationsCloudflarePagesAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create": typeof secretManagerIntegrationsCloudflarePagesConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize": typeof secretManagerIntegrationsCloudflareWorkersAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create": typeof secretManagerIntegrationsCloudflareWorkersConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize": typeof secretManagerIntegrationsCodefreshAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create": typeof secretManagerIntegrationsCodefreshConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize": typeof secretManagerIntegrationsDatabricksAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create": typeof secretManagerIntegrationsDatabricksConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize": typeof secretManagerIntegrationsDigitalOceanAppPlatformAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create": typeof secretManagerIntegrationsDigitalOceanAppPlatformConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize": typeof secretManagerIntegrationsFlyioAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create": typeof secretManagerIntegrationsFlyioConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize": typeof secretManagerIntegrationsGcpSecretManagerAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create": typeof secretManagerIntegrationsGcpSecretManagerConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection": typeof secretManagerIntegrationsGithubAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create": typeof secretManagerIntegrationsGithubConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize": typeof secretManagerIntegrationsGitlabAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create": typeof secretManagerIntegrationsGitlabConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize": typeof secretManagerIntegrationsHashicorpVaultAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create": typeof secretManagerIntegrationsHashicorpVaultConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize": typeof secretManagerIntegrationsHasuraCloudAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create": typeof secretManagerIntegrationsHasuraCloudConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create": typeof secretManagerIntegrationsHerokuConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize": typeof secretManagerIntegrationsLaravelForgeAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create": typeof secretManagerIntegrationsLaravelForgeConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create": typeof secretManagerIntegrationsNetlifyConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize": typeof secretManagerIntegrationsNorthflankAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create": typeof secretManagerIntegrationsNorthflankConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize": typeof secretManagerIntegrationsOctopusDeployAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create": typeof secretManagerIntegrationsOctopusDeployConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize": typeof secretManagerIntegrationsQoveryAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create": typeof secretManagerIntegrationsQoveryConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize": typeof secretManagerIntegrationsRailwayAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create": typeof secretManagerIntegrationsRailwayConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize": typeof secretManagerIntegrationsRenderAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create": typeof secretManagerIntegrationsRenderConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize": typeof secretManagerIntegrationsRundeckAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create": typeof secretManagerIntegrationsRundeckConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize": typeof secretManagerIntegrationsSupabaseAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create": typeof secretManagerIntegrationsSupabaseConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize": typeof secretManagerIntegrationsTeamcityAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create": typeof secretManagerIntegrationsTeamcityConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize": typeof secretManagerIntegrationsTerraformCloudAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create": typeof secretManagerIntegrationsTerraformCloudConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize": typeof secretManagerIntegrationsTravisCIAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create": typeof secretManagerIntegrationsTravisCIConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create": typeof secretManagerIntegrationsVercelConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize": typeof secretManagerIntegrationsWindmillAuthorizePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create": typeof secretManagerIntegrationsWindmillConfigurePageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId": typeof secretScanningSecretScanningDataSourceByIdPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/": typeof secretManagerCommitsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback": typeof secretManagerIntegrationsAzureAppConfigurationOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback": typeof secretManagerIntegrationsAzureKeyVaultOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback": typeof secretManagerIntegrationsBitbucketOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback": typeof secretManagerIntegrationsGcpSecretManagerOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback": typeof secretManagerIntegrationsGithubOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback": typeof secretManagerIntegrationsGitlabOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback": typeof secretManagerIntegrationsHerokuOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback": typeof secretManagerIntegrationsNetlifyOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId": typeof secretManagerSecretSyncDetailsByIDPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback": typeof secretManagerIntegrationsVercelOauthCallbackPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId": typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationsOrgIdProjectsSecretManagementProjectIdSecretManagerLayoutCommitsEnvironmentFolderIdCommitIdRouteWithChildren; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/": typeof secretManagerCommitDetailsPageRouteRoute; + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore": typeof secretManagerCommitDetailsPageComponentsRollbackPreviewTabRouteRoute; } export interface FileRouteTypes { - fileRoutesByFullPath: FileRoutesByFullPath + fileRoutesByFullPath: FileRoutesByFullPath; fullPaths: - | '/' - | '/cli-redirect' - | '/share-secret' - | '/upgrade-path' - | '' - | '/password-setup' - | '/email-not-verified' - | '/password-reset' - | '/requestnewinvite' - | '/signupinvite' - | '/verify-email' - | '/personal-settings' - | '/login' - | '/signup' - | '/login/' - | '/signup/' - | '/organizations/none' - | '/admin/signup' - | '/login/admin' - | '/login/ldap' - | '/login/select-organization' - | '/login/sso' - | '/signup/sso' - | '/secret-request/secret/$secretRequestId' - | '/shared/secret/$secretId' - | '/admin' - | '/personal-settings/' - | '/login/provider/error' - | '/login/provider/success' - | '/integrations' - | '/organization/$' - | '/projects/$' - | '/admin/' - | '/admin/access-management' - | '/admin/authentication' - | '/admin/caching' - | '/admin/encryption' - | '/admin/environment' - | '/admin/integrations' - | '/organizations/$orgId' - | '/organizations/$orgId/access-management' - | '/organizations/$orgId/audit-logs' - | '/organizations/$orgId/billing' - | '/organizations/$orgId/networking' - | '/organizations/$orgId/projects' - | '/admin/resources/overview' - | '/organizations/$orgId/$' - | '/organizations/$orgId/app-connections' - | '/organizations/$orgId/secret-sharing' - | '/organizations/$orgId/settings' - | '/organizations/$orgId/app-connections/' - | '/organizations/$orgId/secret-sharing/' - | '/organizations/$orgId/settings/' - | '/organizations/$orgId/groups/$groupId' - | '/organizations/$orgId/identities/$identityId' - | '/organizations/$orgId/members/$membershipId' - | '/organizations/$orgId/roles/$roleId' - | '/integrations/azure-app-configuration/oauth2/callback' - | '/integrations/azure-key-vault/oauth2/callback' - | '/integrations/bitbucket/oauth2/callback' - | '/integrations/gcp-secret-manager/oauth2/callback' - | '/integrations/github/oauth2/callback' - | '/integrations/gitlab/oauth2/callback' - | '/integrations/heroku/oauth2/callback' - | '/integrations/netlify/oauth2/callback' - | '/integrations/vercel/oauth2/callback' - | '/organizations/$orgId/projects/$' - | '/organizations/$orgId/secret-manager/$projectId' - | '/organizations/$orgId/settings/oauth/callback' - | '/organizations/$orgId/projects/cert-management/$projectId' - | '/organizations/$orgId/projects/kms/$projectId' - | '/organizations/$orgId/projects/pam/$projectId' - | '/organizations/$orgId/projects/secret-management/$projectId' - | '/organizations/$orgId/projects/secret-scanning/$projectId' - | '/organizations/$orgId/projects/ssh/$projectId' - | '/organizations/$orgId/secret-manager/$projectId/approval' - | '/organizations/$orgId/app-connections/$appConnection/oauth/callback' - | '/organizations/$orgId/projects/cert-management/$projectId/alerting' - | '/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities' - | '/organizations/$orgId/projects/cert-management/$projectId/policies' - | '/organizations/$orgId/projects/cert-management/$projectId/settings' - | '/organizations/$orgId/projects/kms/$projectId/kmip' - | '/organizations/$orgId/projects/kms/$projectId/overview' - | '/organizations/$orgId/projects/kms/$projectId/settings' - | '/organizations/$orgId/projects/pam/$projectId/accounts' - | '/organizations/$orgId/projects/pam/$projectId/approvals' - | '/organizations/$orgId/projects/pam/$projectId/resources' - | '/organizations/$orgId/projects/pam/$projectId/settings' - | '/organizations/$orgId/projects/secret-management/$projectId/allowlist' - | '/organizations/$orgId/projects/secret-management/$projectId/approval' - | '/organizations/$orgId/projects/secret-management/$projectId/overview' - | '/organizations/$orgId/projects/secret-management/$projectId/secret-rotation' - | '/organizations/$orgId/projects/secret-management/$projectId/settings' - | '/organizations/$orgId/projects/secret-scanning/$projectId/findings' - | '/organizations/$orgId/projects/secret-scanning/$projectId/settings' - | '/organizations/$orgId/projects/ssh/$projectId/cas' - | '/organizations/$orgId/projects/ssh/$projectId/certificates' - | '/organizations/$orgId/projects/ssh/$projectId/overview' - | '/organizations/$orgId/projects/ssh/$projectId/settings' - | '/organizations/$orgId/projects/cert-management/$projectId/access-management' - | '/organizations/$orgId/projects/cert-management/$projectId/app-connections' - | '/organizations/$orgId/projects/cert-management/$projectId/audit-logs' - | '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates' - | '/organizations/$orgId/projects/cert-management/$projectId/integrations' - | '/organizations/$orgId/projects/cert-management/$projectId/subscribers' - | '/organizations/$orgId/projects/kms/$projectId/access-management' - | '/organizations/$orgId/projects/kms/$projectId/audit-logs' - | '/organizations/$orgId/projects/pam/$projectId/access-management' - | '/organizations/$orgId/projects/pam/$projectId/audit-logs' - | '/organizations/$orgId/projects/pam/$projectId/sessions' - | '/organizations/$orgId/projects/secret-management/$projectId/access-management' - | '/organizations/$orgId/projects/secret-management/$projectId/app-connections' - | '/organizations/$orgId/projects/secret-management/$projectId/audit-logs' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations' - | '/organizations/$orgId/projects/secret-scanning/$projectId/access-management' - | '/organizations/$orgId/projects/secret-scanning/$projectId/app-connections' - | '/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs' - | '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources' - | '/organizations/$orgId/projects/ssh/$projectId/access-management' - | '/organizations/$orgId/projects/ssh/$projectId/audit-logs' - | '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates/' - | '/organizations/$orgId/projects/cert-management/$projectId/integrations/' - | '/organizations/$orgId/projects/cert-management/$projectId/subscribers/' - | '/organizations/$orgId/projects/pam/$projectId/sessions/' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/' - | '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/' - | '/organizations/$orgId/projects/cert-management/$projectId/ca/$caId' - | '/organizations/$orgId/projects/cert-management/$projectId/integrations/$syncId' - | '/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName' - | '/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId' - | '/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth' - | '/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug' - | '/organizations/$orgId/projects/ssh/$projectId/ca/$caId' - | '/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' - | '/organizations/$orgId/projects/cert-management/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/cert-management/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/cert-management/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId' - | '/organizations/$orgId/projects/cert-management/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/kms/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/kms/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/kms/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/pam/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/pam/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/pam/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/ssh/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/ssh/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/ssh/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create' - | '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' - fileRoutesByTo: FileRoutesByTo + | "/" + | "/cli-redirect" + | "/share-secret" + | "/upgrade-path" + | "" + | "/password-setup" + | "/email-not-verified" + | "/password-reset" + | "/requestnewinvite" + | "/signupinvite" + | "/verify-email" + | "/personal-settings" + | "/login" + | "/signup" + | "/login/" + | "/signup/" + | "/organizations/none" + | "/admin/signup" + | "/login/admin" + | "/login/ldap" + | "/login/select-organization" + | "/login/sso" + | "/signup/sso" + | "/secret-request/secret/$secretRequestId" + | "/shared/secret/$secretId" + | "/admin" + | "/personal-settings/" + | "/login/provider/error" + | "/login/provider/success" + | "/integrations" + | "/organization/$" + | "/projects/$" + | "/admin/" + | "/admin/access-management" + | "/admin/authentication" + | "/admin/caching" + | "/admin/encryption" + | "/admin/environment" + | "/admin/integrations" + | "/organizations/$orgId" + | "/organizations/$orgId/access-management" + | "/organizations/$orgId/audit-logs" + | "/organizations/$orgId/billing" + | "/organizations/$orgId/networking" + | "/organizations/$orgId/projects" + | "/admin/resources/overview" + | "/organizations/$orgId/$" + | "/organizations/$orgId/app-connections" + | "/organizations/$orgId/secret-sharing" + | "/organizations/$orgId/settings" + | "/organizations/$orgId/app-connections/" + | "/organizations/$orgId/secret-sharing/" + | "/organizations/$orgId/settings/" + | "/organizations/$orgId/groups/$groupId" + | "/organizations/$orgId/identities/$identityId" + | "/organizations/$orgId/members/$membershipId" + | "/organizations/$orgId/roles/$roleId" + | "/integrations/azure-app-configuration/oauth2/callback" + | "/integrations/azure-key-vault/oauth2/callback" + | "/integrations/bitbucket/oauth2/callback" + | "/integrations/gcp-secret-manager/oauth2/callback" + | "/integrations/github/oauth2/callback" + | "/integrations/gitlab/oauth2/callback" + | "/integrations/heroku/oauth2/callback" + | "/integrations/netlify/oauth2/callback" + | "/integrations/vercel/oauth2/callback" + | "/organizations/$orgId/projects/$" + | "/organizations/$orgId/secret-manager/$projectId" + | "/organizations/$orgId/settings/oauth/callback" + | "/organizations/$orgId/projects/cert-manager/$projectId" + | "/organizations/$orgId/projects/kms/$projectId" + | "/organizations/$orgId/projects/pam/$projectId" + | "/organizations/$orgId/projects/secret-management/$projectId" + | "/organizations/$orgId/projects/secret-scanning/$projectId" + | "/organizations/$orgId/projects/ssh/$projectId" + | "/organizations/$orgId/secret-manager/$projectId/approval" + | "/organizations/$orgId/app-connections/$appConnection/oauth/callback" + | "/organizations/$orgId/projects/cert-manager/$projectId/alerting" + | "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities" + | "/organizations/$orgId/projects/cert-manager/$projectId/policies" + | "/organizations/$orgId/projects/cert-manager/$projectId/settings" + | "/organizations/$orgId/projects/kms/$projectId/kmip" + | "/organizations/$orgId/projects/kms/$projectId/overview" + | "/organizations/$orgId/projects/kms/$projectId/settings" + | "/organizations/$orgId/projects/pam/$projectId/accounts" + | "/organizations/$orgId/projects/pam/$projectId/approvals" + | "/organizations/$orgId/projects/pam/$projectId/resources" + | "/organizations/$orgId/projects/pam/$projectId/settings" + | "/organizations/$orgId/projects/secret-management/$projectId/allowlist" + | "/organizations/$orgId/projects/secret-management/$projectId/approval" + | "/organizations/$orgId/projects/secret-management/$projectId/overview" + | "/organizations/$orgId/projects/secret-management/$projectId/secret-rotation" + | "/organizations/$orgId/projects/secret-management/$projectId/settings" + | "/organizations/$orgId/projects/secret-scanning/$projectId/findings" + | "/organizations/$orgId/projects/secret-scanning/$projectId/settings" + | "/organizations/$orgId/projects/ssh/$projectId/cas" + | "/organizations/$orgId/projects/ssh/$projectId/certificates" + | "/organizations/$orgId/projects/ssh/$projectId/overview" + | "/organizations/$orgId/projects/ssh/$projectId/settings" + | "/organizations/$orgId/projects/cert-manager/$projectId/access-management" + | "/organizations/$orgId/projects/cert-manager/$projectId/app-connections" + | "/organizations/$orgId/projects/cert-manager/$projectId/audit-logs" + | "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates" + | "/organizations/$orgId/projects/cert-manager/$projectId/integrations" + | "/organizations/$orgId/projects/cert-manager/$projectId/subscribers" + | "/organizations/$orgId/projects/kms/$projectId/access-management" + | "/organizations/$orgId/projects/kms/$projectId/audit-logs" + | "/organizations/$orgId/projects/pam/$projectId/access-management" + | "/organizations/$orgId/projects/pam/$projectId/audit-logs" + | "/organizations/$orgId/projects/pam/$projectId/sessions" + | "/organizations/$orgId/projects/secret-management/$projectId/access-management" + | "/organizations/$orgId/projects/secret-management/$projectId/app-connections" + | "/organizations/$orgId/projects/secret-management/$projectId/audit-logs" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations" + | "/organizations/$orgId/projects/secret-scanning/$projectId/access-management" + | "/organizations/$orgId/projects/secret-scanning/$projectId/app-connections" + | "/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs" + | "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources" + | "/organizations/$orgId/projects/ssh/$projectId/access-management" + | "/organizations/$orgId/projects/ssh/$projectId/audit-logs" + | "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates/" + | "/organizations/$orgId/projects/cert-manager/$projectId/integrations/" + | "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/" + | "/organizations/$orgId/projects/pam/$projectId/sessions/" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/" + | "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/" + | "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId" + | "/organizations/$orgId/projects/cert-manager/$projectId/integrations/$syncId" + | "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName" + | "/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId" + | "/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth" + | "/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug" + | "/organizations/$orgId/projects/ssh/$projectId/ca/$caId" + | "/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId" + | "/organizations/$orgId/projects/cert-manager/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/cert-manager/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/cert-manager/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId" + | "/organizations/$orgId/projects/cert-manager/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/kms/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/kms/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/kms/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/pam/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/pam/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/pam/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/ssh/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/ssh/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/ssh/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create" + | "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore"; + fileRoutesByTo: FileRoutesByTo; to: - | '/' - | '/cli-redirect' - | '/share-secret' - | '/upgrade-path' - | '' - | '/password-setup' - | '/email-not-verified' - | '/password-reset' - | '/requestnewinvite' - | '/signupinvite' - | '/verify-email' - | '/personal-settings' - | '/login' - | '/signup' - | '/organizations/none' - | '/admin/signup' - | '/login/admin' - | '/login/ldap' - | '/login/select-organization' - | '/login/sso' - | '/signup/sso' - | '/secret-request/secret/$secretRequestId' - | '/shared/secret/$secretId' - | '/admin' - | '/login/provider/error' - | '/login/provider/success' - | '/integrations' - | '/organization/$' - | '/projects/$' - | '/admin/access-management' - | '/admin/authentication' - | '/admin/caching' - | '/admin/encryption' - | '/admin/environment' - | '/admin/integrations' - | '/organizations/$orgId' - | '/organizations/$orgId/access-management' - | '/organizations/$orgId/audit-logs' - | '/organizations/$orgId/billing' - | '/organizations/$orgId/networking' - | '/organizations/$orgId/projects' - | '/admin/resources/overview' - | '/organizations/$orgId/$' - | '/organizations/$orgId/app-connections' - | '/organizations/$orgId/secret-sharing' - | '/organizations/$orgId/settings' - | '/organizations/$orgId/groups/$groupId' - | '/organizations/$orgId/identities/$identityId' - | '/organizations/$orgId/members/$membershipId' - | '/organizations/$orgId/roles/$roleId' - | '/integrations/azure-app-configuration/oauth2/callback' - | '/integrations/azure-key-vault/oauth2/callback' - | '/integrations/bitbucket/oauth2/callback' - | '/integrations/gcp-secret-manager/oauth2/callback' - | '/integrations/github/oauth2/callback' - | '/integrations/gitlab/oauth2/callback' - | '/integrations/heroku/oauth2/callback' - | '/integrations/netlify/oauth2/callback' - | '/integrations/vercel/oauth2/callback' - | '/organizations/$orgId/projects/$' - | '/organizations/$orgId/secret-manager/$projectId' - | '/organizations/$orgId/settings/oauth/callback' - | '/organizations/$orgId/projects/cert-management/$projectId' - | '/organizations/$orgId/projects/kms/$projectId' - | '/organizations/$orgId/projects/pam/$projectId' - | '/organizations/$orgId/projects/secret-management/$projectId' - | '/organizations/$orgId/projects/secret-scanning/$projectId' - | '/organizations/$orgId/projects/ssh/$projectId' - | '/organizations/$orgId/secret-manager/$projectId/approval' - | '/organizations/$orgId/app-connections/$appConnection/oauth/callback' - | '/organizations/$orgId/projects/cert-management/$projectId/alerting' - | '/organizations/$orgId/projects/cert-management/$projectId/certificate-authorities' - | '/organizations/$orgId/projects/cert-management/$projectId/policies' - | '/organizations/$orgId/projects/cert-management/$projectId/settings' - | '/organizations/$orgId/projects/kms/$projectId/kmip' - | '/organizations/$orgId/projects/kms/$projectId/overview' - | '/organizations/$orgId/projects/kms/$projectId/settings' - | '/organizations/$orgId/projects/pam/$projectId/accounts' - | '/organizations/$orgId/projects/pam/$projectId/approvals' - | '/organizations/$orgId/projects/pam/$projectId/resources' - | '/organizations/$orgId/projects/pam/$projectId/settings' - | '/organizations/$orgId/projects/secret-management/$projectId/allowlist' - | '/organizations/$orgId/projects/secret-management/$projectId/approval' - | '/organizations/$orgId/projects/secret-management/$projectId/overview' - | '/organizations/$orgId/projects/secret-management/$projectId/secret-rotation' - | '/organizations/$orgId/projects/secret-management/$projectId/settings' - | '/organizations/$orgId/projects/secret-scanning/$projectId/findings' - | '/organizations/$orgId/projects/secret-scanning/$projectId/settings' - | '/organizations/$orgId/projects/ssh/$projectId/cas' - | '/organizations/$orgId/projects/ssh/$projectId/certificates' - | '/organizations/$orgId/projects/ssh/$projectId/overview' - | '/organizations/$orgId/projects/ssh/$projectId/settings' - | '/organizations/$orgId/projects/cert-management/$projectId/access-management' - | '/organizations/$orgId/projects/cert-management/$projectId/app-connections' - | '/organizations/$orgId/projects/cert-management/$projectId/audit-logs' - | '/organizations/$orgId/projects/kms/$projectId/access-management' - | '/organizations/$orgId/projects/kms/$projectId/audit-logs' - | '/organizations/$orgId/projects/pam/$projectId/access-management' - | '/organizations/$orgId/projects/pam/$projectId/audit-logs' - | '/organizations/$orgId/projects/secret-management/$projectId/access-management' - | '/organizations/$orgId/projects/secret-management/$projectId/app-connections' - | '/organizations/$orgId/projects/secret-management/$projectId/audit-logs' - | '/organizations/$orgId/projects/secret-scanning/$projectId/access-management' - | '/organizations/$orgId/projects/secret-scanning/$projectId/app-connections' - | '/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs' - | '/organizations/$orgId/projects/ssh/$projectId/access-management' - | '/organizations/$orgId/projects/ssh/$projectId/audit-logs' - | '/organizations/$orgId/projects/cert-management/$projectId/certificate-templates' - | '/organizations/$orgId/projects/cert-management/$projectId/integrations' - | '/organizations/$orgId/projects/cert-management/$projectId/subscribers' - | '/organizations/$orgId/projects/pam/$projectId/sessions' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations' - | '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources' - | '/organizations/$orgId/projects/cert-management/$projectId/ca/$caId' - | '/organizations/$orgId/projects/cert-management/$projectId/integrations/$syncId' - | '/organizations/$orgId/projects/cert-management/$projectId/subscribers/$subscriberName' - | '/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId' - | '/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth' - | '/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug' - | '/organizations/$orgId/projects/ssh/$projectId/ca/$caId' - | '/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId' - | '/organizations/$orgId/projects/cert-management/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/cert-management/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/cert-management/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/cert-management/$projectId/pki-collections/$collectionId' - | '/organizations/$orgId/projects/cert-management/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/kms/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/kms/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/kms/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/pam/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/pam/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/pam/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/ssh/$projectId/groups/$groupId' - | '/organizations/$orgId/projects/ssh/$projectId/identities/$identityId' - | '/organizations/$orgId/projects/ssh/$projectId/members/$membershipId' - | '/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create' - | '/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId' - | '/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId' - | '/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore' + | "/" + | "/cli-redirect" + | "/share-secret" + | "/upgrade-path" + | "" + | "/password-setup" + | "/email-not-verified" + | "/password-reset" + | "/requestnewinvite" + | "/signupinvite" + | "/verify-email" + | "/personal-settings" + | "/login" + | "/signup" + | "/organizations/none" + | "/admin/signup" + | "/login/admin" + | "/login/ldap" + | "/login/select-organization" + | "/login/sso" + | "/signup/sso" + | "/secret-request/secret/$secretRequestId" + | "/shared/secret/$secretId" + | "/admin" + | "/login/provider/error" + | "/login/provider/success" + | "/integrations" + | "/organization/$" + | "/projects/$" + | "/admin/access-management" + | "/admin/authentication" + | "/admin/caching" + | "/admin/encryption" + | "/admin/environment" + | "/admin/integrations" + | "/organizations/$orgId" + | "/organizations/$orgId/access-management" + | "/organizations/$orgId/audit-logs" + | "/organizations/$orgId/billing" + | "/organizations/$orgId/networking" + | "/organizations/$orgId/projects" + | "/admin/resources/overview" + | "/organizations/$orgId/$" + | "/organizations/$orgId/app-connections" + | "/organizations/$orgId/secret-sharing" + | "/organizations/$orgId/settings" + | "/organizations/$orgId/groups/$groupId" + | "/organizations/$orgId/identities/$identityId" + | "/organizations/$orgId/members/$membershipId" + | "/organizations/$orgId/roles/$roleId" + | "/integrations/azure-app-configuration/oauth2/callback" + | "/integrations/azure-key-vault/oauth2/callback" + | "/integrations/bitbucket/oauth2/callback" + | "/integrations/gcp-secret-manager/oauth2/callback" + | "/integrations/github/oauth2/callback" + | "/integrations/gitlab/oauth2/callback" + | "/integrations/heroku/oauth2/callback" + | "/integrations/netlify/oauth2/callback" + | "/integrations/vercel/oauth2/callback" + | "/organizations/$orgId/projects/$" + | "/organizations/$orgId/secret-manager/$projectId" + | "/organizations/$orgId/settings/oauth/callback" + | "/organizations/$orgId/projects/cert-manager/$projectId" + | "/organizations/$orgId/projects/kms/$projectId" + | "/organizations/$orgId/projects/pam/$projectId" + | "/organizations/$orgId/projects/secret-management/$projectId" + | "/organizations/$orgId/projects/secret-scanning/$projectId" + | "/organizations/$orgId/projects/ssh/$projectId" + | "/organizations/$orgId/secret-manager/$projectId/approval" + | "/organizations/$orgId/app-connections/$appConnection/oauth/callback" + | "/organizations/$orgId/projects/cert-manager/$projectId/alerting" + | "/organizations/$orgId/projects/cert-manager/$projectId/certificate-authorities" + | "/organizations/$orgId/projects/cert-manager/$projectId/policies" + | "/organizations/$orgId/projects/cert-manager/$projectId/settings" + | "/organizations/$orgId/projects/kms/$projectId/kmip" + | "/organizations/$orgId/projects/kms/$projectId/overview" + | "/organizations/$orgId/projects/kms/$projectId/settings" + | "/organizations/$orgId/projects/pam/$projectId/accounts" + | "/organizations/$orgId/projects/pam/$projectId/approvals" + | "/organizations/$orgId/projects/pam/$projectId/resources" + | "/organizations/$orgId/projects/pam/$projectId/settings" + | "/organizations/$orgId/projects/secret-management/$projectId/allowlist" + | "/organizations/$orgId/projects/secret-management/$projectId/approval" + | "/organizations/$orgId/projects/secret-management/$projectId/overview" + | "/organizations/$orgId/projects/secret-management/$projectId/secret-rotation" + | "/organizations/$orgId/projects/secret-management/$projectId/settings" + | "/organizations/$orgId/projects/secret-scanning/$projectId/findings" + | "/organizations/$orgId/projects/secret-scanning/$projectId/settings" + | "/organizations/$orgId/projects/ssh/$projectId/cas" + | "/organizations/$orgId/projects/ssh/$projectId/certificates" + | "/organizations/$orgId/projects/ssh/$projectId/overview" + | "/organizations/$orgId/projects/ssh/$projectId/settings" + | "/organizations/$orgId/projects/cert-manager/$projectId/access-management" + | "/organizations/$orgId/projects/cert-manager/$projectId/app-connections" + | "/organizations/$orgId/projects/cert-manager/$projectId/audit-logs" + | "/organizations/$orgId/projects/kms/$projectId/access-management" + | "/organizations/$orgId/projects/kms/$projectId/audit-logs" + | "/organizations/$orgId/projects/pam/$projectId/access-management" + | "/organizations/$orgId/projects/pam/$projectId/audit-logs" + | "/organizations/$orgId/projects/secret-management/$projectId/access-management" + | "/organizations/$orgId/projects/secret-management/$projectId/app-connections" + | "/organizations/$orgId/projects/secret-management/$projectId/audit-logs" + | "/organizations/$orgId/projects/secret-scanning/$projectId/access-management" + | "/organizations/$orgId/projects/secret-scanning/$projectId/app-connections" + | "/organizations/$orgId/projects/secret-scanning/$projectId/audit-logs" + | "/organizations/$orgId/projects/ssh/$projectId/access-management" + | "/organizations/$orgId/projects/ssh/$projectId/audit-logs" + | "/organizations/$orgId/projects/cert-manager/$projectId/certificate-templates" + | "/organizations/$orgId/projects/cert-manager/$projectId/integrations" + | "/organizations/$orgId/projects/cert-manager/$projectId/subscribers" + | "/organizations/$orgId/projects/pam/$projectId/sessions" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations" + | "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources" + | "/organizations/$orgId/projects/cert-manager/$projectId/ca/$caId" + | "/organizations/$orgId/projects/cert-manager/$projectId/integrations/$syncId" + | "/organizations/$orgId/projects/cert-manager/$projectId/subscribers/$subscriberName" + | "/organizations/$orgId/projects/pam/$projectId/approval-requests/$approvalRequestId" + | "/organizations/$orgId/projects/pam/$projectId/sessions/$sessionId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/$integrationId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/select-integration-auth" + | "/organizations/$orgId/projects/secret-management/$projectId/secrets/$envSlug" + | "/organizations/$orgId/projects/ssh/$projectId/ca/$caId" + | "/organizations/$orgId/projects/ssh/$projectId/ssh-host-groups/$sshHostGroupId" + | "/organizations/$orgId/projects/cert-manager/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/cert-manager/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/cert-manager/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/cert-manager/$projectId/pki-collections/$collectionId" + | "/organizations/$orgId/projects/cert-manager/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/kms/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/kms/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/kms/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/kms/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/pam/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/pam/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/pam/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/pam/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-management/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/secret-management/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/secret-management/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/secret-management/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-scanning/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/secret-scanning/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/ssh/$projectId/groups/$groupId" + | "/organizations/$orgId/projects/ssh/$projectId/identities/$identityId" + | "/organizations/$orgId/projects/ssh/$projectId/members/$membershipId" + | "/organizations/$orgId/projects/ssh/$projectId/roles/$roleSlug" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-parameter-store/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/aws-secret-manager/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-devops/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/checkly/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/circleci/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloud-66/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-pages/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/cloudflare-workers/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/codefresh/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/databricks/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/digital-ocean-app-platform/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/flyio/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/auth-mode-selection" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hashicorp-vault/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/hasura-cloud/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/laravel-forge/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/northflank/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/octopus-deploy/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/qovery/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/railway/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/render/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/rundeck/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/supabase/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/teamcity/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/terraform-cloud/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/travisci/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/create" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/authorize" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/windmill/create" + | "/organizations/$orgId/projects/secret-scanning/$projectId/data-sources/$type/$dataSourceId" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-app-configuration/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/azure-key-vault/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/bitbucket/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gcp-secret-manager/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/github/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/gitlab/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/heroku/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/netlify/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/secret-syncs/$destination/$syncId" + | "/organizations/$orgId/projects/secret-management/$projectId/integrations/vercel/oauth2/callback" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId" + | "/organizations/$orgId/projects/secret-management/$projectId/commits/$environment/$folderId/$commitId/restore"; id: - | '__root__' - | '/' - | '/cli-redirect' - | '/share-secret' - | '/upgrade-path' - | '/_authenticate' - | '/_restrict-login-signup' - | '/_authenticate/password-setup' - | '/_restrict-login-signup/email-not-verified' - | '/_restrict-login-signup/password-reset' - | '/_restrict-login-signup/requestnewinvite' - | '/_restrict-login-signup/signupinvite' - | '/_restrict-login-signup/verify-email' - | '/_authenticate/_inject-org-details' - | '/_authenticate/personal-settings' - | '/_restrict-login-signup/login' - | '/_restrict-login-signup/signup' - | '/_restrict-login-signup/login/' - | '/_restrict-login-signup/signup/' - | '/_authenticate/organizations/none' - | '/_restrict-login-signup/admin/signup' - | '/_restrict-login-signup/login/admin' - | '/_restrict-login-signup/login/ldap' - | '/_restrict-login-signup/login/select-organization' - | '/_restrict-login-signup/login/sso' - | '/_restrict-login-signup/signup/sso' - | '/secret-request/secret/$secretRequestId' - | '/shared/secret/$secretId' - | '/_authenticate/_inject-org-details/_org-layout' - | '/_authenticate/_inject-org-details/admin' - | '/_authenticate/personal-settings/_layout' - | '/_authenticate/personal-settings/_layout/' - | '/_restrict-login-signup/login/provider/error' - | '/_restrict-login-signup/login/provider/success' - | '/_authenticate/_inject-org-details/_org-layout/integrations' - | '/_authenticate/_inject-org-details/admin/_admin-layout' - | '/_authenticate/_inject-org-details/organization/$' - | '/_authenticate/_inject-org-details/projects/$' - | '/_authenticate/_inject-org-details/admin/_admin-layout/' - | '/_authenticate/_inject-org-details/admin/_admin-layout/access-management' - | '/_authenticate/_inject-org-details/admin/_admin-layout/authentication' - | '/_authenticate/_inject-org-details/admin/_admin-layout/caching' - | '/_authenticate/_inject-org-details/admin/_admin-layout/encryption' - | '/_authenticate/_inject-org-details/admin/_admin-layout/environment' - | '/_authenticate/_inject-org-details/admin/_admin-layout/integrations' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects' - | '/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId' - | '/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/' - | '/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore' - fileRoutesById: FileRoutesById + | "__root__" + | "/" + | "/cli-redirect" + | "/share-secret" + | "/upgrade-path" + | "/_authenticate" + | "/_restrict-login-signup" + | "/_authenticate/password-setup" + | "/_restrict-login-signup/email-not-verified" + | "/_restrict-login-signup/password-reset" + | "/_restrict-login-signup/requestnewinvite" + | "/_restrict-login-signup/signupinvite" + | "/_restrict-login-signup/verify-email" + | "/_authenticate/_inject-org-details" + | "/_authenticate/personal-settings" + | "/_restrict-login-signup/login" + | "/_restrict-login-signup/signup" + | "/_restrict-login-signup/login/" + | "/_restrict-login-signup/signup/" + | "/_authenticate/organizations/none" + | "/_restrict-login-signup/admin/signup" + | "/_restrict-login-signup/login/admin" + | "/_restrict-login-signup/login/ldap" + | "/_restrict-login-signup/login/select-organization" + | "/_restrict-login-signup/login/sso" + | "/_restrict-login-signup/signup/sso" + | "/secret-request/secret/$secretRequestId" + | "/shared/secret/$secretId" + | "/_authenticate/_inject-org-details/_org-layout" + | "/_authenticate/_inject-org-details/admin" + | "/_authenticate/personal-settings/_layout" + | "/_authenticate/personal-settings/_layout/" + | "/_restrict-login-signup/login/provider/error" + | "/_restrict-login-signup/login/provider/success" + | "/_authenticate/_inject-org-details/_org-layout/integrations" + | "/_authenticate/_inject-org-details/admin/_admin-layout" + | "/_authenticate/_inject-org-details/organization/$" + | "/_authenticate/_inject-org-details/projects/$" + | "/_authenticate/_inject-org-details/admin/_admin-layout/" + | "/_authenticate/_inject-org-details/admin/_admin-layout/access-management" + | "/_authenticate/_inject-org-details/admin/_admin-layout/authentication" + | "/_authenticate/_inject-org-details/admin/_admin-layout/caching" + | "/_authenticate/_inject-org-details/admin/_admin-layout/encryption" + | "/_authenticate/_inject-org-details/admin/_admin-layout/environment" + | "/_authenticate/_inject-org-details/admin/_admin-layout/integrations" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/billing" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/networking" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects" + | "/_authenticate/_inject-org-details/admin/_admin-layout/resources/overview" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/$" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-sharing/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/roles/$roleId" + | "/_authenticate/_inject-org-details/_org-layout/integrations/azure-app-configuration/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/azure-key-vault/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/bitbucket/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/gcp-secret-manager/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/github/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/gitlab/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/heroku/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/netlify/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/integrations/vercel/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings/oauth/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/secret-manager/$projectId/approval" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections/$appConnection/oauth/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/overview" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/accounts" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approvals" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/resources" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/allowlist" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/approval" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/overview" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/findings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/cas" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/certificates" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/overview" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/settings" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/app-connections" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/app-connections" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/access-management" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/audit-logs" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/$sessionId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/$integrationId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/select-integration-auth" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/secrets/$envSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ca/$caId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/ssh-host-groups/$sshHostGroupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/groups/$groupId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/identities/$identityId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/members/$membershipId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-devops/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/checkly/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/circleci/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloud-66/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/codefresh/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/databricks/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/flyio/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/auth-mode-selection" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/hasura-cloud/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/laravel-forge/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/northflank/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/octopus-deploy/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/qovery/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/railway/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/render/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/rundeck/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/supabase/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/teamcity/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/terraform-cloud/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/travisci/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/authorize" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/windmill/create" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/$type/$dataSourceId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/github/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/secret-syncs/$destination/$syncId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/" + | "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId/_secret-manager-layout/commits/$environment/$folderId/$commitId/restore"; + fileRoutesById: FileRoutesById; } export interface RootRouteChildren { - indexRoute: typeof indexRoute - authCliRedirectPageRouteRoute: typeof authCliRedirectPageRouteRoute - publicShareSecretPageRouteRoute: typeof publicShareSecretPageRouteRoute - publicUpgradePathPageRouteRoute: typeof publicUpgradePathPageRouteRoute - middlewaresAuthenticateRoute: typeof middlewaresAuthenticateRouteWithChildren - middlewaresRestrictLoginSignupRoute: typeof middlewaresRestrictLoginSignupRouteWithChildren - publicViewSecretRequestByIDPageRouteRoute: typeof publicViewSecretRequestByIDPageRouteRoute - publicViewSharedSecretByIDPageRouteRoute: typeof publicViewSharedSecretByIDPageRouteRoute + indexRoute: typeof indexRoute; + authCliRedirectPageRouteRoute: typeof authCliRedirectPageRouteRoute; + publicShareSecretPageRouteRoute: typeof publicShareSecretPageRouteRoute; + publicUpgradePathPageRouteRoute: typeof publicUpgradePathPageRouteRoute; + middlewaresAuthenticateRoute: typeof middlewaresAuthenticateRouteWithChildren; + middlewaresRestrictLoginSignupRoute: typeof middlewaresRestrictLoginSignupRouteWithChildren; + publicViewSecretRequestByIDPageRouteRoute: typeof publicViewSecretRequestByIDPageRouteRoute; + publicViewSharedSecretByIDPageRouteRoute: typeof publicViewSharedSecretByIDPageRouteRoute; } const rootRouteChildren: RootRouteChildren = { @@ -6588,17 +6410,14 @@ const rootRouteChildren: RootRouteChildren = { publicShareSecretPageRouteRoute: publicShareSecretPageRouteRoute, publicUpgradePathPageRouteRoute: publicUpgradePathPageRouteRoute, middlewaresAuthenticateRoute: middlewaresAuthenticateRouteWithChildren, - middlewaresRestrictLoginSignupRoute: - middlewaresRestrictLoginSignupRouteWithChildren, - publicViewSecretRequestByIDPageRouteRoute: - publicViewSecretRequestByIDPageRouteRoute, - publicViewSharedSecretByIDPageRouteRoute: - publicViewSharedSecretByIDPageRouteRoute, -} + middlewaresRestrictLoginSignupRoute: middlewaresRestrictLoginSignupRouteWithChildren, + publicViewSecretRequestByIDPageRouteRoute: publicViewSecretRequestByIDPageRouteRoute, + publicViewSharedSecretByIDPageRouteRoute: publicViewSharedSecretByIDPageRouteRoute +}; export const routeTree = rootRoute ._addFileChildren(rootRouteChildren) - ._addFileTypes() + ._addFileTypes(); /* ROUTE_MANIFEST_START { @@ -6894,7 +6713,7 @@ export const routeTree = rootRoute "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId", "children": [ "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/$", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId", "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId", "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId", "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-management/$projectId", @@ -7012,11 +6831,11 @@ export const routeTree = rootRoute "filePath": "organization/SettingsPage/OauthCallbackPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/settings" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId": { "filePath": "", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects", "children": [ - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" ] }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId": { @@ -7062,26 +6881,26 @@ export const routeTree = rootRoute "filePath": "organization/AppConnections/OauthCallbackPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/app-connections" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout": { "filePath": "cert-manager/layout.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId", + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId", "children": [ - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug" ] }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout": { @@ -7172,21 +6991,21 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug" ] }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/alerting": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/alerting": { "filePath": "cert-manager/AlertingPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-authorities": { "filePath": "cert-manager/CertificateAuthoritiesPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/policies": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/policies": { "filePath": "cert-manager/PoliciesPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/settings": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/settings": { "filePath": "cert-manager/SettingsPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/kmip": { "filePath": "kms/KmipPage/route.tsx", @@ -7260,39 +7079,39 @@ export const routeTree = rootRoute "filePath": "ssh/SettingsPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/access-management": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/access-management": { "filePath": "project/AccessControlPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/app-connections": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/app-connections": { "filePath": "project/AppConnectionsPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/audit-logs": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/audit-logs": { "filePath": "project/AuditLogsPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/" ] }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId" ] }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers": { "filePath": "", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout", + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout", "children": [ - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/", - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName" + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/", + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName" ] }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/access-management": { @@ -7443,17 +7262,17 @@ export const routeTree = rootRoute "filePath": "project/AuditLogsPage/route-ssh.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates/": { "filePath": "cert-manager/PkiTemplateListPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/certificate-templates" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/": { "filePath": "cert-manager/IntegrationsListPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/": { "filePath": "cert-manager/PkiSubscribersPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers" }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/sessions/": { "filePath": "pam/PamSessionsPage/route.tsx", @@ -7467,17 +7286,17 @@ export const routeTree = rootRoute "filePath": "secret-scanning/SecretScanningDataSourcesPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/ca/$caId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/ca/$caId": { "filePath": "cert-manager/CertAuthDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations/$syncId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations/$syncId": { "filePath": "cert-manager/PkiSyncDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/integrations" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/integrations" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers/$subscriberName": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers/$subscriberName": { "filePath": "cert-manager/PkiSubscriberDetailsByIDPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/subscribers" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/subscribers" }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/pam/$projectId/_pam-layout/approval-requests/$approvalRequestId": { "filePath": "pam/ApprovalRequestDetailPage/route.tsx", @@ -7507,25 +7326,25 @@ export const routeTree = rootRoute "filePath": "ssh/SshHostGroupDetailsByIDPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/ssh/$projectId/_ssh-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/groups/$groupId": { "filePath": "project/GroupDetailsByIDPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/identities/$identityId": { "filePath": "project/IdentityDetailsByIDPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/members/$membershipId": { "filePath": "project/MemberDetailsByIDPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/pki-collections/$collectionId": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId": { "filePath": "cert-manager/PkiCollectionDetailsByIDPage/routes.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, - "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug": { + "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout/roles/$roleSlug": { "filePath": "project/RoleDetailsBySlugPage/route-cert-manager.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-management/$projectId/_cert-manager-layout" + "parent": "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/cert-manager/$projectId/_cert-manager-layout" }, "/_authenticate/_inject-org-details/_org-layout/organizations/$orgId/projects/kms/$projectId/_kms-layout/groups/$groupId": { "filePath": "project/GroupDetailsByIDPage/route-kms.tsx", diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index 41d1c319d3..bb32273671 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -272,7 +272,7 @@ const secretManagerIntegrationsRedirect = route("/integrations", [ ) ]); -const certManagerRoutes = route("/organizations/$orgId/projects/cert-management/$projectId", [ +const certManagerRoutes = route("/organizations/$orgId/projects/cert-manager/$projectId", [ layout("cert-manager-layout", "cert-manager/layout.tsx", [ route("/policies", "cert-manager/PoliciesPage/route.tsx"), route("/subscribers", [ diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index ace4852ac1..56fd3e1831 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -52,6 +52,15 @@ export default defineConfig(({ mode }) => { } } }, + experimental: { + renderBuiltUrl(filename, { hostType }) { + if (hostType === "js") { + return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` }; + } + + return { relative: true }; + } + }, plugins: [ tsconfigPaths(), nodePolyfills({ diff --git a/helm-charts/secrets-operator/.helmignore b/helm-charts/secrets-operator/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/helm-charts/secrets-operator/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/helm-charts/secrets-operator/Chart.yaml b/helm-charts/secrets-operator/Chart.yaml deleted file mode 100644 index c0f190104f..0000000000 --- a/helm-charts/secrets-operator/Chart.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: v2 -name: secrets-operator -description: A Helm chart for Infisical secrets -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: v0.10.3 -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "v0.10.3" diff --git a/helm-charts/secrets-operator/README.md b/helm-charts/secrets-operator/README.md deleted file mode 100644 index 688670608a..0000000000 --- a/helm-charts/secrets-operator/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# Infisical Helm Chart - -This is the Infisical Secrets Operator Helm chart. Find the integration documentation [here](https://infisical.com/docs/integrations/platforms/kubernetes) - -## Installation - -To install the chart, run the following : - -```sh -# Add the Infisical repository -helm repo add infisical 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/' && helm repo update - -# Install Infisical Secrets Operator (with default values) -helm upgrade --install --atomic \ - -n infisical-dev --create-namespace \ - infisical-secrets-operator infisical/secrets-operator - -# Install Infisical Secrets Operator (with custom inline values, replace with your own values) -helm upgrade --install --atomic \ - -n infisical-dev --create-namespace \ - --set controllerManager.replicas=3 \ - infisical-secrets-operator infisical/secrets-operator - -# Install Infisical Secrets Operator (with custom values file, replace with your own values file) -helm upgrade --install --atomic \ - -n infisical-dev --create-namespace \ - -f custom-values.yaml \ - infisical-secrets-operator infisical/secrets-operator -``` - -## Synchronization - -To sync your secrets from Infisical (or from your own instance), create the below resources : - -```sh -# Create the tokenSecretReference (replace with your own token) -kubectl create secret generic infisical-example-service-token \ - --from-literal=infisicalToken="" - -# Create the InfisicalSecret -cat < kubectl-install/install-secrets-operator.yaml - - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk command is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -.PHONY: manifests -manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases - -.PHONY: generate -generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - -.PHONY: test -test: manifests generate fmt vet setup-envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out - -# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'. -# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally. -# CertManager is installed by default; skip with: -# - CERT_MANAGER_INSTALL_SKIP=true -KIND_CLUSTER ?= infisical-operator-test-e2e - -.PHONY: setup-test-e2e -setup-test-e2e: ## Set up a Kind cluster for e2e tests if it does not exist - @command -v $(KIND) >/dev/null 2>&1 || { \ - echo "Kind is not installed. Please install Kind manually."; \ - exit 1; \ - } - @case "$$($(KIND) get clusters)" in \ - *"$(KIND_CLUSTER)"*) \ - echo "Kind cluster '$(KIND_CLUSTER)' already exists. Skipping creation." ;; \ - *) \ - echo "Creating Kind cluster '$(KIND_CLUSTER)'..."; \ - $(KIND) create cluster --name $(KIND_CLUSTER) ;; \ - esac - -.PHONY: test-e2e -test-e2e: setup-test-e2e manifests generate fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. - KIND_CLUSTER=$(KIND_CLUSTER) go test ./test/e2e/ -v -ginkgo.v - $(MAKE) cleanup-test-e2e - -.PHONY: cleanup-test-e2e -cleanup-test-e2e: ## Tear down the Kind cluster used for e2e tests - @$(KIND) delete cluster --name $(KIND_CLUSTER) - -.PHONY: lint -lint: golangci-lint ## Run golangci-lint linter - $(GOLANGCI_LINT) run - -.PHONY: lint-fix -lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes - $(GOLANGCI_LINT) run --fix - -.PHONY: lint-config -lint-config: golangci-lint ## Verify golangci-lint linter configuration - $(GOLANGCI_LINT) config verify - -##@ Build - -.PHONY: build -build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager cmd/main.go - -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go - -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name infisical-operator-builder - $(CONTAINER_TOOL) buildx use infisical-operator-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm infisical-operator-builder - rm Dockerfile.cross - -.PHONY: build-installer -build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. - mkdir -p dist - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default > dist/install.yaml - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | $(KUBECTL) apply -f - - -.PHONY: undeploy -undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - - -##@ Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUBECTL ?= kubectl -KIND ?= kind -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest -GOLANGCI_LINT = $(LOCALBIN)/golangci-lint - -## Tool Versions -KUSTOMIZE_VERSION ?= v5.6.0 -CONTROLLER_TOOLS_VERSION ?= v0.18.0 -#ENVTEST_VERSION is the version of controller-runtime release branch to fetch the envtest setup script (i.e. release-0.20) -ENVTEST_VERSION ?= $(shell go list -m -f "{{ .Version }}" sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $$2, $$3}') -#ENVTEST_K8S_VERSION is the version of Kubernetes to use for setting up ENVTEST binaries (i.e. 1.31) -ENVTEST_K8S_VERSION ?= $(shell go list -m -f "{{ .Version }}" k8s.io/api | awk -F'[v.]' '{printf "1.%d", $$3}') -GOLANGCI_LINT_VERSION ?= v2.1.6 - -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. -$(KUSTOMIZE): $(LOCALBIN) - $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. -$(CONTROLLER_GEN): $(LOCALBIN) - $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) - -.PHONY: setup-envtest -setup-envtest: envtest ## Download the binaries required for ENVTEST in the local bin directory. - @echo "Setting up envtest binaries for Kubernetes version $(ENVTEST_K8S_VERSION)..." - @$(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path || { \ - echo "Error: Failed to set up envtest binaries for version $(ENVTEST_K8S_VERSION)."; \ - exit 1; \ - } - -.PHONY: envtest -envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. -$(ENVTEST): $(LOCALBIN) - $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) - -.PHONY: golangci-lint -golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. -$(GOLANGCI_LINT): $(LOCALBIN) - $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) - -# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist -# $1 - target path with name of binary -# $2 - package url which can be installed -# $3 - specific version of package -define go-install-tool -@[ -f "$(1)-$(3)" ] || { \ -set -e; \ -package=$(2)@$(3) ;\ -echo "Downloading $${package}" ;\ -rm -f $(1) || true ;\ -GOBIN=$(LOCALBIN) go install $${package} ;\ -mv $(1) $(1)-$(3) ;\ -} ;\ -ln -sf $(1)-$(3) $(1) -endef diff --git a/k8-operator/PROJECT b/k8-operator/PROJECT deleted file mode 100644 index 5a28e2212e..0000000000 --- a/k8-operator/PROJECT +++ /dev/null @@ -1,39 +0,0 @@ -# Code generated by tool. DO NOT EDIT. -# This file is used to track the info used to scaffold your project -# and allow the plugins properly work. -# More info: https://book.kubebuilder.io/reference/project-config.html -cliVersion: 4.7.0 -domain: infisical.com -layout: -- go.kubebuilder.io/v4 -projectName: k8-operator -repo: github.com/Infisical/infisical/k8-operator -resources: -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: infisical.com - group: secrets - kind: InfisicalSecret - path: github.com/Infisical/infisical/k8-operator/api/v1alpha1 - version: v1alpha1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: infisical.com - group: secrets - kind: InfisicalPushSecret - path: github.com/Infisical/infisical/k8-operator/api/v1alpha1 - version: v1alpha1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: infisical.com - group: secrets - kind: InfisicalDynamicSecret - path: github.com/Infisical/infisical/k8-operator/api/v1alpha1 - version: v1alpha1 -version: "3" diff --git a/k8-operator/README.md b/k8-operator/README.md deleted file mode 100644 index f2e349f07e..0000000000 --- a/k8-operator/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# k8-operator -// TODO - -## Description -// TODO - -## Getting Started -You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. -**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). - -### Running on the cluster -1. Install Instances of Custom Resources: - -```sh -kubectl apply -f config/samples/ -``` - -2. Build and push your image to the location specified by `IMG`: - -```sh -make docker-build docker-push IMG=/k8-operator:tag -``` - -3. Deploy the controller to the cluster with the image specified by `IMG`: - -```sh -make deploy IMG=/k8-operator:tag -``` - -### Uninstall CRDs -To delete the CRDs from the cluster: - -```sh -make uninstall -``` - -### Undeploy controller -UnDeploy the controller to the cluster: - -```sh -make undeploy -``` - -## Contributing -// TODO - -### How it works -This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) - -It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/) -which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster - -### Test It Out -1. Install the CRDs into the cluster: - -```sh -make install -``` - -2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running): - -```sh -make run -``` - -**NOTE:** You can also run this in one step by running: `make install run` - -### Modifying the API definitions -If you are editing the API definitions, generate the manifests such as CRs or CRDs using: - -```sh -make manifests -``` - -Also, after editing the API definitions, update the kubectl-install folder: - -```sh -make kubectl-install -``` - -**NOTE:** Run `make --help` for more information on all potential `make` targets - -More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) - diff --git a/k8-operator/api/v1alpha1/common.go b/k8-operator/api/v1alpha1/common.go deleted file mode 100644 index ce7a3db3be..0000000000 --- a/k8-operator/api/v1alpha1/common.go +++ /dev/null @@ -1,158 +0,0 @@ -package v1alpha1 - -type GenericInfisicalAuthentication struct { - // +kubebuilder:validation:Optional - UniversalAuth GenericUniversalAuth `json:"universalAuth,omitempty"` - // +kubebuilder:validation:Optional - KubernetesAuth GenericKubernetesAuth `json:"kubernetesAuth,omitempty"` - // +kubebuilder:validation:Optional - AwsIamAuth GenericAwsIamAuth `json:"awsIamAuth,omitempty"` - // +kubebuilder:validation:Optional - AzureAuth GenericAzureAuth `json:"azureAuth,omitempty"` - // +kubebuilder:validation:Optional - GcpIdTokenAuth GenericGcpIdTokenAuth `json:"gcpIdTokenAuth,omitempty"` - // +kubebuilder:validation:Optional - GcpIamAuth GenericGcpIamAuth `json:"gcpIamAuth,omitempty"` - // +kubebuilder:validation:Optional - LdapAuth GenericLdapAuth `json:"ldapAuth,omitempty"` -} - -type GenericUniversalAuth struct { - // +kubebuilder:validation:Required - CredentialsRef KubeSecretReference `json:"credentialsRef"` -} - -type GenericLdapAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - CredentialsRef KubeSecretReference `json:"credentialsRef"` -} - -type GenericAwsIamAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` -} - -type GenericAzureAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Optional - Resource string `json:"resource,omitempty"` -} - -type GenericGcpIdTokenAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` -} - -type GenericGcpIamAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - ServiceAccountKeyFilePath string `json:"serviceAccountKeyFilePath"` -} - -type GenericKubernetesAuth struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - ServiceAccountRef KubernetesServiceAccountRef `json:"serviceAccountRef"` - - // Optionally automatically create a service account token for the configured service account. - // If this is set to `true`, the operator will automatically create a service account token for the configured service account. This field is recommended in most cases. - // +kubebuilder:validation:Optional - AutoCreateServiceAccountToken bool `json:"autoCreateServiceAccountToken"` - // The audiences to use for the service account token. This is only relevant if `autoCreateServiceAccountToken` is true. - // +kubebuilder:validation:Optional - ServiceAccountTokenAudiences []string `json:"serviceAccountTokenAudiences"` -} - -type TLSConfig struct { - // Reference to secret containing CA cert - // +kubebuilder:validation:Optional - CaRef CaReference `json:"caRef,omitempty"` -} - -type CaReference struct { - // The name of the Kubernetes Secret - // +kubebuilder:validation:Required - SecretName string `json:"secretName"` - - // The namespace where the Kubernetes Secret is located - // +kubebuilder:validation:Required - SecretNamespace string `json:"secretNamespace"` - - // +kubebuilder:validation:Required - // The name of the secret property with the CA certificate value - SecretKey string `json:"key"` -} - -type KubeSecretReference struct { - // The name of the Kubernetes Secret - // +kubebuilder:validation:Required - SecretName string `json:"secretName"` - - // The name space where the Kubernetes Secret is located - // +kubebuilder:validation:Required - SecretNamespace string `json:"secretNamespace"` -} - -type ManagedKubeSecretConfig struct { - // The name of the Kubernetes Secret - // +kubebuilder:validation:Required - SecretName string `json:"secretName"` - - // The name space where the Kubernetes Secret is located - // +kubebuilder:validation:Required - SecretNamespace string `json:"secretNamespace"` - - // The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types - // +kubebuilder:validation:Optional - // +kubebuilder:default:=Opaque - SecretType string `json:"secretType"` - - // The Kubernetes Secret creation policy. - // Enum with values: 'Owner', 'Orphan'. - // Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - // Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted. - // +kubebuilder:validation:Optional - // +kubebuilder:default:=Orphan - CreationPolicy string `json:"creationPolicy"` - - // The template to transform the secret data - // +kubebuilder:validation:Optional - Template *SecretTemplate `json:"template,omitempty"` -} - -type ManagedKubeConfigMapConfig struct { - // The name of the Kubernetes ConfigMap - // +kubebuilder:validation:Required - ConfigMapName string `json:"configMapName"` - - // The Kubernetes ConfigMap creation policy. - // Enum with values: 'Owner', 'Orphan'. - // Owner creates the config map and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - // Orphan will not set the config map owner. This will result in the config map being orphaned and not deleted when the resource is deleted. - // +kubebuilder:validation:Optional - // +kubebuilder:default:=Orphan - CreationPolicy string `json:"creationPolicy"` - - // The namespace where the Kubernetes ConfigMap is located - // +kubebuilder:validation:Required - ConfigMapNamespace string `json:"configMapNamespace"` - - // The template to transform the secret data - // +kubebuilder:validation:Optional - Template *SecretTemplate `json:"template,omitempty"` -} - -type SecretTemplate struct { - // This injects all retrieved secrets into the top level of your template. - // Secrets defined in the template will take precedence over the injected ones. - // +kubebuilder:validation:Optional - IncludeAllSecrets bool `json:"includeAllSecrets"` - // The template key values - // +kubebuilder:validation:Optional - Data map[string]string `json:"data,omitempty"` -} diff --git a/k8-operator/api/v1alpha1/generators.go b/k8-operator/api/v1alpha1/generators.go deleted file mode 100644 index 0f6d86c2dd..0000000000 --- a/k8-operator/api/v1alpha1/generators.go +++ /dev/null @@ -1,152 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// GeneratorKind represents a kind of generator. -// +kubebuilder:validation:Enum=Password;UUID -type GeneratorKind string - -const ( - GeneratorKindPassword GeneratorKind = "Password" - GeneratorKindUUID GeneratorKind = "UUID" -) - -type ClusterGeneratorSpec struct { - // Kind the kind of this generator. - Kind GeneratorKind `json:"kind"` - - // Generator the spec for this generator, must match the kind. - Generator GeneratorSpec `json:"generator,omitempty"` -} - -type GeneratorSpec struct { - // +kubebuilder:validation:Optional - PasswordSpec *PasswordSpec `json:"passwordSpec,omitempty"` - // +kubebuilder:validation:Optional - UUIDSpec *UUIDSpec `json:"uuidSpec,omitempty"` -} - -// ClusterGenerator represents a cluster-wide generator -// +kubebuilder:object:root=true -// +kubebuilder:storageversion -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Cluster -type ClusterGenerator struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec ClusterGeneratorSpec `json:"spec,omitempty"` -} - -// +kubebuilder:object:root=true - -// ClusterGeneratorList contains a list of ClusterGenerator resources. -type ClusterGeneratorList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ClusterGenerator `json:"items"` -} - -// ! UUID Generator - -// UUIDSpec controls the behavior of the uuid generator. -type UUIDSpec struct{} - -// UUID generates a version 4 UUID (e56657e3-764f-11ef-a397-65231a88c216). -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -type UUID struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec UUIDSpec `json:"spec,omitempty"` -} - -// +kubebuilder:object:root=true - -// UUIDList contains a list of UUID resources. -type UUIDList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []UUID `json:"items"` -} - -// ! Password Generator - -// PasswordSpec controls the behavior of the password generator. -type PasswordSpec struct { - // Length of the password to be generated. - // Defaults to 24 - // +kubebuilder:validation:Optional - // +kubebuilder:default=24 - Length int `json:"length"` - - // digits specifies the number of digits in the generated - // password. If omitted it defaults to 25% of the length of the password - Digits *int `json:"digits,omitempty"` - - // symbols specifies the number of symbol characters in the generated - // password. If omitted it defaults to 25% of the length of the password - Symbols *int `json:"symbols,omitempty"` - - // symbolCharacters specifies the special characters that should be used - // in the generated password. - SymbolCharacters *string `json:"symbolCharacters,omitempty"` - - // Set noUpper to disable uppercase characters - // +kubebuilder:validation:Optional - // +kubebuilder:default=false - NoUpper bool `json:"noUpper"` - - // set allowRepeat to true to allow repeating characters. - // +kubebuilder:validation:Optional - // +kubebuilder:default=false - AllowRepeat bool `json:"allowRepeat"` -} - -// Password generates a random password based on the -// configuration parameters in spec. -// You can specify the length, characterset and other attributes. -// +kubebuilder:object:root=true -// +kubebuilder:storageversion -// +kubebuilder:subresource:status -// +kubebuilder:resource:scope=Namespaced -type Password struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec PasswordSpec `json:"spec,omitempty"` -} - -// +kubebuilder:object:root=true - -// PasswordList contains a list of Password resources. -type PasswordList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Password `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Password{}, &PasswordList{}) - SchemeBuilder.Register(&UUID{}, &UUIDList{}) - SchemeBuilder.Register(&ClusterGenerator{}, &ClusterGeneratorList{}) -} diff --git a/k8-operator/api/v1alpha1/groupversion_info.go b/k8-operator/api/v1alpha1/groupversion_info.go deleted file mode 100644 index 36ebd80ce7..0000000000 --- a/k8-operator/api/v1alpha1/groupversion_info.go +++ /dev/null @@ -1,20 +0,0 @@ -// Package v1alpha1 contains API Schema definitions for the secrets v1alpha1 API group -// +kubebuilder:object:generate=true -// +groupName=secrets.infisical.com -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "secrets.infisical.com", Version: "v1alpha1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/k8-operator/api/v1alpha1/infisicaldynamicsecret_types.go b/k8-operator/api/v1alpha1/infisicaldynamicsecret_types.go deleted file mode 100644 index a55e215a35..0000000000 --- a/k8-operator/api/v1alpha1/infisicaldynamicsecret_types.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type InfisicalDynamicSecretLease struct { - ID string `json:"id"` - Version int64 `json:"version"` - CreationTimestamp metav1.Time `json:"creationTimestamp"` - ExpiresAt metav1.Time `json:"expiresAt"` -} - -type DynamicSecretDetails struct { - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - SecretName string `json:"secretName"` - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - SecretPath string `json:"secretsPath"` - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - EnvironmentSlug string `json:"environmentSlug"` - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - ProjectID string `json:"projectId"` -} - -// InfisicalDynamicSecretSpec defines the desired state of InfisicalDynamicSecret. -type InfisicalDynamicSecretSpec struct { - // +kubebuilder:validation:Required - ManagedSecretReference ManagedKubeSecretConfig `json:"managedSecretReference"` // The destination to store the lease in. - - // +kubebuilder:validation:Required - Authentication GenericInfisicalAuthentication `json:"authentication"` // The authentication to use for authenticating with Infisical. - - // +kubebuilder:validation:Required - DynamicSecret DynamicSecretDetails `json:"dynamicSecret"` // The dynamic secret to create the lease for. Required. - - LeaseRevocationPolicy string `json:"leaseRevocationPolicy"` // Revoke will revoke the lease when the resource is deleted. Optional, will default to no revocation. - LeaseTTL string `json:"leaseTTL"` // The TTL of the lease in seconds. Optional, will default to the dynamic secret default TTL. - - // +kubebuilder:validation:Optional - HostAPI string `json:"hostAPI"` - - // +kubebuilder:validation:Optional - TLS TLSConfig `json:"tls"` -} - -// InfisicalDynamicSecretStatus defines the observed state of InfisicalDynamicSecret. -type InfisicalDynamicSecretStatus struct { - Conditions []metav1.Condition `json:"conditions"` - - Lease *InfisicalDynamicSecretLease `json:"lease,omitempty"` - DynamicSecretID string `json:"dynamicSecretId,omitempty"` - // The MaxTTL can be null, if it's null, there's no max TTL and we should never have to renew. - MaxTTL string `json:"maxTTL,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status - -// InfisicalDynamicSecret is the Schema for the infisicaldynamicsecrets API. -type InfisicalDynamicSecret struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec InfisicalDynamicSecretSpec `json:"spec,omitempty"` - Status InfisicalDynamicSecretStatus `json:"status,omitempty"` -} - -// +kubebuilder:object:root=true - -// InfisicalDynamicSecretList contains a list of InfisicalDynamicSecret. -type InfisicalDynamicSecretList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []InfisicalDynamicSecret `json:"items"` -} - -func init() { - SchemeBuilder.Register(&InfisicalDynamicSecret{}, &InfisicalDynamicSecretList{}) -} diff --git a/k8-operator/api/v1alpha1/infisicalpushsecret_types.go b/k8-operator/api/v1alpha1/infisicalpushsecret_types.go deleted file mode 100644 index f1905c1307..0000000000 --- a/k8-operator/api/v1alpha1/infisicalpushsecret_types.go +++ /dev/null @@ -1,115 +0,0 @@ -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type InfisicalPushSecretDestination struct { - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - SecretsPath string `json:"secretsPath"` - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - EnvironmentSlug string `json:"environmentSlug"` - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - ProjectID string `json:"projectId"` -} - -type InfisicalPushSecretSource struct { - // The name of the Kubernetes Secret - // +kubebuilder:validation:Required - SecretName string `json:"secretName"` - - // The name space where the Kubernetes Secret is located - // +kubebuilder:validation:Required - SecretNamespace string `json:"secretNamespace"` - - // +kubebuilder:validation:Optional - Template *SecretTemplate `json:"template,omitempty"` -} - -type GeneratorRef struct { - // Specify the Kind of the generator resource - // +kubebuilder:validation:Enum=Password;UUID - // +kubebuilder:validation:Required - Kind GeneratorKind `json:"kind"` - - // +kubebuilder:validation:Required - Name string `json:"name"` -} - -type SecretPushGenerator struct { - // +kubebuilder:validation:Required - DestinationSecretName string `json:"destinationSecretName"` - // +kubebuilder:validation:Required - GeneratorRef GeneratorRef `json:"generatorRef"` -} - -type SecretPush struct { - // +kubebuilder:validation:Optional - Secret *InfisicalPushSecretSource `json:"secret,omitempty"` - // +kubebuilder:validation:Optional - Generators []SecretPushGenerator `json:"generators,omitempty"` -} - -// InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret -type InfisicalPushSecretSpec struct { - // +kubebuilder:validation:Optional - UpdatePolicy string `json:"updatePolicy"` - - // +kubebuilder:validation:Optional - DeletionPolicy string `json:"deletionPolicy"` - - // +kubebuilder:validation:Required - // +kubebuilder:validation:Immutable - Destination InfisicalPushSecretDestination `json:"destination"` - - // +kubebuilder:validation:Optional - Authentication GenericInfisicalAuthentication `json:"authentication"` - - // +kubebuilder:validation:Required - Push SecretPush `json:"push"` - - // +kubebuilder:validation:Optional - ResyncInterval *string `json:"resyncInterval,omitempty"` - - // Infisical host to pull secrets from - // +kubebuilder:validation:Optional - HostAPI string `json:"hostAPI"` - - // +kubebuilder:validation:Optional - TLS TLSConfig `json:"tls"` -} - -// InfisicalPushSecretStatus defines the observed state of InfisicalPushSecret -type InfisicalPushSecretStatus struct { - Conditions []metav1.Condition `json:"conditions"` - - // managed secrets is a map where the key is the ID, and the value is the secret key (string[id], string[key] ) - ManagedSecrets map[string]string `json:"managedSecrets"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// InfisicalPushSecret is the Schema for the infisicalpushsecrets API -type InfisicalPushSecret struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec InfisicalPushSecretSpec `json:"spec,omitempty"` - Status InfisicalPushSecretStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// InfisicalPushSecretList contains a list of InfisicalPushSecret -type InfisicalPushSecretList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []InfisicalPushSecret `json:"items"` -} - -func init() { - SchemeBuilder.Register(&InfisicalPushSecret{}, &InfisicalPushSecretList{}) -} diff --git a/k8-operator/api/v1alpha1/infisicalsecret_types.go b/k8-operator/api/v1alpha1/infisicalsecret_types.go deleted file mode 100644 index 796c97265b..0000000000 --- a/k8-operator/api/v1alpha1/infisicalsecret_types.go +++ /dev/null @@ -1,196 +0,0 @@ -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type Authentication struct { - // +kubebuilder:validation:Optional - ServiceAccount ServiceAccountDetails `json:"serviceAccount"` - // +kubebuilder:validation:Optional - ServiceToken ServiceTokenDetails `json:"serviceToken"` - // +kubebuilder:validation:Optional - UniversalAuth UniversalAuthDetails `json:"universalAuth"` - // +kubebuilder:validation:Optional - KubernetesAuth KubernetesAuthDetails `json:"kubernetesAuth"` - // +kubebuilder:validation:Optional - AwsIamAuth AWSIamAuthDetails `json:"awsIamAuth"` - // +kubebuilder:validation:Optional - AzureAuth AzureAuthDetails `json:"azureAuth"` - // +kubebuilder:validation:Optional - GcpIdTokenAuth GCPIdTokenAuthDetails `json:"gcpIdTokenAuth"` - // +kubebuilder:validation:Optional - GcpIamAuth GcpIamAuthDetails `json:"gcpIamAuth"` - // +kubebuilder:validation:Optional - LdapAuth LdapAuthDetails `json:"ldapAuth"` -} - -type UniversalAuthDetails struct { - // +kubebuilder:validation:Required - CredentialsRef KubeSecretReference `json:"credentialsRef"` - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type LdapAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - CredentialsRef KubeSecretReference `json:"credentialsRef"` - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type KubernetesAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - ServiceAccountRef KubernetesServiceAccountRef `json:"serviceAccountRef"` - - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` - - // Optionally automatically create a service account token for the configured service account. - // If this is set to `true`, the operator will automatically create a service account token for the configured service account. - // +kubebuilder:validation:Optional - AutoCreateServiceAccountToken bool `json:"autoCreateServiceAccountToken"` - // The audiences to use for the service account token. This is only relevant if `autoCreateServiceAccountToken` is true. - // +kubebuilder:validation:Optional - ServiceAccountTokenAudiences []string `json:"serviceAccountTokenAudiences"` -} - -type KubernetesServiceAccountRef struct { - // +kubebuilder:validation:Required - Name string `json:"name"` - // +kubebuilder:validation:Required - Namespace string `json:"namespace"` -} - -type AWSIamAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type AzureAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Optional - Resource string `json:"resource"` - - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type GCPIdTokenAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type GcpIamAuthDetails struct { - // +kubebuilder:validation:Required - IdentityID string `json:"identityId"` - // +kubebuilder:validation:Required - ServiceAccountKeyFilePath string `json:"serviceAccountKeyFilePath"` - - // +kubebuilder:validation:Required - SecretsScope MachineIdentityScopeInWorkspace `json:"secretsScope"` -} - -type ServiceTokenDetails struct { - // +kubebuilder:validation:Required - ServiceTokenSecretReference KubeSecretReference `json:"serviceTokenSecretReference"` - // +kubebuilder:validation:Required - SecretsScope SecretScopeInWorkspace `json:"secretsScope"` -} - -type ServiceAccountDetails struct { - ServiceAccountSecretReference KubeSecretReference `json:"serviceAccountSecretReference"` - ProjectId string `json:"projectId"` - EnvironmentName string `json:"environmentName"` -} - -type SecretScopeInWorkspace struct { - // +kubebuilder:validation:Required - SecretsPath string `json:"secretsPath"` - // +kubebuilder:validation:Required - EnvSlug string `json:"envSlug"` - // +kubebuilder:validation:Optional - Recursive bool `json:"recursive"` -} - -type MachineIdentityScopeInWorkspace struct { - // +kubebuilder:validation:Required - SecretsPath string `json:"secretsPath"` - // +kubebuilder:validation:Required - EnvSlug string `json:"envSlug"` - // +kubebuilder:validation:Required - ProjectSlug string `json:"projectSlug"` - // +kubebuilder:validation:Optional - Recursive bool `json:"recursive"` -} - -// InfisicalSecretSpec defines the desired state of InfisicalSecret -type InfisicalSecretSpec struct { - // +kubebuilder:validation:Optional - TokenSecretReference KubeSecretReference `json:"tokenSecretReference"` - - // +kubebuilder:validation:Optional - Authentication Authentication `json:"authentication"` - - // +kubebuilder:validation:Optional - ManagedSecretReference ManagedKubeSecretConfig `json:"managedSecretReference"` - - // +kubebuilder:validation:Optional - ManagedKubeSecretReferences []ManagedKubeSecretConfig `json:"managedKubeSecretReferences"` - // +kubebuilder:validation:Optional - ManagedKubeConfigMapReferences []ManagedKubeConfigMapConfig `json:"managedKubeConfigMapReferences"` - - // +kubebuilder:default:=60 - ResyncInterval int `json:"resyncInterval"` - - // Infisical host to pull secrets from - // +kubebuilder:validation:Optional - HostAPI string `json:"hostAPI"` - - // +kubebuilder:validation:Optional - TLS TLSConfig `json:"tls"` - - // +kubebuilder:validation:Optional - InstantUpdates bool `json:"instantUpdates"` -} - -// InfisicalSecretStatus defines the observed state of InfisicalSecret -type InfisicalSecretStatus struct { - Conditions []metav1.Condition `json:"conditions"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// InfisicalSecret is the Schema for the infisicalsecrets API -type InfisicalSecret struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec InfisicalSecretSpec `json:"spec,omitempty"` - Status InfisicalSecretStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// InfisicalSecretList contains a list of InfisicalSecret -type InfisicalSecretList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []InfisicalSecret `json:"items"` -} - -func init() { - SchemeBuilder.Register(&InfisicalSecret{}, &InfisicalSecretList{}) -} diff --git a/k8-operator/api/v1alpha1/zz_generated.deepcopy.go b/k8-operator/api/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index 02bb65b5bd..0000000000 --- a/k8-operator/api/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,1205 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AWSIamAuthDetails) DeepCopyInto(out *AWSIamAuthDetails) { - *out = *in - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSIamAuthDetails. -func (in *AWSIamAuthDetails) DeepCopy() *AWSIamAuthDetails { - if in == nil { - return nil - } - out := new(AWSIamAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Authentication) DeepCopyInto(out *Authentication) { - *out = *in - out.ServiceAccount = in.ServiceAccount - out.ServiceToken = in.ServiceToken - out.UniversalAuth = in.UniversalAuth - in.KubernetesAuth.DeepCopyInto(&out.KubernetesAuth) - out.AwsIamAuth = in.AwsIamAuth - out.AzureAuth = in.AzureAuth - out.GcpIdTokenAuth = in.GcpIdTokenAuth - out.GcpIamAuth = in.GcpIamAuth - out.LdapAuth = in.LdapAuth -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Authentication. -func (in *Authentication) DeepCopy() *Authentication { - if in == nil { - return nil - } - out := new(Authentication) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AzureAuthDetails) DeepCopyInto(out *AzureAuthDetails) { - *out = *in - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureAuthDetails. -func (in *AzureAuthDetails) DeepCopy() *AzureAuthDetails { - if in == nil { - return nil - } - out := new(AzureAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CaReference) DeepCopyInto(out *CaReference) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaReference. -func (in *CaReference) DeepCopy() *CaReference { - if in == nil { - return nil - } - out := new(CaReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterGenerator) DeepCopyInto(out *ClusterGenerator) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGenerator. -func (in *ClusterGenerator) DeepCopy() *ClusterGenerator { - if in == nil { - return nil - } - out := new(ClusterGenerator) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterGenerator) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterGeneratorList) DeepCopyInto(out *ClusterGeneratorList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ClusterGenerator, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGeneratorList. -func (in *ClusterGeneratorList) DeepCopy() *ClusterGeneratorList { - if in == nil { - return nil - } - out := new(ClusterGeneratorList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterGeneratorList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterGeneratorSpec) DeepCopyInto(out *ClusterGeneratorSpec) { - *out = *in - in.Generator.DeepCopyInto(&out.Generator) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterGeneratorSpec. -func (in *ClusterGeneratorSpec) DeepCopy() *ClusterGeneratorSpec { - if in == nil { - return nil - } - out := new(ClusterGeneratorSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DynamicSecretDetails) DeepCopyInto(out *DynamicSecretDetails) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicSecretDetails. -func (in *DynamicSecretDetails) DeepCopy() *DynamicSecretDetails { - if in == nil { - return nil - } - out := new(DynamicSecretDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GCPIdTokenAuthDetails) DeepCopyInto(out *GCPIdTokenAuthDetails) { - *out = *in - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GCPIdTokenAuthDetails. -func (in *GCPIdTokenAuthDetails) DeepCopy() *GCPIdTokenAuthDetails { - if in == nil { - return nil - } - out := new(GCPIdTokenAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GcpIamAuthDetails) DeepCopyInto(out *GcpIamAuthDetails) { - *out = *in - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GcpIamAuthDetails. -func (in *GcpIamAuthDetails) DeepCopy() *GcpIamAuthDetails { - if in == nil { - return nil - } - out := new(GcpIamAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GeneratorRef) DeepCopyInto(out *GeneratorRef) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratorRef. -func (in *GeneratorRef) DeepCopy() *GeneratorRef { - if in == nil { - return nil - } - out := new(GeneratorRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GeneratorSpec) DeepCopyInto(out *GeneratorSpec) { - *out = *in - if in.PasswordSpec != nil { - in, out := &in.PasswordSpec, &out.PasswordSpec - *out = new(PasswordSpec) - (*in).DeepCopyInto(*out) - } - if in.UUIDSpec != nil { - in, out := &in.UUIDSpec, &out.UUIDSpec - *out = new(UUIDSpec) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneratorSpec. -func (in *GeneratorSpec) DeepCopy() *GeneratorSpec { - if in == nil { - return nil - } - out := new(GeneratorSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericAwsIamAuth) DeepCopyInto(out *GenericAwsIamAuth) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericAwsIamAuth. -func (in *GenericAwsIamAuth) DeepCopy() *GenericAwsIamAuth { - if in == nil { - return nil - } - out := new(GenericAwsIamAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericAzureAuth) DeepCopyInto(out *GenericAzureAuth) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericAzureAuth. -func (in *GenericAzureAuth) DeepCopy() *GenericAzureAuth { - if in == nil { - return nil - } - out := new(GenericAzureAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericGcpIamAuth) DeepCopyInto(out *GenericGcpIamAuth) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericGcpIamAuth. -func (in *GenericGcpIamAuth) DeepCopy() *GenericGcpIamAuth { - if in == nil { - return nil - } - out := new(GenericGcpIamAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericGcpIdTokenAuth) DeepCopyInto(out *GenericGcpIdTokenAuth) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericGcpIdTokenAuth. -func (in *GenericGcpIdTokenAuth) DeepCopy() *GenericGcpIdTokenAuth { - if in == nil { - return nil - } - out := new(GenericGcpIdTokenAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericInfisicalAuthentication) DeepCopyInto(out *GenericInfisicalAuthentication) { - *out = *in - out.UniversalAuth = in.UniversalAuth - in.KubernetesAuth.DeepCopyInto(&out.KubernetesAuth) - out.AwsIamAuth = in.AwsIamAuth - out.AzureAuth = in.AzureAuth - out.GcpIdTokenAuth = in.GcpIdTokenAuth - out.GcpIamAuth = in.GcpIamAuth - out.LdapAuth = in.LdapAuth -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericInfisicalAuthentication. -func (in *GenericInfisicalAuthentication) DeepCopy() *GenericInfisicalAuthentication { - if in == nil { - return nil - } - out := new(GenericInfisicalAuthentication) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericKubernetesAuth) DeepCopyInto(out *GenericKubernetesAuth) { - *out = *in - out.ServiceAccountRef = in.ServiceAccountRef - if in.ServiceAccountTokenAudiences != nil { - in, out := &in.ServiceAccountTokenAudiences, &out.ServiceAccountTokenAudiences - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericKubernetesAuth. -func (in *GenericKubernetesAuth) DeepCopy() *GenericKubernetesAuth { - if in == nil { - return nil - } - out := new(GenericKubernetesAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericLdapAuth) DeepCopyInto(out *GenericLdapAuth) { - *out = *in - out.CredentialsRef = in.CredentialsRef -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericLdapAuth. -func (in *GenericLdapAuth) DeepCopy() *GenericLdapAuth { - if in == nil { - return nil - } - out := new(GenericLdapAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GenericUniversalAuth) DeepCopyInto(out *GenericUniversalAuth) { - *out = *in - out.CredentialsRef = in.CredentialsRef -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericUniversalAuth. -func (in *GenericUniversalAuth) DeepCopy() *GenericUniversalAuth { - if in == nil { - return nil - } - out := new(GenericUniversalAuth) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalDynamicSecret) DeepCopyInto(out *InfisicalDynamicSecret) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalDynamicSecret. -func (in *InfisicalDynamicSecret) DeepCopy() *InfisicalDynamicSecret { - if in == nil { - return nil - } - out := new(InfisicalDynamicSecret) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalDynamicSecret) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalDynamicSecretLease) DeepCopyInto(out *InfisicalDynamicSecretLease) { - *out = *in - in.CreationTimestamp.DeepCopyInto(&out.CreationTimestamp) - in.ExpiresAt.DeepCopyInto(&out.ExpiresAt) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalDynamicSecretLease. -func (in *InfisicalDynamicSecretLease) DeepCopy() *InfisicalDynamicSecretLease { - if in == nil { - return nil - } - out := new(InfisicalDynamicSecretLease) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalDynamicSecretList) DeepCopyInto(out *InfisicalDynamicSecretList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]InfisicalDynamicSecret, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalDynamicSecretList. -func (in *InfisicalDynamicSecretList) DeepCopy() *InfisicalDynamicSecretList { - if in == nil { - return nil - } - out := new(InfisicalDynamicSecretList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalDynamicSecretList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalDynamicSecretSpec) DeepCopyInto(out *InfisicalDynamicSecretSpec) { - *out = *in - in.ManagedSecretReference.DeepCopyInto(&out.ManagedSecretReference) - in.Authentication.DeepCopyInto(&out.Authentication) - out.DynamicSecret = in.DynamicSecret - out.TLS = in.TLS -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalDynamicSecretSpec. -func (in *InfisicalDynamicSecretSpec) DeepCopy() *InfisicalDynamicSecretSpec { - if in == nil { - return nil - } - out := new(InfisicalDynamicSecretSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalDynamicSecretStatus) DeepCopyInto(out *InfisicalDynamicSecretStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Lease != nil { - in, out := &in.Lease, &out.Lease - *out = new(InfisicalDynamicSecretLease) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalDynamicSecretStatus. -func (in *InfisicalDynamicSecretStatus) DeepCopy() *InfisicalDynamicSecretStatus { - if in == nil { - return nil - } - out := new(InfisicalDynamicSecretStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecret) DeepCopyInto(out *InfisicalPushSecret) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecret. -func (in *InfisicalPushSecret) DeepCopy() *InfisicalPushSecret { - if in == nil { - return nil - } - out := new(InfisicalPushSecret) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalPushSecret) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecretDestination) DeepCopyInto(out *InfisicalPushSecretDestination) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretDestination. -func (in *InfisicalPushSecretDestination) DeepCopy() *InfisicalPushSecretDestination { - if in == nil { - return nil - } - out := new(InfisicalPushSecretDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecretList) DeepCopyInto(out *InfisicalPushSecretList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]InfisicalPushSecret, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretList. -func (in *InfisicalPushSecretList) DeepCopy() *InfisicalPushSecretList { - if in == nil { - return nil - } - out := new(InfisicalPushSecretList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalPushSecretList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecretSource) DeepCopyInto(out *InfisicalPushSecretSource) { - *out = *in - if in.Template != nil { - in, out := &in.Template, &out.Template - *out = new(SecretTemplate) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretSource. -func (in *InfisicalPushSecretSource) DeepCopy() *InfisicalPushSecretSource { - if in == nil { - return nil - } - out := new(InfisicalPushSecretSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecretSpec) DeepCopyInto(out *InfisicalPushSecretSpec) { - *out = *in - out.Destination = in.Destination - in.Authentication.DeepCopyInto(&out.Authentication) - in.Push.DeepCopyInto(&out.Push) - if in.ResyncInterval != nil { - in, out := &in.ResyncInterval, &out.ResyncInterval - *out = new(string) - **out = **in - } - out.TLS = in.TLS -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretSpec. -func (in *InfisicalPushSecretSpec) DeepCopy() *InfisicalPushSecretSpec { - if in == nil { - return nil - } - out := new(InfisicalPushSecretSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalPushSecretStatus) DeepCopyInto(out *InfisicalPushSecretStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.ManagedSecrets != nil { - in, out := &in.ManagedSecrets, &out.ManagedSecrets - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalPushSecretStatus. -func (in *InfisicalPushSecretStatus) DeepCopy() *InfisicalPushSecretStatus { - if in == nil { - return nil - } - out := new(InfisicalPushSecretStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalSecret) DeepCopyInto(out *InfisicalSecret) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecret. -func (in *InfisicalSecret) DeepCopy() *InfisicalSecret { - if in == nil { - return nil - } - out := new(InfisicalSecret) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalSecret) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalSecretList) DeepCopyInto(out *InfisicalSecretList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]InfisicalSecret, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretList. -func (in *InfisicalSecretList) DeepCopy() *InfisicalSecretList { - if in == nil { - return nil - } - out := new(InfisicalSecretList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InfisicalSecretList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalSecretSpec) DeepCopyInto(out *InfisicalSecretSpec) { - *out = *in - out.TokenSecretReference = in.TokenSecretReference - in.Authentication.DeepCopyInto(&out.Authentication) - in.ManagedSecretReference.DeepCopyInto(&out.ManagedSecretReference) - if in.ManagedKubeSecretReferences != nil { - in, out := &in.ManagedKubeSecretReferences, &out.ManagedKubeSecretReferences - *out = make([]ManagedKubeSecretConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.ManagedKubeConfigMapReferences != nil { - in, out := &in.ManagedKubeConfigMapReferences, &out.ManagedKubeConfigMapReferences - *out = make([]ManagedKubeConfigMapConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - out.TLS = in.TLS -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretSpec. -func (in *InfisicalSecretSpec) DeepCopy() *InfisicalSecretSpec { - if in == nil { - return nil - } - out := new(InfisicalSecretSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InfisicalSecretStatus) DeepCopyInto(out *InfisicalSecretStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalSecretStatus. -func (in *InfisicalSecretStatus) DeepCopy() *InfisicalSecretStatus { - if in == nil { - return nil - } - out := new(InfisicalSecretStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeSecretReference) DeepCopyInto(out *KubeSecretReference) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSecretReference. -func (in *KubeSecretReference) DeepCopy() *KubeSecretReference { - if in == nil { - return nil - } - out := new(KubeSecretReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubernetesAuthDetails) DeepCopyInto(out *KubernetesAuthDetails) { - *out = *in - out.ServiceAccountRef = in.ServiceAccountRef - out.SecretsScope = in.SecretsScope - if in.ServiceAccountTokenAudiences != nil { - in, out := &in.ServiceAccountTokenAudiences, &out.ServiceAccountTokenAudiences - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesAuthDetails. -func (in *KubernetesAuthDetails) DeepCopy() *KubernetesAuthDetails { - if in == nil { - return nil - } - out := new(KubernetesAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubernetesServiceAccountRef) DeepCopyInto(out *KubernetesServiceAccountRef) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesServiceAccountRef. -func (in *KubernetesServiceAccountRef) DeepCopy() *KubernetesServiceAccountRef { - if in == nil { - return nil - } - out := new(KubernetesServiceAccountRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LdapAuthDetails) DeepCopyInto(out *LdapAuthDetails) { - *out = *in - out.CredentialsRef = in.CredentialsRef - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapAuthDetails. -func (in *LdapAuthDetails) DeepCopy() *LdapAuthDetails { - if in == nil { - return nil - } - out := new(LdapAuthDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MachineIdentityScopeInWorkspace) DeepCopyInto(out *MachineIdentityScopeInWorkspace) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineIdentityScopeInWorkspace. -func (in *MachineIdentityScopeInWorkspace) DeepCopy() *MachineIdentityScopeInWorkspace { - if in == nil { - return nil - } - out := new(MachineIdentityScopeInWorkspace) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ManagedKubeConfigMapConfig) DeepCopyInto(out *ManagedKubeConfigMapConfig) { - *out = *in - if in.Template != nil { - in, out := &in.Template, &out.Template - *out = new(SecretTemplate) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedKubeConfigMapConfig. -func (in *ManagedKubeConfigMapConfig) DeepCopy() *ManagedKubeConfigMapConfig { - if in == nil { - return nil - } - out := new(ManagedKubeConfigMapConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ManagedKubeSecretConfig) DeepCopyInto(out *ManagedKubeSecretConfig) { - *out = *in - if in.Template != nil { - in, out := &in.Template, &out.Template - *out = new(SecretTemplate) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedKubeSecretConfig. -func (in *ManagedKubeSecretConfig) DeepCopy() *ManagedKubeSecretConfig { - if in == nil { - return nil - } - out := new(ManagedKubeSecretConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Password) DeepCopyInto(out *Password) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Password. -func (in *Password) DeepCopy() *Password { - if in == nil { - return nil - } - out := new(Password) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Password) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PasswordList) DeepCopyInto(out *PasswordList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Password, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordList. -func (in *PasswordList) DeepCopy() *PasswordList { - if in == nil { - return nil - } - out := new(PasswordList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PasswordList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PasswordSpec) DeepCopyInto(out *PasswordSpec) { - *out = *in - if in.Digits != nil { - in, out := &in.Digits, &out.Digits - *out = new(int) - **out = **in - } - if in.Symbols != nil { - in, out := &in.Symbols, &out.Symbols - *out = new(int) - **out = **in - } - if in.SymbolCharacters != nil { - in, out := &in.SymbolCharacters, &out.SymbolCharacters - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PasswordSpec. -func (in *PasswordSpec) DeepCopy() *PasswordSpec { - if in == nil { - return nil - } - out := new(PasswordSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretPush) DeepCopyInto(out *SecretPush) { - *out = *in - if in.Secret != nil { - in, out := &in.Secret, &out.Secret - *out = new(InfisicalPushSecretSource) - (*in).DeepCopyInto(*out) - } - if in.Generators != nil { - in, out := &in.Generators, &out.Generators - *out = make([]SecretPushGenerator, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPush. -func (in *SecretPush) DeepCopy() *SecretPush { - if in == nil { - return nil - } - out := new(SecretPush) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretPushGenerator) DeepCopyInto(out *SecretPushGenerator) { - *out = *in - out.GeneratorRef = in.GeneratorRef -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretPushGenerator. -func (in *SecretPushGenerator) DeepCopy() *SecretPushGenerator { - if in == nil { - return nil - } - out := new(SecretPushGenerator) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretScopeInWorkspace) DeepCopyInto(out *SecretScopeInWorkspace) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretScopeInWorkspace. -func (in *SecretScopeInWorkspace) DeepCopy() *SecretScopeInWorkspace { - if in == nil { - return nil - } - out := new(SecretScopeInWorkspace) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretTemplate) DeepCopyInto(out *SecretTemplate) { - *out = *in - if in.Data != nil { - in, out := &in.Data, &out.Data - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretTemplate. -func (in *SecretTemplate) DeepCopy() *SecretTemplate { - if in == nil { - return nil - } - out := new(SecretTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceAccountDetails) DeepCopyInto(out *ServiceAccountDetails) { - *out = *in - out.ServiceAccountSecretReference = in.ServiceAccountSecretReference -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountDetails. -func (in *ServiceAccountDetails) DeepCopy() *ServiceAccountDetails { - if in == nil { - return nil - } - out := new(ServiceAccountDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceTokenDetails) DeepCopyInto(out *ServiceTokenDetails) { - *out = *in - out.ServiceTokenSecretReference = in.ServiceTokenSecretReference - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceTokenDetails. -func (in *ServiceTokenDetails) DeepCopy() *ServiceTokenDetails { - if in == nil { - return nil - } - out := new(ServiceTokenDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { - *out = *in - out.CaRef = in.CaRef -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. -func (in *TLSConfig) DeepCopy() *TLSConfig { - if in == nil { - return nil - } - out := new(TLSConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UUID) DeepCopyInto(out *UUID) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUID. -func (in *UUID) DeepCopy() *UUID { - if in == nil { - return nil - } - out := new(UUID) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *UUID) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UUIDList) DeepCopyInto(out *UUIDList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]UUID, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUIDList. -func (in *UUIDList) DeepCopy() *UUIDList { - if in == nil { - return nil - } - out := new(UUIDList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *UUIDList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UUIDSpec) DeepCopyInto(out *UUIDSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UUIDSpec. -func (in *UUIDSpec) DeepCopy() *UUIDSpec { - if in == nil { - return nil - } - out := new(UUIDSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UniversalAuthDetails) DeepCopyInto(out *UniversalAuthDetails) { - *out = *in - out.CredentialsRef = in.CredentialsRef - out.SecretsScope = in.SecretsScope -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UniversalAuthDetails. -func (in *UniversalAuthDetails) DeepCopy() *UniversalAuthDetails { - if in == nil { - return nil - } - out := new(UniversalAuthDetails) - in.DeepCopyInto(out) - return out -} diff --git a/k8-operator/cmd/main.go b/k8-operator/cmd/main.go deleted file mode 100644 index 40142a4461..0000000000 --- a/k8-operator/cmd/main.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "crypto/tls" - "flag" - "fmt" - "os" - "path/filepath" - - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/certwatcher" - "sigs.k8s.io/controller-runtime/pkg/healthz" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/metrics/filters" - metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - "sigs.k8s.io/controller-runtime/pkg/webhook" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/controller" - // +kubebuilder:scaffold:imports -) - -var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") -) - -func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - - utilruntime.Must(secretsv1alpha1.AddToScheme(scheme)) - // +kubebuilder:scaffold:scheme -} - -// nolint:gocyclo -func main() { - var metricsAddr string - var metricsCertPath, metricsCertName, metricsCertKey string - var webhookCertPath, webhookCertName, webhookCertKey string - var enableLeaderElection bool - var probeAddr string - var secureMetrics bool - var enableHTTP2 bool - var namespace string - - var tlsOpts []func(*tls.Config) - flag.StringVar(&namespace, "namespace", "", "Watch InfisicalSecrets scoped in the provided namespace only") - flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ - "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") - flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "leader-elect", false, - "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - flag.BoolVar(&secureMetrics, "metrics-secure", true, - "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") - flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.") - flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.") - flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.") - flag.StringVar(&metricsCertPath, "metrics-cert-path", "", - "The directory that contains the metrics server certificate.") - flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.") - flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.") - flag.BoolVar(&enableHTTP2, "enable-http2", false, - "If set, HTTP/2 will be enabled for the metrics and webhook servers") - opts := zap.Options{ - Development: true, - } - opts.BindFlags(flag.CommandLine) - flag.Parse() - - ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - - // if the enable-http2 flag is false (the default), http/2 should be disabled - // due to its vulnerabilities. More specifically, disabling http/2 will - // prevent from being vulnerable to the HTTP/2 Stream Cancellation and - // Rapid Reset CVEs. For more information see: - // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 - // - https://github.com/advisories/GHSA-4374-p667-p6c8 - disableHTTP2 := func(c *tls.Config) { - setupLog.Info("disabling http/2") - c.NextProtos = []string{"http/1.1"} - } - - if !enableHTTP2 { - tlsOpts = append(tlsOpts, disableHTTP2) - } - - // Create watchers for metrics and webhooks certificates - var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher - - // Initial webhook TLS options - webhookTLSOpts := tlsOpts - - if len(webhookCertPath) > 0 { - setupLog.Info("Initializing webhook certificate watcher using provided certificates", - "webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey) - - var err error - webhookCertWatcher, err = certwatcher.New( - filepath.Join(webhookCertPath, webhookCertName), - filepath.Join(webhookCertPath, webhookCertKey), - ) - if err != nil { - setupLog.Error(err, "Failed to initialize webhook certificate watcher") - os.Exit(1) - } - - webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) { - config.GetCertificate = webhookCertWatcher.GetCertificate - }) - } - - webhookServer := webhook.NewServer(webhook.Options{ - TLSOpts: webhookTLSOpts, - }) - - // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. - // More info: - // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server - // - https://book.kubebuilder.io/reference/metrics.html - metricsServerOptions := metricsserver.Options{ - BindAddress: metricsAddr, - SecureServing: secureMetrics, - TLSOpts: tlsOpts, - } - - if secureMetrics { - // FilterProvider is used to protect the metrics endpoint with authn/authz. - // These configurations ensure that only authorized users and service accounts - // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: - // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization - metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization - } - - // If the certificate is not specified, controller-runtime will automatically - // generate self-signed certificates for the metrics server. While convenient for development and testing, - // this setup is not recommended for production. - // - // TODO(user): If you enable certManager, uncomment the following lines: - // - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates - // managed by cert-manager for the metrics server. - // - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification. - if len(metricsCertPath) > 0 { - setupLog.Info("Initializing metrics certificate watcher using provided certificates", - "metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey) - - var err error - metricsCertWatcher, err = certwatcher.New( - filepath.Join(metricsCertPath, metricsCertName), - filepath.Join(metricsCertPath, metricsCertKey), - ) - if err != nil { - setupLog.Error(err, "to initialize metrics certificate watcher", "error", err) - os.Exit(1) - } - - metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) { - config.GetCertificate = metricsCertWatcher.GetCertificate - }) - } - - managerOptions := ctrl.Options{ - Scheme: scheme, - Metrics: metricsServerOptions, - WebhookServer: webhookServer, - HealthProbeBindAddress: probeAddr, - LeaderElection: enableLeaderElection, - LeaderElectionID: "cf2b8c44.infisical.com", - // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily - // when the Manager ends. This requires the binary to immediately end when the - // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly - // speeds up voluntary leader transitions as the new leader don't have to wait - // LeaseDuration time first. - // - // In the default scaffold provided, the program ends immediately after - // the manager stops, so would be fine to enable this option. However, - // if you are doing or is intended to do any operation such as perform cleanups - // after the manager stops then its usage might be unsafe. - // LeaderElectionReleaseOnCancel: true, - } - - // Only set cache options if we're namespace-scoped - if namespace != "" { - managerOptions.Cache = cache.Options{ - Scheme: scheme, - DefaultNamespaces: map[string]cache.Config{ - namespace: {}, // whichever namespace the operator is running in - }, - } - ctrl.Log.Info(fmt.Sprintf("Watching CRDs in [namespace=%s]", namespace)) - } - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), managerOptions) - if err != nil { - setupLog.Error(err, "unable to start manager") - os.Exit(1) - } - - if err := (&controller.InfisicalSecretReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - BaseLogger: ctrl.Log, - Namespace: namespace, - IsNamespaceScoped: namespace != "", - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "InfisicalSecret") - os.Exit(1) - } - if err := (&controller.InfisicalPushSecretReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - IsNamespaceScoped: namespace != "", - Namespace: namespace, - BaseLogger: ctrl.Log, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "InfisicalPushSecret") - os.Exit(1) - } - if err := (&controller.InfisicalDynamicSecretReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - BaseLogger: ctrl.Log, - IsNamespaceScoped: namespace != "", - Namespace: namespace, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "InfisicalDynamicSecret") - os.Exit(1) - } - // +kubebuilder:scaffold:builder - - if metricsCertWatcher != nil { - setupLog.Info("Adding metrics certificate watcher to manager") - if err := mgr.Add(metricsCertWatcher); err != nil { - setupLog.Error(err, "unable to add metrics certificate watcher to manager") - os.Exit(1) - } - } - - if webhookCertWatcher != nil { - setupLog.Info("Adding webhook certificate watcher to manager") - if err := mgr.Add(webhookCertWatcher); err != nil { - setupLog.Error(err, "unable to add webhook certificate watcher to manager") - os.Exit(1) - } - } - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") - os.Exit(1) - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") - os.Exit(1) - } - - setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") - os.Exit(1) - } -} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_clustergenerators.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_clustergenerators.yaml deleted file mode 100644 index 0681f26ecf..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_clustergenerators.yaml +++ /dev/null @@ -1,96 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: clustergenerators.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: ClusterGenerator - listKind: ClusterGeneratorList - plural: clustergenerators - singular: clustergenerator - scope: Cluster - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: ClusterGenerator represents a cluster-wide generator - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - properties: - generator: - description: Generator the spec for this generator, must match the - kind. - properties: - passwordSpec: - description: PasswordSpec controls the behavior of the password - generator. - properties: - allowRepeat: - default: false - description: set allowRepeat to true to allow repeating characters. - type: boolean - digits: - description: |- - digits specifies the number of digits in the generated - password. If omitted it defaults to 25% of the length of the password - type: integer - length: - default: 24 - description: |- - Length of the password to be generated. - Defaults to 24 - type: integer - noUpper: - default: false - description: Set noUpper to disable uppercase characters - type: boolean - symbolCharacters: - description: |- - symbolCharacters specifies the special characters that should be used - in the generated password. - type: string - symbols: - description: |- - symbols specifies the number of symbol characters in the generated - password. If omitted it defaults to 25% of the length of the password - type: integer - type: object - uuidSpec: - description: UUIDSpec controls the behavior of the uuid generator. - type: object - type: object - kind: - description: Kind the kind of this generator. - enum: - - Password - - UUID - type: string - required: - - kind - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml deleted file mode 100644 index f50b303e94..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicaldynamicsecrets.yaml +++ /dev/null @@ -1,330 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: infisicaldynamicsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalDynamicSecret - listKind: InfisicalDynamicSecretList - plural: infisicaldynamicsecrets - singular: infisicaldynamicsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalDynamicSecret is the Schema for the infisicaldynamicsecrets - API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: InfisicalDynamicSecretSpec defines the desired state of InfisicalDynamicSecret. - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - required: - - identityId - type: object - gcpIamAuth: - properties: - identityId: - type: string - serviceAccountKeyFilePath: - type: string - required: - - identityId - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - kubernetesAuth: - properties: - autoCreateServiceAccountToken: - description: |- - Optionally automatically create a service account token for the configured service account. - If this is set to `true`, the operator will automatically create a service account token for the configured service account. This field is recommended in most cases. - type: boolean - identityId: - type: string - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - serviceAccountTokenAudiences: - description: The audiences to use for the service account - token. This is only relevant if `autoCreateServiceAccountToken` - is true. - items: - type: string - type: array - required: - - identityId - - serviceAccountRef - type: object - ldapAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - identityId: - type: string - required: - - credentialsRef - - identityId - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - credentialsRef - type: object - type: object - dynamicSecret: - properties: - environmentSlug: - type: string - projectId: - type: string - secretName: - type: string - secretsPath: - type: string - required: - - environmentSlug - - projectId - - secretName - - secretsPath - type: object - hostAPI: - type: string - leaseRevocationPolicy: - type: string - leaseTTL: - type: string - managedSecretReference: - properties: - creationPolicy: - default: Orphan - description: |- - The Kubernetes Secret creation policy. - Enum with values: 'Owner', 'Orphan'. - Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted. - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: 'The Kubernetes Secret type (experimental feature). - More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types' - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: |- - This injects all retrieved secrets into the top level of your template. - Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate - value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is - located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - required: - - authentication - - dynamicSecret - - leaseRevocationPolicy - - leaseTTL - - managedSecretReference - type: object - status: - description: InfisicalDynamicSecretStatus defines the observed state of - InfisicalDynamicSecret. - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - dynamicSecretId: - type: string - lease: - properties: - creationTimestamp: - format: date-time - type: string - expiresAt: - format: date-time - type: string - id: - type: string - version: - format: int64 - type: integer - required: - - creationTimestamp - - expiresAt - - id - - version - type: object - maxTTL: - description: The MaxTTL can be null, if it's null, there's no max - TTL and we should never have to renew. - type: string - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml deleted file mode 100644 index a176e45f4c..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalpushsecrets.yaml +++ /dev/null @@ -1,326 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: infisicalpushsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalPushSecret - listKind: InfisicalPushSecretList - plural: infisicalpushsecrets - singular: infisicalpushsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalPushSecret is the Schema for the infisicalpushsecrets - API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - required: - - identityId - type: object - gcpIamAuth: - properties: - identityId: - type: string - serviceAccountKeyFilePath: - type: string - required: - - identityId - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - kubernetesAuth: - properties: - autoCreateServiceAccountToken: - description: |- - Optionally automatically create a service account token for the configured service account. - If this is set to `true`, the operator will automatically create a service account token for the configured service account. This field is recommended in most cases. - type: boolean - identityId: - type: string - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - serviceAccountTokenAudiences: - description: The audiences to use for the service account - token. This is only relevant if `autoCreateServiceAccountToken` - is true. - items: - type: string - type: array - required: - - identityId - - serviceAccountRef - type: object - ldapAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - identityId: - type: string - required: - - credentialsRef - - identityId - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - credentialsRef - type: object - type: object - deletionPolicy: - type: string - destination: - properties: - environmentSlug: - type: string - projectId: - type: string - secretsPath: - type: string - required: - - environmentSlug - - projectId - - secretsPath - type: object - hostAPI: - description: Infisical host to pull secrets from - type: string - push: - properties: - generators: - items: - properties: - destinationSecretName: - type: string - generatorRef: - properties: - kind: - allOf: - - enum: - - Password - - UUID - - enum: - - Password - - UUID - description: Specify the Kind of the generator resource - type: string - name: - type: string - required: - - kind - - name - type: object - required: - - destinationSecretName - - generatorRef - type: object - type: array - secret: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is - located - type: string - template: - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: |- - This injects all retrieved secrets into the top level of your template. - Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - type: object - resyncInterval: - type: string - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate - value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is - located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - updatePolicy: - type: string - required: - - destination - - push - type: object - status: - description: InfisicalPushSecretStatus defines the observed state of InfisicalPushSecret - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - managedSecrets: - additionalProperties: - type: string - description: managed secrets is a map where the key is the ID, and - the value is the secret key (string[id], string[key] ) - type: object - required: - - conditions - - managedSecrets - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml deleted file mode 100644 index 176c44374d..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_infisicalsecrets.yaml +++ /dev/null @@ -1,542 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: infisicalsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalSecret - listKind: InfisicalSecretList - plural: infisicalsecrets - singular: infisicalsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalSecret is the Schema for the infisicalsecrets API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: InfisicalSecretSpec defines the desired state of InfisicalSecret - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - gcpIamAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - serviceAccountKeyFilePath: - type: string - required: - - identityId - - secretsScope - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - kubernetesAuth: - properties: - autoCreateServiceAccountToken: - description: |- - Optionally automatically create a service account token for the configured service account. - If this is set to `true`, the operator will automatically create a service account token for the configured service account. - type: boolean - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - serviceAccountTokenAudiences: - description: The audiences to use for the service account - token. This is only relevant if `autoCreateServiceAccountToken` - is true. - items: - type: string - type: array - required: - - identityId - - secretsScope - - serviceAccountRef - type: object - ldapAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - credentialsRef - - identityId - - secretsScope - type: object - serviceAccount: - properties: - environmentName: - type: string - projectId: - type: string - serviceAccountSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - environmentName - - projectId - - serviceAccountSecretReference - type: object - serviceToken: - properties: - secretsScope: - properties: - envSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - secretsPath - type: object - serviceTokenSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - secretsScope - - serviceTokenSecretReference - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret - is located - type: string - required: - - secretName - - secretNamespace - type: object - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - credentialsRef - - secretsScope - type: object - type: object - hostAPI: - description: Infisical host to pull secrets from - type: string - instantUpdates: - type: boolean - managedKubeConfigMapReferences: - items: - properties: - configMapName: - description: The name of the Kubernetes ConfigMap - type: string - configMapNamespace: - description: The namespace where the Kubernetes ConfigMap is - located - type: string - creationPolicy: - default: Orphan - description: |- - The Kubernetes ConfigMap creation policy. - Enum with values: 'Owner', 'Orphan'. - Owner creates the config map and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - Orphan will not set the config map owner. This will result in the config map being orphaned and not deleted when the resource is deleted. - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: |- - This injects all retrieved secrets into the top level of your template. - Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - configMapName - - configMapNamespace - type: object - type: array - managedKubeSecretReferences: - items: - properties: - creationPolicy: - default: Orphan - description: |- - The Kubernetes Secret creation policy. - Enum with values: 'Owner', 'Orphan'. - Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted. - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: 'The Kubernetes Secret type (experimental feature). - More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types' - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: |- - This injects all retrieved secrets into the top level of your template. - Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - type: array - managedSecretReference: - properties: - creationPolicy: - default: Orphan - description: |- - The Kubernetes Secret creation policy. - Enum with values: 'Owner', 'Orphan'. - Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. - Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted. - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: 'The Kubernetes Secret type (experimental feature). - More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types' - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: |- - This injects all retrieved secrets into the top level of your template. - Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - resyncInterval: - default: 60 - type: integer - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate - value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is - located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - tokenSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - resyncInterval - type: object - status: - description: InfisicalSecretStatus defines the observed state of InfisicalSecret - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_passwords.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_passwords.yaml deleted file mode 100644 index 788e077a6e..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_passwords.yaml +++ /dev/null @@ -1,79 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: passwords.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: Password - listKind: PasswordList - plural: passwords - singular: password - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: |- - Password generates a random password based on the - configuration parameters in spec. - You can specify the length, characterset and other attributes. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: PasswordSpec controls the behavior of the password generator. - properties: - allowRepeat: - default: false - description: set allowRepeat to true to allow repeating characters. - type: boolean - digits: - description: |- - digits specifies the number of digits in the generated - password. If omitted it defaults to 25% of the length of the password - type: integer - length: - default: 24 - description: |- - Length of the password to be generated. - Defaults to 24 - type: integer - noUpper: - default: false - description: Set noUpper to disable uppercase characters - type: boolean - symbolCharacters: - description: |- - symbolCharacters specifies the special characters that should be used - in the generated password. - type: string - symbols: - description: |- - symbols specifies the number of symbol characters in the generated - password. If omitted it defaults to 25% of the length of the password - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/bases/secrets.infisical.com_uuids.yaml b/k8-operator/config/crd/bases/secrets.infisical.com_uuids.yaml deleted file mode 100644 index 659dfc7ac1..0000000000 --- a/k8-operator/config/crd/bases/secrets.infisical.com_uuids.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: uuids.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: UUID - listKind: UUIDList - plural: uuids - singular: uuid - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: UUID generates a version 4 UUID (e56657e3-764f-11ef-a397-65231a88c216). - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: UUIDSpec controls the behavior of the uuid generator. - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/k8-operator/config/crd/kustomization.yaml b/k8-operator/config/crd/kustomization.yaml deleted file mode 100644 index 02e3fad980..0000000000 --- a/k8-operator/config/crd/kustomization.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default -resources: - - bases/secrets.infisical.com_infisicalsecrets.yaml - - bases/secrets.infisical.com_infisicalpushsecrets.yaml - - bases/secrets.infisical.com_infisicaldynamicsecrets.yaml - - bases/secrets.infisical.com_clustergenerators.yaml -#+kubebuilder:scaffold:crdkustomizeresource - -patchesStrategicMerge: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_infisicalsecrets.yaml -#+kubebuilder:scaffold:crdkustomizewebhookpatch - -# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_infisicalsecrets.yaml -#+kubebuilder:scaffold:crdkustomizecainjectionpatch - -# the following config is for teaching kustomize how to do kustomization for CRDs. -configurations: - - kustomizeconfig.yaml diff --git a/k8-operator/config/crd/kustomizeconfig.yaml b/k8-operator/config/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a9d..0000000000 --- a/k8-operator/config/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/k8-operator/config/default/cert_metrics_manager_patch.yaml b/k8-operator/config/default/cert_metrics_manager_patch.yaml deleted file mode 100644 index d975015538..0000000000 --- a/k8-operator/config/default/cert_metrics_manager_patch.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# This patch adds the args, volumes, and ports to allow the manager to use the metrics-server certs. - -# Add the volumeMount for the metrics-server certs -- op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: - mountPath: /tmp/k8s-metrics-server/metrics-certs - name: metrics-certs - readOnly: true - -# Add the --metrics-cert-path argument for the metrics server -- op: add - path: /spec/template/spec/containers/0/args/- - value: --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs - -# Add the metrics-server certs volume configuration -- op: add - path: /spec/template/spec/volumes/- - value: - name: metrics-certs - secret: - secretName: metrics-server-cert - optional: false - items: - - key: ca.crt - path: ca.crt - - key: tls.crt - path: tls.crt - - key: tls.key - path: tls.key diff --git a/k8-operator/config/default/kustomization.yaml b/k8-operator/config/default/kustomization.yaml deleted file mode 100644 index 87497e05af..0000000000 --- a/k8-operator/config/default/kustomization.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Adds namespace to all resources. -namespace: infisical-operator-system - -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. -namePrefix: infisical-operator- - -# Labels to add to all resources and selectors. -#labels: -#- includeSelectors: true -# pairs: -# someName: someValue - -resources: - - ../crd - - ../rbac - - ../manager - - metrics_service.yaml - -patches: - - path: manager_metrics_patch.yaml - target: - kind: Deployment diff --git a/k8-operator/config/default/manager_metrics_patch.yaml b/k8-operator/config/default/manager_metrics_patch.yaml deleted file mode 100644 index 2aaef6536f..0000000000 --- a/k8-operator/config/default/manager_metrics_patch.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# This patch adds the args to allow exposing the metrics endpoint using HTTPS -- op: add - path: /spec/template/spec/containers/0/args/0 - value: --metrics-bind-address=:8443 diff --git a/k8-operator/config/default/metrics_service.yaml b/k8-operator/config/default/metrics_service.yaml deleted file mode 100644 index 6acf3ca492..0000000000 --- a/k8-operator/config/default/metrics_service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-service - namespace: system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - control-plane: controller-manager diff --git a/k8-operator/config/manager/kustomization.yaml b/k8-operator/config/manager/kustomization.yaml deleted file mode 100644 index ad13e96b3f..0000000000 --- a/k8-operator/config/manager/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -resources: -- manager.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -images: -- name: controller - newName: controller - newTag: latest diff --git a/k8-operator/config/manager/manager.yaml b/k8-operator/config/manager/manager.yaml deleted file mode 100644 index fe46017354..0000000000 --- a/k8-operator/config/manager/manager.yaml +++ /dev/null @@ -1,97 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize -spec: - selector: - matchLabels: - control-plane: controller-manager - replicas: 1 - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - # TODO(user): Uncomment the following code to configure the nodeAffinity expression - # according to the platforms which are supported by your solution. - # It is considered best practice to support multiple architectures. You can - # build your manager image using the makefile target docker-buildx. - # affinity: - # nodeAffinity: - # requiredDuringSchedulingIgnoredDuringExecution: - # nodeSelectorTerms: - # - matchExpressions: - # - key: kubernetes.io/arch - # operator: In - # values: - # - amd64 - # - arm64 - # - ppc64le - # - s390x - # - key: kubernetes.io/os - # operator: In - # values: - # - linux - securityContext: - # Projects are configured by default to adhere to the "restricted" Pod Security Standards. - # This ensures that deployments meet the highest security requirements for Kubernetes. - # For more details, see: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - containers: - - command: - - /manager - args: - - --leader-elect - - --health-probe-bind-address=:8081 - image: controller:latest - name: manager - ports: [] - securityContext: - readOnlyRootFilesystem: true - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - # TODO(user): Configure the resources accordingly based on the project requirements. - # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - volumeMounts: [] - volumes: [] - serviceAccountName: controller-manager - terminationGracePeriodSeconds: 10 diff --git a/k8-operator/config/network-policy/allow-metrics-traffic.yaml b/k8-operator/config/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index 21eed79447..0000000000 --- a/k8-operator/config/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gather data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: allow-metrics-traffic - namespace: system -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator - policyTypes: - - Ingress - ingress: - # This allows ingress traffic from any namespace with the label metrics: enabled - - from: - - namespaceSelector: - matchLabels: - metrics: enabled # Only from namespaces with this label - ports: - - port: 8443 - protocol: TCP diff --git a/k8-operator/config/network-policy/kustomization.yaml b/k8-operator/config/network-policy/kustomization.yaml deleted file mode 100644 index ec0fb5e57d..0000000000 --- a/k8-operator/config/network-policy/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- allow-metrics-traffic.yaml diff --git a/k8-operator/config/prometheus/kustomization.yaml b/k8-operator/config/prometheus/kustomization.yaml deleted file mode 100644 index fdc5481b10..0000000000 --- a/k8-operator/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,11 +0,0 @@ -resources: -- monitor.yaml - -# [PROMETHEUS-WITH-CERTS] The following patch configures the ServiceMonitor in ../prometheus -# to securely reference certificates created and managed by cert-manager. -# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml -# to mount the "metrics-server-cert" secret in the Manager Deployment. -#patches: -# - path: monitor_tls_patch.yaml -# target: -# kind: ServiceMonitor diff --git a/k8-operator/config/prometheus/monitor.yaml b/k8-operator/config/prometheus/monitor.yaml deleted file mode 100644 index abaef64896..0000000000 --- a/k8-operator/config/prometheus/monitor.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https # Ensure this is the name of the port that exposes HTTPS metrics - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables - # certificate verification, exposing the system to potential man-in-the-middle attacks. - # For production environments, it is recommended to use cert-manager for automatic TLS certificate management. - # To apply this configuration, enable cert-manager and use the patch located at config/prometheus/servicemonitor_tls_patch.yaml, - # which securely references the certificate from the 'metrics-server-cert' secret. - insecureSkipVerify: true - selector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: k8-operator diff --git a/k8-operator/config/prometheus/monitor_tls_patch.yaml b/k8-operator/config/prometheus/monitor_tls_patch.yaml deleted file mode 100644 index 5bf84ce0d5..0000000000 --- a/k8-operator/config/prometheus/monitor_tls_patch.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Patch for Prometheus ServiceMonitor to enable secure TLS configuration -# using certificates managed by cert-manager -- op: replace - path: /spec/endpoints/0/tlsConfig - value: - # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize - serverName: SERVICE_NAME.SERVICE_NAMESPACE.svc - insecureSkipVerify: false - ca: - secret: - name: metrics-server-cert - key: ca.crt - cert: - secret: - name: metrics-server-cert - key: tls.crt - keySecret: - name: metrics-server-cert - key: tls.key diff --git a/k8-operator/config/rbac/infisicaldynamicsecret_admin_role.yaml b/k8-operator/config/rbac/infisicaldynamicsecret_admin_role.yaml deleted file mode 100644 index 8bcd0e68cf..0000000000 --- a/k8-operator/config/rbac/infisicaldynamicsecret_admin_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over secrets.infisical.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicaldynamicsecret-admin-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets - verbs: - - '*' -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicaldynamicsecret_editor_role.yaml b/k8-operator/config/rbac/infisicaldynamicsecret_editor_role.yaml deleted file mode 100644 index 4d3ffc985c..0000000000 --- a/k8-operator/config/rbac/infisicaldynamicsecret_editor_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the secrets.infisical.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicaldynamicsecret-editor-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicaldynamicsecret_viewer_role.yaml b/k8-operator/config/rbac/infisicaldynamicsecret_viewer_role.yaml deleted file mode 100644 index d5cfc7be94..0000000000 --- a/k8-operator/config/rbac/infisicaldynamicsecret_viewer_role.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to secrets.infisical.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicaldynamicsecret-viewer-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets - verbs: - - get - - list - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalpushsecretsecret_admin_role.yaml b/k8-operator/config/rbac/infisicalpushsecretsecret_admin_role.yaml deleted file mode 100644 index e8674cc6f0..0000000000 --- a/k8-operator/config/rbac/infisicalpushsecretsecret_admin_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over secrets.infisical.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalpushsecretsecret-admin-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets - verbs: - - '*' -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalpushsecretsecret_editor_role.yaml b/k8-operator/config/rbac/infisicalpushsecretsecret_editor_role.yaml deleted file mode 100644 index 97ab6dc66d..0000000000 --- a/k8-operator/config/rbac/infisicalpushsecretsecret_editor_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the secrets.infisical.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalpushsecretsecret-editor-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalpushsecretsecret_viewer_role.yaml b/k8-operator/config/rbac/infisicalpushsecretsecret_viewer_role.yaml deleted file mode 100644 index 4a7ae8346f..0000000000 --- a/k8-operator/config/rbac/infisicalpushsecretsecret_viewer_role.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to secrets.infisical.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalpushsecretsecret-viewer-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets - verbs: - - get - - list - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecretsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalsecret_admin_role.yaml b/k8-operator/config/rbac/infisicalsecret_admin_role.yaml deleted file mode 100644 index 1c5d88eed1..0000000000 --- a/k8-operator/config/rbac/infisicalsecret_admin_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over secrets.infisical.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalsecret-admin-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets - verbs: - - '*' -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalsecret_editor_role.yaml b/k8-operator/config/rbac/infisicalsecret_editor_role.yaml deleted file mode 100644 index a70abf3c44..0000000000 --- a/k8-operator/config/rbac/infisicalsecret_editor_role.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the secrets.infisical.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalsecret-editor-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/infisicalsecret_viewer_role.yaml b/k8-operator/config/rbac/infisicalsecret_viewer_role.yaml deleted file mode 100644 index a5a7249402..0000000000 --- a/k8-operator/config/rbac/infisicalsecret_viewer_role.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# This rule is not used by the project k8-operator itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to secrets.infisical.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: infisicalsecret-viewer-role -rules: -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets - verbs: - - get - - list - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets/status - verbs: - - get diff --git a/k8-operator/config/rbac/kustomization.yaml b/k8-operator/config/rbac/kustomization.yaml deleted file mode 100644 index 386e871712..0000000000 --- a/k8-operator/config/rbac/kustomization.yaml +++ /dev/null @@ -1,34 +0,0 @@ -resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. -- service_account.yaml -- role.yaml -- role_binding.yaml -- leader_election_role.yaml -- leader_election_role_binding.yaml -# The following RBAC configurations are used to protect -# the metrics endpoint with authn/authz. These configurations -# ensure that only authorized users and service accounts -# can access the metrics endpoint. Comment the following -# permissions if you want to disable this protection. -# More info: https://book.kubebuilder.io/reference/metrics.html -- metrics_auth_role.yaml -- metrics_auth_role_binding.yaml -- metrics_reader_role.yaml -# For each CRD, "Admin", "Editor" and "Viewer" roles are scaffolded by -# default, aiding admins in cluster management. Those roles are -# not used by the k8-operator itself. You can comment the following lines -# if you do not want those helpers be installed with your Project. -# - infisicaldynamicsecret_admin_role.yaml -# - infisicaldynamicsecret_editor_role.yaml -# - infisicaldynamicsecret_viewer_role.yaml -# - infisicalpushsecret_admin_role.yaml -# - infisicalpushsecret_editor_role.yaml -# - infisicalpushsecret_viewer_role.yaml -# - infisicalsecret_admin_role.yaml -# - infisicalsecret_editor_role.yaml -# - infisicalsecret_viewer_role.yaml - diff --git a/k8-operator/config/rbac/leader_election_role.yaml b/k8-operator/config/rbac/leader_election_role.yaml deleted file mode 100644 index a86e00ed14..0000000000 --- a/k8-operator/config/rbac/leader_election_role.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: leader-election-role -rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch diff --git a/k8-operator/config/rbac/leader_election_role_binding.yaml b/k8-operator/config/rbac/leader_election_role_binding.yaml deleted file mode 100644 index d662fc9de7..0000000000 --- a/k8-operator/config/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: leader-election-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/k8-operator/config/rbac/metrics_auth_role.yaml b/k8-operator/config/rbac/metrics_auth_role.yaml deleted file mode 100644 index 32d2e4ec6b..0000000000 --- a/k8-operator/config/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/k8-operator/config/rbac/metrics_auth_role_binding.yaml b/k8-operator/config/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index e775d67ff0..0000000000 --- a/k8-operator/config/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: metrics-auth-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/k8-operator/config/rbac/metrics_reader_role.yaml b/k8-operator/config/rbac/metrics_reader_role.yaml deleted file mode 100644 index 51a75db47a..0000000000 --- a/k8-operator/config/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/k8-operator/config/rbac/role.yaml b/k8-operator/config/rbac/role.yaml deleted file mode 100644 index 97151dd0bc..0000000000 --- a/k8-operator/config/rbac/role.yaml +++ /dev/null @@ -1,89 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: manager-role -rules: -- apiGroups: - - "" - resources: - - configmaps - - secrets - verbs: - - create - - delete - - get - - list - - update - - watch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - serviceaccounts/token - verbs: - - create -- apiGroups: - - apps - resources: - - daemonsets - - deployments - - statefulsets - verbs: - - get - - list - - update - - watch -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - secrets.infisical.com - resources: - - clustergenerators - - infisicaldynamicsecrets - - infisicalpushsecrets - - infisicalsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/finalizers - - infisicalpushsecrets/finalizers - - infisicalsecrets/finalizers - verbs: - - update -- apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/status - - infisicalpushsecrets/status - - infisicalsecrets/status - verbs: - - get - - patch - - update diff --git a/k8-operator/config/rbac/role_binding.yaml b/k8-operator/config/rbac/role_binding.yaml deleted file mode 100644 index 5e15ad6f45..0000000000 --- a/k8-operator/config/rbac/role_binding.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/k8-operator/config/rbac/service_account.yaml b/k8-operator/config/rbac/service_account.yaml deleted file mode 100644 index ed238fe997..0000000000 --- a/k8-operator/config/rbac/service_account.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/name: k8-operator - app.kubernetes.io/managed-by: kustomize - name: controller-manager - namespace: system diff --git a/k8-operator/config/samples/crd/infisicaldynamicsecret/dynamicSecret.yaml b/k8-operator/config/samples/crd/infisicaldynamicsecret/dynamicSecret.yaml deleted file mode 100644 index 98bb548661..0000000000 --- a/k8-operator/config/samples/crd/infisicaldynamicsecret/dynamicSecret.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalDynamicSecret -metadata: - name: infisicaldynamicsecret-demo -spec: - hostAPI: http://localhost:8080/api - - dynamicSecret: - secretName: dynamic-secret - projectId: 5cdc4fec-f541-413c-b0bc-4c15572e421e - secretsPath: / - environmentSlug: dev - - leaseRevocationPolicy: Revoke # Revoke or None. Revoke will revoke leases created by the operator if the CRD is deleted. - leaseTTL: 1m # TTL for the leases created. Must be below 24 hours. - - # Reference to the secret that you want to store the lease credentials in. If a secret with the name specified name does not exist, it will automatically be created. - managedSecretReference: - secretName: lease - secretNamespace: default - creationPolicy: Orphan # Orphan or Owner - - authentication: - universalAuth: - credentialsRef: - secretName: universal-auth-credentials # universal-auth-credentials - secretNamespace: default # default diff --git a/k8-operator/config/samples/crd/infisicalsecret/infisical-secret-crd-with-template.yml b/k8-operator/config/samples/crd/infisicalsecret/infisical-secret-crd-with-template.yml deleted file mode 100644 index 06086e93f8..0000000000 --- a/k8-operator/config/samples/crd/infisicalsecret/infisical-secret-crd-with-template.yml +++ /dev/null @@ -1,112 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalSecret -metadata: - name: infisicalsecret-sample - labels: - label-to-be-passed-to-managed-secret: sample-value - annotations: - example.com/annotation-to-be-passed-to-managed-secret: "sample-value" -spec: - hostAPI: https://app.infisical.com/api - resyncInterval: 10 - # tls: - # caRef: - # secretName: custom-ca-certificate - # secretNamespace: default - # key: ca.crt - authentication: - # Make sure to only have 1 authentication method defined, serviceToken/universalAuth. - # If you have multiple authentication methods defined, it may cause issues. - - # (Deprecated) Service Token Auth - serviceToken: - serviceTokenSecretReference: - secretName: service-token - secretNamespace: default - secretsScope: - envSlug: - secretsPath: - recursive: true - - # Universal Auth - universalAuth: - secretsScope: - projectSlug: new-ob-em - envSlug: dev # "dev", "staging", "prod", etc.. - secretsPath: "/" # Root is "/" - recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false - credentialsRef: - secretName: universal-auth-credentials - secretNamespace: default - - # Native Kubernetes Auth - kubernetesAuth: - serviceAccountRef: - name: - namespace: - identityId: - serviceAccountTokenPath: "/path/to/your/service-account/token" # Optional, defaults to /var/run/secrets/kubernetes.io/serviceaccount/token - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # AWS IAM Auth - awsIamAuth: - identityId: - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # Azure Auth - azureAuth: - identityId: - resource: https://management.azure.com/&client_id=your_client_id # This field is optional, and will default to "https://management.azure.com/" if nothing is provided. - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # GCP ID Token Auth - gcpIdTokenAuth: - identityId: - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # GCP IAM Auth - gcpIamAuth: - identityId: - serviceAccountKeyFilePath: "/path/to-service-account-key-file-path.json" - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - managedKubeSecretReferences: - - secretName: managed-secret - secretNamespace: default - creationPolicy: "Orphan" ## Owner | Orphan - # secretType: kubernetes.io/dockerconfigjson - template: - includeAllSecrets: true - data: - SSH_KEY: "{{ .KEY.SecretPath }} {{ .KEY.Value }}" - BINARY_KEY: "{{ decodeBase64ToBytes .BINARY_KEY_BASE64.Value }}" diff --git a/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml b/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml deleted file mode 100644 index 6ea6dc5611..0000000000 --- a/k8-operator/config/samples/crd/infisicalsecret/infisicalSecretCrd.yaml +++ /dev/null @@ -1,107 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalSecret -metadata: - name: infisicalsecret-sample - labels: - label-to-be-passed-to-managed-secret: sample-value - annotations: - example.com/annotation-to-be-passed-to-managed-secret: "sample-value" -spec: - hostAPI: http://localhost:8080/api - resyncInterval: 10 - instantUpdates: false - # tls: - # caRef: - # secretName: custom-ca-certificate - # secretNamespace: default - # key: ca.crt - authentication: - # Universal Auth - universalAuth: - secretsScope: - projectSlug: hello-9zkr - envSlug: dev # "dev", "staging", "prod", etc.. - secretsPath: "/" # Root is "/" - recursive: true # Wether or not to use recursive mode (Fetches all secrets in an environment from a given secret path, and all folders inside the path) / defaults to false - credentialsRef: - secretName: universal-auth-credentials - secretNamespace: default - - # Native Kubernetes Auth - kubernetesAuth: - serviceAccountRef: - name: - namespace: - identityId: - serviceAccountTokenPath: "/path/to/your/service-account/token" # Optional, defaults to /var/run/secrets/kubernetes.io/serviceaccount/token - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # AWS IAM Auth - awsIamAuth: - identityId: - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - ldapAuth: - identityId: - credentialsRef: - secretName: # ldap-auth-credentials - secretNamespace: # default - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # Azure Auth - azureAuth: - identityId: - resource: https://management.azure.com/&client_id=your_client_id # This field is optional, and will default to "https://management.azure.com/" if nothing is provided. - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # GCP ID Token Auth - gcpIdTokenAuth: - identityId: - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - # GCP IAM Auth - gcpIamAuth: - identityId: - serviceAccountKeyFilePath: "/path/to-service-account-key-file-path.json" - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: your-project-slug - envSlug: prod - secretsPath: "/path" - recursive: true - - managedKubeSecretReferences: - - secretName: managed-secret - secretNamespace: default - creationPolicy: "Orphan" ## Owner | Orphan diff --git a/k8-operator/config/samples/crd/pushsecret/cluster-password-generator.yml b/k8-operator/config/samples/crd/pushsecret/cluster-password-generator.yml deleted file mode 100644 index ce3c8c0877..0000000000 --- a/k8-operator/config/samples/crd/pushsecret/cluster-password-generator.yml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: ClusterGenerator -metadata: - name: password-generator -spec: - kind: Password - generator: - passwordSpec: - length: 10 - digits: 5 - symbols: 5 - symbolCharacters: "-_$@" - noUpper: false - allowRepeat: true diff --git a/k8-operator/config/samples/crd/pushsecret/push-secret-with-template.yaml b/k8-operator/config/samples/crd/pushsecret/push-secret-with-template.yaml deleted file mode 100644 index a81c2189da..0000000000 --- a/k8-operator/config/samples/crd/pushsecret/push-secret-with-template.yaml +++ /dev/null @@ -1,91 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalPushSecret -metadata: - name: infisical-api-secret-sample-push -spec: - resyncInterval: 1m - hostAPI: https://app.infisical.com/api # This is the default hostAPI for the Infisical API - - # Optional, defaults to replacement. - updatePolicy: Replace # If set to replace, existing secrets inside Infisical will be replaced by the value of the PushSecret on sync. - - # Optional, defaults to no deletion. - deletionPolicy: Delete # If set to delete, the secret(s) inside Infisical managed by the operator, will be deleted if the InfisicalPushSecret CRD is deleted. - - destination: - projectId: - environmentSlug: - secretsPath: - - push: - secret: - secretName: push-secret-demo-with-templating - secretNamespace: default - template: - includeAllSecrets: false - data: - PKCS12_CERT_NO_PASSWORD: "{{ .PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert }}" - PKCS12_KEY_NO_PASSWORD: "{{ .PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key }}" - - PKCS12_CERT_WITH_PASSWORD: '{{ .PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456" }}' - PKCS12_KEY_WITH_PASSWORD: '{{ .PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456" }}' - - PEM_TO_PKCS12_PASS: '{{ pemToPkcs12Pass - (.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456") - (.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456") - "123456" }}' - PEM_TO_PKCS12_NO_PASSWORD: "{{ pemToPkcs12 - (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert) - (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key) - }}" - - FULL_PEM_TO_PKCS12_PASS: '{{ fullPemToPkcs12Pass - (.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456") - (.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456") - "123456" }}' - FULL_PEM_TO_PKCS12_NO_PASSWORD: "{{ fullPemToPkcs12 - (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert) - (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key) - }}" - - FILTERED_PEM_CERT: '{{ filterPEM "CERTIFICATE" (printf "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" .JWK_PRIVATE_RSA_PKCS8.Value .PKCS12_CONTENT_NO_PASSWORD.Value) }}' - FILTERED_PEM_KEY: '{{ filterPEM "PRIVATE KEY" (printf "-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----\n-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----" .JWK_PRIVATE_RSA_PKCS8.Value .PKCS12_CONTENT_NO_PASSWORD.Value) }}' - - # Will be empty with our current test data as there is no chain - CERT_CHAIN: '{{ filterCertChain "CERTIFICATE" (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert) }}' - - JWK_RSA_PUBLIC_PEM: "{{ jwkPublicKeyPem .JWK_PUB_RSA.Value }}" - JWK_ECDSA_PUBLIC_PEM: "{{ jwkPublicKeyPem .JWK_PUB_ECDSA.Value }}" - - JWK_ECDSA_PRIVATE_PEM: "{{ jwkPrivateKeyPem .JWK_PRIV_ECDSA.Value }}" - JWK_RSA_PRIVATE_PEM: "{{ jwkPrivateKeyPem .JWK_PRIV_RSA.Value }}" - - JSON_STR_TO_YAML: "{{ .TEST_JSON_DATA.Value | fromJsonStringToJson | toYaml }}" - - FROM_YAML_TO_JSON: "{{ .TEST_YAML_STRING.Value | fromYaml | toJson }}" - YAML_ROUNDTRIP: "{{ .TEST_YAML_STRING.Value | fromYaml | toYaml }}" - - TEST_LOWERCASE_STRING: "{{ .TEST_LOWERCASE_STRING.Value | upper }}" - - # Only have one authentication method defined or you are likely to run into authentication issues. - # Remove all except one authentication method. - authentication: - awsIamAuth: - identityId: - azureAuth: - identityId: - gcpIamAuth: - identityId: - serviceAccountKeyFilePath: - gcpIdTokenAuth: - identityId: - kubernetesAuth: - identityId: - serviceAccountRef: - name: - namespace: - universalAuth: - credentialsRef: - secretName: # universal-auth-credentials - secretNamespace: # default - diff --git a/k8-operator/config/samples/crd/pushsecret/push-secret.yaml b/k8-operator/config/samples/crd/pushsecret/push-secret.yaml deleted file mode 100644 index 15302e6cca..0000000000 --- a/k8-operator/config/samples/crd/pushsecret/push-secret.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalPushSecret -metadata: - name: infisical-api-secret-sample-push -spec: - resyncInterval: 1m - hostAPI: http://localhost:8080/api - - # Optional, defaults to replacement. - updatePolicy: Replace # If set to replace, existing secrets inside Infisical will be replaced by the value of the PushSecret on sync. - - # Optional, defaults to no deletion. - deletionPolicy: Delete # If set to delete, the secret(s) inside Infisical managed by the operator, will be deleted if the InfisicalPushSecret CRD is deleted. - - destination: - projectId: 5cdc4fec-f541-413c-b0bc-4c15572e421e - environmentSlug: dev - secretsPath: / - - push: - secret: - secretName: push-secret-source-secret # Secret CRD - secretNamespace: default - - # Only have one authentication method defined or you are likely to run into authentication issues. - # Remove all except one authentication method. - authentication: - universalAuth: - credentialsRef: - secretName: universal-auth-credentials # universal-auth-credentials - secretNamespace: default # default diff --git a/k8-operator/config/samples/crd/pushsecret/source-secret-with-templating.yaml b/k8-operator/config/samples/crd/pushsecret/source-secret-with-templating.yaml deleted file mode 100644 index 79a12a4d4d..0000000000 --- a/k8-operator/config/samples/crd/pushsecret/source-secret-with-templating.yaml +++ /dev/null @@ -1,91 +0,0 @@ -# This is the source secret that you can use to demo the advanced templating functionality seen in `push-secret-with-template.yaml` - -apiVersion: v1 -kind: Secret -metadata: - name: push-secret-demo-with-templating - namespace: default -stringData: - PKCS12_CONTENT_NO_PASSWORD: MIIJYQIBAzCCCScGCSqGSIb3DQEHAaCCCRgEggkUMIIJEDCCA8cGCSqGSIb3DQEHBqCCA7gwggO0AgEAMIIDrQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQInZmyWpNTPS4CAggAgIIDgPzZTmogBRiLP0NJZEUghZ3Oh1aqHJJ32HKgXUpD5BJ/5AvpUL9FC7m6a3GD++P1On/35J9N50bDjfBJjJrl2zpA143bzltPQBOK30cBJjNsCeN2Dq1dcsvJZfEy20z75NduXjMF6/qs4BbE+1E6nYFYVNHUybFnaQwSx7+2/2OMbXbcFpt4bv3HTw0YLw2pZeW/4/4A9d+tC9UdVQTTyNbI8l9nf1aeaaPsw1keVLmHurmTihfwh469FvjgwiHUP/P3ZCn1tOpWDR8ck0j+ru6imVP2hn+Kvk6svllmYqo3A5DnDRoF/Cl9R0DAPyS0lw7BeGskgTm7B79mzVitTbzRnIUP+sGJjc1AVghnitfcX4ffv8gq5xWaKGucO/IZXbPBoe7tMhKZmsirKzD4RBhC3nMyrwaHJB6PqUwxMQGMLbuHe7GlWhJAyFlcOTt5dgNl+axIkWdisoKNinYYeOuxudqyX6yPfsyaRCV5MEez3Wu+59MENGlGDRWbw61QuwsZkr1bAT2SJrQ/zHn5aGAluQZ1csJhKQ34iy1Ml9K9F4Zh3/2OWPs0u6+JCb1PC1vChBkguqcqQtEcikRwR9dNF9cdMB1T1Xk5GqlmOPaigkYzGWLgtl8cV5/Zl0m2j77mX9x4HVCTercAABGf9JcCLzSCo04c5OwIYtWUXBkux5n2VI2ZIuS1KF+r6JNyL3lg/D8LColzDUP/6tQCBVVgMar3iLblM17wPMTDMR5Bn+NvenwJj6FWaGGMtdjygtN+oSHpNDbVygfGQy+jEgUtK7yw0uh/WKBMWVw1E6iNuhb8HIyCFtQon8sDkuZ81czOpR3Ta1SWUWrZD+pjpL2Z4y8Nc2wt9pVPvLFOTn+GDFVqGpde3kovh3GfJjYCG/HI5rXZyziflDOoSy0SyG6aVCG4ZqW2LTymoVN/kxf+skqAweX1vxvvJniiv8HgYfEASFUWear4uT641d1YwcEIawNv4n+GKBilK/7ODl2QL86svwqIcbyiJrneyU2tHymKzGcU2VxmSgf8EnjqGuIEo7WXOpk0oUMcvYrM73cgzZ3BchUDIN0KWSDI+vDcVY82dbI39KM6dtOJFAx3kEdms/gdSqZtmHUIeArGp+8caCCAK/W+4wTOvtisK+6MtzdMz6P93N78N4Vo6cs3dkj6t/6tgNog5SCfwlOEyUpmMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4wggUqMIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECHVnarQ94cqlAgIIAASCBMgUvEVKsUcqEvYJEJ9JixgB0W3uhSi/Espt931a/mwx5Ja2K7vjlttaOct3Zc8umVrP5C322tmHz9QDVPj3Bln8CGfofC/8Nb6+SDeofmYaQYReOZpZGksEBs4P3yURl8wQpIkG31Oyf3urDTJdplfDrzu6XpEpIf7RicIR+Zh4Q1+F75XwPo52/yNs8q/kVV8H97gSRqQ2GixIdyNu+JLtNjdwAERHy4DeQjwgiMCdL+xMfN+WJyIvkLZDoy9bacXeG4IcQM+n84272C6j1a0BPaOm0K5A7I0H1zpXOJiWfn3MrT4LHDudrQoIWUOvcJjWaIM/KyghotDN50THKN9qCEE9SmtfWXGGFaJmyxbUDFizBIAsFshNtMs/47PoInTSNwzxNvUUQ3ap93iquGZ9EaZAMY2HQHW/QJIQ70IbtcHU28Bus/hrMcV0X9D1p4UeHuk37W7aCrL6hS+ac9pmzwmcDBwZUliyInxRmqCCerjg2ojAM9SVg8FrpQUErP+BOaoCBwQqLLiz9BM+3tUQc/8MyaBHq+c2dUoPfvipDIQXYiq66CkjmPHxPFEL1l9d9oBFoIGkt6SIHDjWnTPc5q5SvJ9tz8Dp1k/1HQSA8OUS6j+XySYuGe8xTvN/oUpVRswef2Qd/kxZlc1FJ4lVAXvbW7C7772l14BJv/WULcFH4Sn83rlL3YwHr4vJMf6wLahn7oQPI0VFSQiiOOb/+gkiTrwO3Gz+HXOkUwaKnW85PeoIt3/q1u0CRl64mUjqCegi7RMY9Q9tRMlD5yx0RsH7mc4b6Eg/3IwGu8VQmZCO5W2unCpfzzyrOx7OaGGaW4RJ2Mx7bJ8uV9HU8MbbNntmc9oxebPdDnBmbt8p8t4ZZxC+zcqcXi3TxACXmwnasogQEi0d0ttXkB5cnDCG00Y8WPdNIWfJdIQh8Hj16LAMYWUacz/J0kLP99ENQntZibVw/Q3zZtHSF5tmsYp7o1HglBpRwLTcd026YTrxB+VCEiUYy4hH6a38oEEpY7wTIiRmEBQPIRM0HUOqVh4z6TNzRx6iIhrQEvg06B8U6iVPqy8FGDkhf3P55Ed95/Rw6uSdlMTHng+Q4aG00k4qKdKOyv55IXPcvEzAeVNBuesknaS8x7Eb/I5mHSoZU3RYAEFGbehUkvkhNr3Xq7/W/400AKiliravJq8j/qKIZ9hAVUWOps09F/4peYfLXM1AhxWWGa5QqvwFkClM+uRyqIRGJwl2Z7asl4sWVXbwtb+Axio+mYGdzxIki5iwJvRCwKapoZplndXKTrn2nYBuhxW2+fRHa8WYdsm/wn0K+jYMlZhquVjNXyL70/Sym6DkzCtJvveQs2CfcEWQuedjRSGFVFT2jV/s5F8L2TV7nQNVj6dEJSNM5JCdZ//OpiMHMCbPNeSxY9koGplUqFhP54F1WU9x+8xiFjEp8WKxQYKHUtj+ace0lLF4CDGXhFR/0k7Icarpax3hYnvagd2OpZyRJdavKBSs5U7/NPuO6sNhZ2NpzsOiul9Iu8bu3UHCECNKkwN4wF4alTlG9sAAbS4ns4wb9XTajG+OPYoDQZmuJfc71McN6m8KBHEnXU8r4epdR7xREe/w+h2MwtPhLvbxwO592tUxJTAjBgkqhkiG9w0BCRUxFgQUOEXV6IFYGpCSHi0MPHz4b3W0KOQwMTAhMAkGBSsOAwIaBQAEFAjyBCA+mr+5UkKuQ1jGw90ASfbVBAjbvqJJZikDPgICCAA= - PKCS12_CONTENT_WITH_PASSWORD: MIIJYQIBAzCCCScGCSqGSIb3DQEHAaCCCRgEggkUMIIJEDCCA8cGCSqGSIb3DQEHBqCCA7gwggO0AgEAMIIDrQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI2eZRJ7Ar+JQCAggAgIIDgFTbOtkFPjqxAoYRHoq1SbyXKf/NRbBA5AqxQlv9aFVT4VcxUSrMGaSWifX2UjsVWQzn134yoLLbdJ0jTorVD+EuBUmtb3xXbBwLqtFZxwcWodYA5WhPQdDcQo0cD3o1vrsXPQARQR6ISSFnhFjPYdH9cO2LqUKV5pjFhIs2/1VPDS2eY7SWZN52DK3QknSj23S3ZW2s4TFEj/5C4ssbO7cWNWBjjaORnd17FMNgVtcRw8ITmLdGBOpFUwP8wIdiLGrXiyjfMLns74nztRelV30/v0DPlz0pZtOPygi/dy0qpbil3wtOFrtQBLEdvLNmt9ikQgGs3pJBS68eMJLu3jAU6rCIKycq0+E0eMXeHcseyMwgguTj2h4t+E4S7nU11lViBFqkSBKxE28+9fNlPvCsZ4WhQZ6TAW3E/jDy/ZSqmak5V7/khMlRPvtrxz71ivksH0iipPdJJkGi7SDEvETySBETiqIslUmsF0ZYeHR5wIBkB5V8zmi8RRZtpvDGbzuQ22V6sNk2mTDh+BRus7gNCoSGWYXWqNNp1PnznuYCJp9T+0mObcAijE7IQuhpYMeQPF+MUIlG5lmpNouzuygTf++xrKIjzP36DcthnMPeD/8LYWfzkuAeRodjl7Z1G6XLvBD5h+Xlq23WPjMcXUiiWYXxTREAQ1EWUf4A9twGcxHJ5AatbvQY3QUoS4a7LNuy17lF7G+O1SFDtGeHZXHHecaVpuAtqZEYeUpqy6ZzMJXtXE1JNl/UR9TtTordb1V5Pf45JTYKLI+SwxVQbRiTgfhulNc+E3tV1AEELZt4CKmh1OFJoJRtyREMfdVuP4rx7ywIoMYuWw8CRqJ3qSmdwz2kmL2pfJNn6vDfN6rNa+sXWErOJ7naSAKQH2CJfnkCOFxkKfwjbOcNRbnGKah8NyWu6xqlv7Y4xEJYqmPahGHmrSfdAt3mpc5zD74DvetLIczcadKaLH7mp6h98xHayvXh0UE7ERHeskfSPrLxL9A3V1RZXDOtcZFWSKHzokuXMDF9OnrcMYDzYgtzof4ReY2t1ldGF7phYINhDlUNyhzyjwyWQbdkxr/+FtWq8Sbm7o2zMTby48c25gnqD9U8RTAO+bY3oV3dQ4bpAOzWdzVmFjESUFx0xVwbTSJGXdkH4YmD5He+xwxTa0Je0HE5+ui5dbP1gxUY+pCGLOhGMIIFQQYJKoZIhvcNAQcBoIIFMgSCBS4wggUqMIIFJgYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECGYAccNFWW6kAgIIAASCBMgbXw69iyx73RGWS3FYeuvF5L1VWXQGrDLdUGwa3SdovXxmP1pKBAb82UuiydXDpKSVCmefeEQTs6ucEFRmXrDIldNanqUwbydy3GSJ+4iNsVQHbFgNppH4e90L7BlLcZ3MzSrVEwxWVMHq+XLqTKf3X3QyrmA3mmF96+Nd+icpDIktd+/h2BHnSXHNP0QfVH27H4DwbMDijttXY0JB+8qP9m25Wn4zkmOPEUhrY4Ptv2I08eHFAuNI0jWUwfRhC4FDbUdwFb0aZjA3Te6uYTsu2zAlmg9HuqsD/Ef/wkBEKZLBkjiXa/niFVrwELXhWZDPBAuo+/1UbzXglsW4QDU4LbUutcs6DLag1vLe40a2LO1ODQm7Zw0bxLkb3f/ry6ZFYvO78XmHo4c/oQf4KPUtM2bLz5q7uOxAx07vHYaU2BVt3NjgiIO5VVKjw0075GdgFxwPvYncv1fsC5jSIkX43GuzEtoBTpJKDYb2nhKbN9XWixwGOhUBTK3WYBhn+uaMJs4l3EgkDtK9tsUs5VQQHawj0WrGS1mQhaBfcyZzv4wSn0d3JUO2CN0e9EReJcQvsEnwUvohilOvjDHHhTq8Kp4XU4jbq7TAKqxs3TOmdoskRykn9oKUPExJVhJQonFT3ietV5BHrnN/QoDCSeOR80ZxvWHrQDz3Hm1ygiHd8LYmN4IjiD8b28ZrCALifWxh0WmIYtLZrUjMZavPh+caWH9IG32fTxV9b1bgJD8vWqscj9jCjeMJvkKQo8PFg1kMAxt1u+bIyktTq42O9qxwGrdqEMeBzXxDJMMaRIH3m9LNZ/P5Nk4/hMURhCZJtRtNfOVTK+Q6kKgsdK2EHcuEnp/qBefZjve+xmitbF1W7C4+B7b2JNBacdIm1nE56DwglT/IUk65JrNFP3rf4c5ic76LCQrvyfLiKCGaqcihM9siLVFPYdrnr8TlGbCFnGbpBqMQA5MtZQaDUug50PJtdxlgfwWH4qliimgchCaZbSTcgN5YTguSe16uUSusHD+r6XdtI0939uDILXJjQMczhIKNw8w0Tn4Z3/g2KlB6cwbtaglnnO4a/USh0cPC1a581byNqeFoMi+mAhqfKkwdDuti4GX7OrhkUOkiRjEUXdcckpmmIsyamH/g1dq3CNFXFNIgRRrzIDo4Opr3Ip2VE/4BDQoo/+Rybzxh8bsHgCEujQf8urGxjGyd2ulHoXzHWhz7pPPuY5UN6dC9WZmOQDVous/1nhYThoLVVc61Rk6d83+Ac7iRg4bY5q/73J4HvPMmrTOOOqqn3wc9Pe5ibEy4tFaYnim4p1ZRm8YcwosZmuFPdsP6G5l5qt6uOyr2+qNpXIBkDpG7I6Ls10O7L3PQAX9zRGfcz6Ds0KtuDrLpaVvhuXpewsBwpo1lmhv9bAa4ppBuWznmKigX+vYojSxd/eCRAtMs+Lx6ppZsYNVhbdEIGKXSGwG98sSTZkoLHBMkUW7S8jpeSCHZWEFBUOPJQzAr5cW1w+RAs33cGUygZ5XEEx4DeW8MnO4lCuP+VDOwu3TAKhzAD+qCyXbLEzWiyL5fq3XL+YJtoAc8Mra9lK6jDqzq4u+PLNoYY+kWTBhCyRZ+PfzcXLry8pxuP5E6VtRgfYcxJTAjBgkqhkiG9w0BCRUxFgQUOEXV6IFYGpCSHi0MPHz4b3W0KOQwMTAhMAkGBSsOAwIaBQAEFBa+SV9FU2UObo+nYKdyt/kZVw6FBAgey4GonFtJ2gICCAA= - JWK_PRIVATE_RSA_PKCS8: "-----BEGIN PRIVATE KEY----- - MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQCmN2yzxloN8Qfo - rpTsZ5bafEOpHgg/Tj1+TV8rSWd2KZswxUF0+/+FKmbxPwS0EPGtR2LU4dl8yFSL - EZq637edDgYb2czbj2jGEK3Gqo28ReuZBEapzPIvG6H58qf0WD76FL1SlrMel9UA - WcHloJ9eg2E+4jygHLIUowpo5WAc2o/k0ESppuIt+1kPdb+WwUI8a7OvhWnRhLvN - LaENhJwLag4y7isZTUtwxl/f2nfXncKrttLZeHpj6/DmnDMVhl2NDEOfzHwEbd8n - qPxMYtdCxsofXbXz8dxQlG8zB2ltRAbme8DYZdWoup3CnTngvOT38H9/WVWuY4q4 - eNM0erjzAgMBAAECggEBAJLA5rnHTCV5BRmcYqJjR566DmcXvAJgywxjtb4bPjzm - uT2TO5rVD6J8cI1ZrYZqW2c5WvpIOeThXzu2HF4YPh5tjlkysJu9/6y4dyWr2h47 - warFSrqK191d0WJEq6Oh8mCMxSdRJO7C8W4w0XAzo+Inr0l9KDfZfiWYWg2JT5XI - ubibKKq6P2KxND0UVlYbRsp3fv2loEL9WM5H2bjA/oSbQ4tSJtobpjlsQOHmaxbP - XhvsIV3Dr2ksDuLEhm0vfXnEGRzNk3HV3gLNT741YEP3Sp2ZRjd5U1qFn0D+eWe0 - 4LfDX9auGQCnfjZTHvu4qghX7JxcF40omjmtgkRmZ/kCgYEA4A5nU4ahEww7B65y - uzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ++wwf - pRwHvSxtNU9qXb8ewo+BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3In - KF4JvIlchyqs0RQ8wx7lULqwnn0CgYEAven83GM6SfrmO+TBHbjTk6JhP/3CMsIv - mSdo4KrbQNvp4vHO3w1/0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEB - pxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA+k4UoH/eQmGKGK44TRz - Yj5hZYGWIC8CgYEAlmmU/AG5SGxBhJqb8wxfNXDPJjf//i92BgJT2Vp4pskBbr5P - GoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ+m0/XSWx13v9t9DIbheA - tgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpECgYEA - mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe//EjuCBbwHfcT8OG3hWOv8vpzo - kQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p+AF2p6Yfahscjtq+GY9cB85Nx - Ly2IXCC0PF++Sq9LOrTE9QV988SJy/yUrAjcZ5MmECkCgYEAldHXIrEmMZVaNwGz - DF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uY - iqewXfCKw/UngrJt8Xwfq1Zruz0YY869zPN4GiE9+9rzdZB33RBw8kIOquY3MK74 - FMwCihYx/LiU2YTHkaoJ3ncvtvg= - -----END PRIVATE KEY-----" - JWK_PUB_RSA: '{"kid":"ex","kty":"RSA","key_ops":["sign","verify","wrapKey","unwrapKey","encrypt","decrypt"],"n":"p2VQo8qCfWAZmdWBVaYuYb-a-tWWm78K6Sr9poCvNcmv8rUPSLACxitQWR8gZaSH1DklVkqz-Ed8Cdlf8lkDg4Ex5tkB64jRdC1Uvn4CDpOH6cp-N2s8hTFLqy9_YaDmyQS7HiqthOi9oVjil1VMeWfaAbClGtFt6UnKD0Vb_DvLoWYQSqlhgBArFJi966b4E1pOq5Ad02K8pHBDThlIIx7unibLehhDU6q3DCwNH_OOLx6bgNtmvGYJDd1cywpkLQ3YzNCUPWnfMBJRP3iQP_WI21uP6cvo0DqBPBM4wvVzHbCT0vnIflwkbgEWkq1FprqAitZlop9KjLqzjp9vyQ","e":"AQAB"}' - JWK_PUB_ECDSA: '{"kid":"https://kv-test-mj.vault.azure.net/keys/ec-p-521/e3d0e9c179b54988860c69c6ae172c65","kty":"EC","key_ops":["sign","verify"],"crv":"P-521","x":"AedOAtb7H7Oz1C_cPKI_R4CN_eai5nteY6KFW07FOoaqgQfVCSkQDK22fCOiMT_28c8LZYJRsiIFz_IIbQUW7bXj","y":"AOnchHnmBphIWXvanmMAmcCDkaED6ycW8GsAl9fQ43BMVZTqcTkJYn6vGnhn7MObizmkNSmgZYTwG-vZkIg03HHs"}' - - JWK_PRIV_RSA: '{"kty" : "RSA","kid" : "cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df","use" : "sig","n" : "pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w","e" : "AQAB","d" : "ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q","p" : "4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0","q" : "ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8","dp" : "lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE","dq" : "mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk","qi" : "ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg"}' - JWK_PRIV_ECDSA: '{"kty": "EC","kid": "rie3pHe8u8gjSa0IaJfqk7_iEfHeYfDYx-Bqi7vQc0s","crv": "P-256","x": "fDjg3Nq4jPf8IOZ0277aPVal_8iXySnzLUJAZghUzZM","y": "d863PeyBOK_Q4duiSmWwgIRzi1RPlFZTR-vACMlPg-Q","d": "jJs5xsoHUetdMabtt8H2KyX5T92nGul1chFeMT5hlr0"}' - - TEST_LOWERCASE_STRING: i am a lowercase string - - TEST_YAML_STRING: | - name: test-object - type: example - properties: - key1: value1 - key2: value2 - numbers: - - 1 - - 2 - - 3 - - TEST_JSON_DATA: '{ - "id": "f1bc87fc-99cf-48d2-b289-7cf578152f9a", - "name": "test", - "description": "", - "type": "secret-manager", - "slug": "test-o-bto", - "autoCapitalization": false, - "orgId": "601815be-6884-4ee4-86c7-bfc6415f2123", - "createdAt": "2025-03-26T01:32:39.890Z", - "updatedAt": "2025-03-26T01:32:41.688Z", - "version": 3, - "upgradeStatus": null, - "pitVersionLimit": 10, - "kmsCertificateKeyId": null, - "auditLogsRetentionDays": null, - "_id": "f1bc87fc-99cf-48d2-b289-7cf578152f9a", - "environments": [ - { - "name": "Development", - "slug": "dev", - "id": "cbb62f88-44cb-4c29-975a-871f8d7d303b" - }, - { - "name": "Staging", - "slug": "staging", - "id": "c933a63d-418a-4d5c-a7d1-91b74d3ee2eb" - }, - { - "name": "Production", - "slug": "prod", - "id": "0b70125e-47d5-46e8-a03e-a3105df05d37" - } - ] - }' diff --git a/k8-operator/config/samples/crd/pushsecret/source-secret.yaml b/k8-operator/config/samples/crd/pushsecret/source-secret.yaml deleted file mode 100644 index 88fd3e0d26..0000000000 --- a/k8-operator/config/samples/crd/pushsecret/source-secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: push-secret-source-secret - namespace: default -stringData: - ENCRYPTION_KEY: secret-encryption-key - API_URL: https://example.com/api - REGION: us-east-1 diff --git a/k8-operator/config/samples/customCaCertificate.yaml b/k8-operator/config/samples/customCaCertificate.yaml deleted file mode 100644 index 67aac47436..0000000000 --- a/k8-operator/config/samples/customCaCertificate.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: custom-ca-certificate -type: Opaque -stringData: - ca.crt: | - -----BEGIN CERTIFICATE----- - MIIEZzCCA0+gAwIBAgIUDk9+HZcMHppiNy0TvoBg8/aMEqIwDQYJKoZIhvcNAQEL - BQAwDTELMAkGA1UEChMCUEgwHhcNMjQxMDI1MTU0MjAzWhcNMjUxMDI1MjE0MjAz - WjAfMR0wGwYDVQQDExRob3N0LmRvY2tlci5pbnRlcm5hbDCCASIwDQYJKoZIhvcN - AQEBBQADggEPADCCAQoCggEBALPBCPhZHCizZWbyGI0LzTLYprsvTMoeZBeR84lj - hv/VDUkH3K6jw5g2o2eXg4Aisb/GcQkTxHjmGlUKymhrLBH9zUHjh1yFKPUJdSy1 - X4YCG+ABNQ8obrTZM/ry5WRHF/KcFIELt/4JpY8OWkxEIisYfe98vObsGH39spcN - c3x3Oo4vsBd6ETQOjrXL81kXLoNZoHdsVIU0ZwNpXR1geI477ce3eHOuEhBvKfUR - ugRdmX6xUhFNZcKRYiv3RRkm/vnuxWx2CxsecJ0BRoB7nT00gJkkxbt1b5MrPFF4 - XIdhWIdxSMdMUwtnEo9hT2mzUCkJohLEeqwivZfewghLo88CAwEAAaOCAaswggGn - MAkGA1UdEwQCMAAwXgYDVR0fBFcwVTBToFGgT4ZNaHR0cDovL2xvY2FsaG9zdDo4 - MDgwL2FwaS92MS9wa2kvY3JsLzY2ZDk3OTNkLWMzMTYtNDNhZS05N2RiLTkzNDBj - ZmJkNTYxNy9kZXIwHwYDVR0jBBgwFoAU3+CiMP0BF+BnjXBYawENOrnQ+q8wHQYD - VR0OBBYEFKUIOV5qAwf0Bd1dMnxIYYglcZT1MIGdBggrBgEFBQcBAQSBkDCBjTCB - igYIKwYBBQUHMAKGfmh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hcGkvdjEvcGtpL2Nh - L2EyNDIyZTdlLTAwZWYtNDlhZC1iY2ZhLTUxMzZhODQxNjEyZC9jZXJ0aWZpY2F0 - ZXMvYWJhNTRjNGEtNjYxOS00MDFlLTk2YTYtN2UwN2MxNzdjOTI4L2RlcjARBgNV - HSAECjAIMAYGBFUdIAAwDgYDVR0PAQH/BAQDAgWgMBYGA1UdJQEB/wQMMAoGCCsG - AQUFBwMBMB8GA1UdEQQYMBaCFGhvc3QuZG9ja2VyLmludGVybmFsMA0GCSqGSIb3 - DQEBCwUAA4IBAQAtUUloE1xU+BNF2Fjc/PSOesHz6dFCzGWvCc0QZceK/6v4EWuZ - vEU07brGrufhwJ3UnOXO4zxIl3UplQ1S14Xrba4R69Fp3dggFV39ON8R5lpL9hZe - cSRywBycKil2C7SytPsjJtvCXY6RXb6YxFse6rDk0qoMwD/g/ou3JIEpgtB2cPuX - Blg9ZWAsaOtKhtmi1IyLjwgHDd86XhMzd9osOna1iuARZMZs80ek5b5H4cdFIBTl - rwIQc6b9ZbHAD56NttCIE18YmLWbYBCdvga0Qmqwr2fRPg2DE9qoyF1ZJVbwisOc - cJ23MFdpsXKiIoQyDmpZl5jg8aKD/jh0wdUx - -----END CERTIFICATE----- diff --git a/k8-operator/config/samples/deployment.yaml b/k8-operator/config/samples/deployment.yaml deleted file mode 100644 index 78de440329..0000000000 --- a/k8-operator/config/samples/deployment.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment - labels: - app: nginx - annotations: - secrets.infisical.com/auto-reload: "true" -spec: - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:1.14.2 - envFrom: - - secretRef: - name: managed-secret - ports: - - containerPort: 80 \ No newline at end of file diff --git a/k8-operator/config/samples/infisical-config.yaml b/k8-operator/config/samples/infisical-config.yaml deleted file mode 100644 index 90f5e49242..0000000000 --- a/k8-operator/config/samples/infisical-config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: infisical-operator-system ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: infisical-config - namespace: infisical-operator-system -data: - hostAPI: "https://example.com/api" diff --git a/k8-operator/config/samples/k8s-auth/cluster-role-binding.yaml b/k8-operator/config/samples/k8s-auth/cluster-role-binding.yaml deleted file mode 100644 index c1adb56e49..0000000000 --- a/k8-operator/config/samples/k8s-auth/cluster-role-binding.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: role-tokenreview-binding - namespace: default -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: system:auth-delegator -subjects: - - kind: ServiceAccount - name: infisical-auth - namespace: default diff --git a/k8-operator/config/samples/k8s-auth/infisical-service-account.yaml b/k8-operator/config/samples/k8s-auth/infisical-service-account.yaml deleted file mode 100644 index 60c7f14fda..0000000000 --- a/k8-operator/config/samples/k8s-auth/infisical-service-account.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: infisical-auth - namespace: default \ No newline at end of file diff --git a/k8-operator/config/samples/k8s-auth/sample.yaml b/k8-operator/config/samples/k8s-auth/sample.yaml deleted file mode 100644 index 91f910aff5..0000000000 --- a/k8-operator/config/samples/k8s-auth/sample.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: secrets.infisical.com/v1alpha1 -kind: InfisicalSecret -metadata: - name: infisicalsecret-sample - labels: - label-to-be-passed-to-managed-secret: sample-value - annotations: - example.com/annotation-to-be-passed-to-managed-secret: "sample-value" -spec: - hostAPI: https://app.infisical.com/api - resyncInterval: 10 - authentication: - # Native Kubernetes Auth - kubernetesAuth: - identityId: <> - serviceAccountRef: - name: infisical-auth - namespace: default - - # secretsScope is identical to the secrets scope in the universalAuth field in this sample. - secretsScope: - projectSlug: dsf-gpb-t - envSlug: dev - secretsPath: "/" - recursive: true - - - managedSecretReference: - secretName: managed-secret-k8s - secretNamespace: default - creationPolicy: "Orphan" ## Owner | Orphan - # secretType: kubernetes.io/dockerconfigjson \ No newline at end of file diff --git a/k8-operator/config/samples/k8s-auth/service-account-token.yaml b/k8-operator/config/samples/k8s-auth/service-account-token.yaml deleted file mode 100644 index 894c98b06b..0000000000 --- a/k8-operator/config/samples/k8s-auth/service-account-token.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -type: kubernetes.io/service-account-token -metadata: - name: infisical-auth-token - annotations: - kubernetes.io/service-account.name: "infisical-auth" \ No newline at end of file diff --git a/k8-operator/config/samples/ldapAuthIdentitySecret.yaml b/k8-operator/config/samples/ldapAuthIdentitySecret.yaml deleted file mode 100644 index 95e258caa4..0000000000 --- a/k8-operator/config/samples/ldapAuthIdentitySecret.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ldap-auth-credentials -type: Opaque -stringData: - username: - password: diff --git a/k8-operator/config/samples/serviceTokenSecret.yaml b/k8-operator/config/samples/serviceTokenSecret.yaml deleted file mode 100644 index dc03abcc2c..0000000000 --- a/k8-operator/config/samples/serviceTokenSecret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# apiVersion: v1 -# kind: Secret -# metadata: -# name: service-token -# type: Opaque -# data: -# infisicalToken: \ No newline at end of file diff --git a/k8-operator/config/samples/universalAuthIdentitySecret.yaml b/k8-operator/config/samples/universalAuthIdentitySecret.yaml deleted file mode 100644 index 741de34ee8..0000000000 --- a/k8-operator/config/samples/universalAuthIdentitySecret.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: universal-auth-credentials -type: Opaque -stringData: - clientId: your-client-id-here - clientSecret: your-client-secret-here \ No newline at end of file diff --git a/k8-operator/go.mod b/k8-operator/go.mod deleted file mode 100644 index 7d0e514633..0000000000 --- a/k8-operator/go.mod +++ /dev/null @@ -1,152 +0,0 @@ -module github.com/Infisical/infisical/k8-operator - -go 1.24.0 - -require ( - github.com/Masterminds/sprig/v3 v3.3.0 - github.com/aws/smithy-go v1.22.4 - github.com/go-logr/logr v1.4.2 - github.com/go-resty/resty/v2 v2.16.5 - github.com/google/uuid v1.6.0 - github.com/infisical/go-sdk v0.5.99 - github.com/lestrrat-go/jwx/v2 v2.1.6 - github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.36.1 - github.com/sethvargo/go-password v0.3.1 - golang.org/x/crypto v0.36.0 - gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.33.3 - k8s.io/apimachinery v0.33.3 - k8s.io/client-go v0.33.3 - sigs.k8s.io/controller-runtime v0.21.0 - software.sslmate.com/src/go-pkcs12 v0.6.0 -) - -replace github.com/google/go-cmp v0.7.0 => github.com/google/go-cmp v0.6.0 - -require ( - cel.dev/expr v0.19.1 // indirect - cloud.google.com/go/auth v0.7.0 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect - cloud.google.com/go/compute/metadata v0.5.0 // indirect - cloud.google.com/go/iam v1.1.11 // indirect - dario.cat/mergo v1.0.1 // indirect - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.27.2 // indirect - github.com/aws/aws-sdk-go-v2/config v1.27.18 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.18 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.9.11 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-logr/zapr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/gofrs/flock v0.8.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/google/btree v1.1.3 // indirect - github.com/google/cel-go v0.23.2 // indirect - github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect - github.com/google/s2a-go v0.1.7 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.5 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/huandu/xstrings v1.5.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/lestrrat-go/blackmagic v1.0.3 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.6 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oracle/oci-go-sdk/v65 v65.95.2 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.22.0 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/segmentio/asm v1.2.0 // indirect - github.com/shopspring/decimal v1.4.0 // indirect - github.com/sony/gobreaker v0.5.0 // indirect - github.com/spf13/cast v1.7.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.3.0 // indirect - github.com/x448/float16 v0.8.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect - go.opentelemetry.io/proto/otlp v1.4.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.26.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.188.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect - google.golang.org/grpc v1.68.1 // indirect - google.golang.org/protobuf v1.36.5 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/apiextensions-apiserver v0.33.0 // indirect - k8s.io/apiserver v0.33.0 // indirect - k8s.io/component-base v0.33.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/k8-operator/go.sum b/k8-operator/go.sum deleted file mode 100644 index 3b4a648248..0000000000 --- a/k8-operator/go.sum +++ /dev/null @@ -1,462 +0,0 @@ -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go/auth v0.7.0 h1:kf/x9B3WTbBUHkC+1VS8wwwli9TzhSt0vSTVBmMR8Ts= -cloud.google.com/go/auth v0.7.0/go.mod h1:D+WqdrpcjmiCgWrXmLLxOVq1GACoE36chW6KXoEvuIw= -cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= -cloud.google.com/go/iam v1.1.11 h1:0mQ8UKSfdHLut6pH9FM3bI55KWR46ketn0PuXleDyxw= -cloud.google.com/go/iam v1.1.11/go.mod h1:biXoiLWYIKntto2joP+62sd9uW5EpkZmKIvfNcTWlnQ= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= -github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/aws/aws-sdk-go-v2 v1.27.2 h1:pLsTXqX93rimAOZG2FIYraDQstZaaGVVN4tNw65v0h8= -github.com/aws/aws-sdk-go-v2 v1.27.2/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/config v1.27.18 h1:wFvAnwOKKe7QAyIxziwSKjmer9JBMH1vzIL6W+fYuKk= -github.com/aws/aws-sdk-go-v2/config v1.27.18/go.mod h1:0xz6cgdX55+kmppvPm2IaKzIXOheGJhAufacPJaXZ7c= -github.com/aws/aws-sdk-go-v2/credentials v1.17.18 h1:D/ALDWqK4JdY3OFgA2thcPO1c9aYTT5STS/CvnkqY1c= -github.com/aws/aws-sdk-go-v2/credentials v1.17.18/go.mod h1:JuitCWq+F5QGUrmMPsk945rop6bB57jdscu+Glozdnc= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5 h1:dDgptDO9dxeFkXy+tEgVkzSClHZje/6JkPW5aZyEvrQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.5/go.mod h1:gjvE2KBUgUQhcv89jqxrIxH9GaKs1JbZzWejj/DaHGA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9 h1:cy8ahBJuhtM8GTTSyOkfy6WVPV1IE+SS5/wfXUYuulw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.9/go.mod h1:CZBXGLaJnEZI6EVNcPd7a6B5IC5cA/GkRWtu9fp3S6Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9 h1:A4SYk07ef04+vxZToz9LWvAXl9LW0NClpPpMsi31cz0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.9/go.mod h1:5jJcHuwDagxN+ErjQ3PU3ocf6Ylc/p9x+BLO/+X4iXw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11 h1:o4T+fKxA3gTMcluBNZZXE9DNaMkJuUL1O3mffCUjoJo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.11/go.mod h1:84oZdJ+VjuJKs9v1UTC9NaodRZRseOXCTgku+vQJWR8= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.11 h1:gEYM2GSpr4YNWc6hCd5nod4+d4kd9vWIAWrmGuLdlMw= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.11/go.mod h1:gVvwPdPNYehHSP9Rs7q27U1EU+3Or2ZpXvzAYJNh63w= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 h1:iXjh3uaH3vsVcnyZX7MqCoCfcyxIrVE9iOQruRaWPrQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5/go.mod h1:5ZXesEuy/QcO0WUnt+4sDkxhdXRHTu2yG0uCSH8B6os= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 h1:M/1u4HBpwLuMtjlxuI2y6HoVLzF5e2mfxHCg7ZVMYmk= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.12/go.mod h1:kcfd+eTdEi/40FIbLq4Hif3XMXnl5b/+t/KTfLt9xIk= -github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= -github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= -github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= -github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= -github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= -github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= -github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA= -github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= -github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/infisical/go-sdk v0.5.99 h1:trvn7JhKYuSzDkc44h+yqToVjclkrRyP42t315k5kEE= -github.com/infisical/go-sdk v0.5.99/go.mod h1:j2D2a5WPNdKXDfHO+3y/TNyLWh5Aq9QYS7EcGI96LZI= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lestrrat-go/blackmagic v1.0.3 h1:94HXkVLxkZO9vJI/w2u1T0DAoprShFd13xtnSINtDWs= -github.com/lestrrat-go/blackmagic v1.0.3/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k= -github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVfecA= -github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= -github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/oracle/oci-go-sdk/v65 v65.95.2 h1:0HJ0AgpLydp/DtvYrF2d4str2BjXOVAeNbuW7E07g94= -github.com/oracle/oci-go-sdk/v65 v65.95.2/go.mod h1:u6XRPsw9tPziBh76K7GrrRXPa8P8W3BQeqJ6ZZt9VLA= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= -github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU= -github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs= -github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= -github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= -github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= -go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= -go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= -gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw= -google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= -k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= -k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= -k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= -k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= -k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc= -k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8= -k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= -k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= -k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk= -k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= -sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -software.sslmate.com/src/go-pkcs12 v0.6.0 h1:f3sQittAeF+pao32Vb+mkli+ZyT+VwKaD014qFGq6oU= -software.sslmate.com/src/go-pkcs12 v0.6.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= diff --git a/k8-operator/hack/boilerplate.go.txt b/k8-operator/hack/boilerplate.go.txt deleted file mode 100644 index 221dcbe0bd..0000000000 --- a/k8-operator/hack/boilerplate.go.txt +++ /dev/null @@ -1,15 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ \ No newline at end of file diff --git a/k8-operator/internal/api/api.go b/k8-operator/internal/api/api.go deleted file mode 100644 index 2e57d59308..0000000000 --- a/k8-operator/internal/api/api.go +++ /dev/null @@ -1,233 +0,0 @@ -package api - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/Infisical/infisical/k8-operator/internal/model" - "github.com/go-resty/resty/v2" -) - -const USER_AGENT_NAME = "k8-operator" - -func CallGetServiceTokenDetailsV2(httpClient *resty.Client) (GetServiceTokenDetailsResponse, error) { - var tokenDetailsResponse GetServiceTokenDetailsResponse - response, err := httpClient. - R(). - SetResult(&tokenDetailsResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%v/v2/service-token", API_HOST_URL)) - - if err != nil { - return GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return GetServiceTokenDetailsResponse{}, fmt.Errorf("CallGetServiceTokenDetails: Unsuccessful response: [response=%s]", response) - } - - return tokenDetailsResponse, nil -} - -func CallGetServiceTokenAccountDetailsV2(httpClient *resty.Client) (ServiceAccountDetailsResponse, error) { - var serviceAccountDetailsResponse ServiceAccountDetailsResponse - response, err := httpClient. - R(). - SetResult(&serviceAccountDetailsResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%v/v2/service-accounts/me", API_HOST_URL)) - - if err != nil { - return ServiceAccountDetailsResponse{}, fmt.Errorf("CallGetServiceTokenAccountDetailsV2: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return ServiceAccountDetailsResponse{}, fmt.Errorf("CallGetServiceTokenAccountDetailsV2: Unsuccessful response: [response=%s]", response) - } - - return serviceAccountDetailsResponse, nil -} - -func CallUniversalMachineIdentityLogin(request MachineIdentityUniversalAuthLoginRequest) (MachineIdentityDetailsResponse, error) { - var machineIdentityDetailsResponse MachineIdentityDetailsResponse - - response, err := resty.New(). - R(). - SetResult(&machineIdentityDetailsResponse). - SetBody(request). - SetHeader("User-Agent", USER_AGENT_NAME). - Post(fmt.Sprintf("%v/v1/auth/universal-auth/login", API_HOST_URL)) - - if err != nil { - return MachineIdentityDetailsResponse{}, fmt.Errorf("CallUniversalMachineIdentityLogin: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return MachineIdentityDetailsResponse{}, fmt.Errorf("CallUniversalMachineIdentityLogin: Unsuccessful response: [response=%s]", response) - } - - return machineIdentityDetailsResponse, nil -} - -func CallUniversalMachineIdentityRefreshAccessToken(request MachineIdentityUniversalAuthRefreshRequest) (MachineIdentityDetailsResponse, error) { - var universalAuthRefreshResponse MachineIdentityDetailsResponse - - response, err := resty.New(). - R(). - SetResult(&universalAuthRefreshResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - SetBody(request). - Post(fmt.Sprintf("%v/v1/auth/token/renew", API_HOST_URL)) - - if err != nil { - return MachineIdentityDetailsResponse{}, fmt.Errorf("CallUniversalAuthRefreshAccessToken: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return MachineIdentityDetailsResponse{}, fmt.Errorf("CallUniversalAuthRefreshAccessToken: Unsuccessful response [%v %v] [status-code=%v] [response=%v]", response.Request.Method, response.Request.URL, response.StatusCode(), response.String()) - } - - return universalAuthRefreshResponse, nil -} - -func CallGetServiceAccountWorkspacePermissionsV2(httpClient *resty.Client) (ServiceAccountWorkspacePermissions, error) { - var serviceAccountWorkspacePermissionsResponse ServiceAccountWorkspacePermissions - response, err := httpClient. - R(). - SetResult(&serviceAccountWorkspacePermissionsResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%v/v2/service-accounts//permissions/workspace", API_HOST_URL)) - - if err != nil { - return ServiceAccountWorkspacePermissions{}, fmt.Errorf("CallGetServiceAccountWorkspacePermissionsV2: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return ServiceAccountWorkspacePermissions{}, fmt.Errorf("CallGetServiceAccountWorkspacePermissionsV2: Unsuccessful response: [response=%s]", response) - } - - return serviceAccountWorkspacePermissionsResponse, nil -} - -func CallGetServiceAccountKeysV2(httpClient *resty.Client, request GetServiceAccountKeysRequest) (GetServiceAccountKeysResponse, error) { - var serviceAccountKeysResponse GetServiceAccountKeysResponse - response, err := httpClient. - R(). - SetResult(&serviceAccountKeysResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%v/v2/service-accounts/%v/keys", API_HOST_URL, request.ServiceAccountId)) - - if err != nil { - return GetServiceAccountKeysResponse{}, fmt.Errorf("CallGetServiceAccountKeysV2: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return GetServiceAccountKeysResponse{}, fmt.Errorf("CallGetServiceAccountKeysV2: Unsuccessful response: [response=%s]", response) - } - - return serviceAccountKeysResponse, nil -} - -func CallGetProjectByID(httpClient *resty.Client, request GetProjectByIDRequest) (GetProjectByIDResponse, error) { - - var projectResponse GetProjectByIDResponse - - response, err := httpClient. - R().SetResult(&projectResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%s/v1/workspace/%s", API_HOST_URL, request.ProjectID)) - - if err != nil { - return GetProjectByIDResponse{}, fmt.Errorf("CallGetProject: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return GetProjectByIDResponse{}, fmt.Errorf("CallGetProject: Unsuccessful response: [response=%s]", response) - } - - return projectResponse, nil - -} - -func CallGetProjectByIDv2(httpClient *resty.Client, request GetProjectByIDRequest) (model.Project, error) { - var projectResponse model.Project - - response, err := httpClient. - R().SetResult(&projectResponse). - SetHeader("User-Agent", USER_AGENT_NAME). - Get(fmt.Sprintf("%s/v2/workspace/%s", API_HOST_URL, request.ProjectID)) - - if err != nil { - return model.Project{}, fmt.Errorf("CallGetProject: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - return model.Project{}, fmt.Errorf("CallGetProject: Unsuccessful response: [response=%s]", response) - } - - return projectResponse, nil - -} - -func CallSubscribeProjectEvents(httpClient *resty.Client, projectId, secretsPath, envSlug, token string) (*http.Response, error) { - conditions := &SubscribeProjectEventsRequestCondition{ - SecretPath: secretsPath, - EnvironmentSlug: envSlug, - } - - body, err := json.Marshal(&SubscribeProjectEventsRequest{ - ProjectID: projectId, - Register: []SubscribeProjectEventsRequestRegister{ - { - Event: "secret:create", - Conditions: conditions, - }, - { - Event: "secret:update", - Conditions: conditions, - }, - { - Event: "secret:delete", - Conditions: conditions, - }, - { - Event: "secret:import-mutation", - Conditions: conditions, - }, - }, - }) - - if err != nil { - return nil, fmt.Errorf("CallSubscribeProjectEvents: Unable to marshal body [err=%s]", err) - } - - response, err := httpClient. - R(). - SetDoNotParseResponse(true). - SetHeader("User-Agent", USER_AGENT_NAME). - SetHeader("Content-Type", "application/json"). - SetHeader("Accept", "text/event-stream"). - SetHeader("Connection", "keep-alive"). - SetHeader("Authorization", fmt.Sprint("Bearer ", token)). - SetBody(body). - Post(fmt.Sprintf("%s/v1/events/subscribe/project-events", API_HOST_URL)) - - if err != nil { - return nil, fmt.Errorf("CallSubscribeProjectEvents: Unable to complete api request [err=%s]", err) - } - - if response.IsError() { - data := struct { - Message string `json:"message"` - }{} - - if err := json.NewDecoder(response.RawBody()).Decode(&data); err != nil { - return nil, err - } - - return nil, fmt.Errorf("CallSubscribeProjectEvents: Unsuccessful response: [message=%s]", data.Message) - } - - return response.RawResponse, nil -} diff --git a/k8-operator/internal/api/models.go b/k8-operator/internal/api/models.go deleted file mode 100644 index 49e1a8c8ce..0000000000 --- a/k8-operator/internal/api/models.go +++ /dev/null @@ -1,225 +0,0 @@ -package api - -import ( - "time" - - "github.com/Infisical/infisical/k8-operator/internal/model" -) - -type GetEncryptedWorkspaceKeyRequest struct { - WorkspaceId string `json:"workspaceId"` -} - -type GetEncryptedWorkspaceKeyResponse struct { - ID string `json:"_id"` - EncryptedKey string `json:"encryptedKey"` - Nonce string `json:"nonce"` - Sender struct { - ID string `json:"_id"` - Email string `json:"email"` - RefreshVersion int `json:"refreshVersion"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - V int `json:"__v"` - FirstName string `json:"firstName"` - LastName string `json:"lastName"` - PublicKey string `json:"publicKey"` - } `json:"sender"` - Receiver string `json:"receiver"` - Workspace string `json:"workspace"` - V int `json:"__v"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} - -type GetEncryptedSecretsV3Request struct { - Environment string `json:"environment"` - WorkspaceId string `json:"workspaceId"` - Recursive bool `json:"recursive"` - SecretPath string `json:"secretPath"` - IncludeImport bool `json:"include_imports"` - ETag string `json:"etag,omitempty"` -} - -type EncryptedSecretV3 struct { - ID string `json:"_id"` - Version int `json:"version"` - Workspace string `json:"workspace"` - Type string `json:"type"` - Tags []struct { - ID string `json:"_id"` - Name string `json:"name"` - Slug string `json:"slug"` - Workspace string `json:"workspace"` - } `json:"tags"` - Environment string `json:"environment"` - SecretKeyCiphertext string `json:"secretKeyCiphertext"` - SecretKeyIV string `json:"secretKeyIV"` - SecretKeyTag string `json:"secretKeyTag"` - SecretValueCiphertext string `json:"secretValueCiphertext"` - SecretValueIV string `json:"secretValueIV"` - SecretValueTag string `json:"secretValueTag"` - SecretCommentCiphertext string `json:"secretCommentCiphertext"` - SecretCommentIV string `json:"secretCommentIV"` - SecretCommentTag string `json:"secretCommentTag"` - Algorithm string `json:"algorithm"` - KeyEncoding string `json:"keyEncoding"` - Folder string `json:"folder"` - V int `json:"__v"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} - -type DecryptedSecretV3 struct { - ID string `json:"id"` - Workspace string `json:"workspace"` - Environment string `json:"environment"` - Version int `json:"version"` - Type string `json:"string"` - SecretKey string `json:"secretKey"` - SecretValue string `json:"secretValue"` - SecretComment string `json:"secretComment"` -} - -type ImportedSecretV3 struct { - Environment string `json:"environment"` - FolderId string `json:"folderId"` - SecretPath string `json:"secretPath"` - Secrets []EncryptedSecretV3 `json:"secrets"` -} - -type ImportedRawSecretV3 struct { - Environment string `json:"environment"` - FolderId string `json:"folderId"` - SecretPath string `json:"secretPath"` - Secrets []DecryptedSecretV3 `json:"secrets"` -} - -type GetEncryptedSecretsV3Response struct { - Secrets []EncryptedSecretV3 `json:"secrets"` - ImportedSecrets []ImportedSecretV3 `json:"imports,omitempty"` - Modified bool `json:"modified,omitempty"` - ETag string `json:"ETag,omitempty"` -} - -type GetDecryptedSecretsV3Response struct { - Secrets []DecryptedSecretV3 `json:"secrets"` - ETag string `json:"ETag,omitempty"` - Modified bool `json:"modified,omitempty"` - Imports []ImportedRawSecretV3 `json:"imports,omitempty"` -} - -type GetDecryptedSecretsV3Request struct { - ProjectID string `json:"workspaceId"` - ProjectSlug string `json:"workspaceSlug"` - Environment string `json:"environment"` - SecretPath string `json:"secretPath"` - Recursive bool `json:"recursive"` - ExpandSecretReferences bool `json:"expandSecretReferences"` - ETag string `json:"etag,omitempty"` -} - -type GetServiceTokenDetailsResponse struct { - ID string `json:"_id"` - Name string `json:"name"` - Workspace string `json:"workspace"` - Environment string `json:"environment"` - EncryptedKey string `json:"encryptedKey"` - Iv string `json:"iv"` - Tag string `json:"tag"` - SecretPath string `json:"secretPath"` -} - -type ServiceAccountDetailsResponse struct { - ServiceAccount struct { - ID string `json:"_id"` - Name string `json:"name"` - Organization string `json:"organization"` - PublicKey string `json:"publicKey"` - LastUsed time.Time `json:"lastUsed"` - ExpiresAt time.Time `json:"expiresAt"` - } `json:"serviceAccount"` -} - -type MachineIdentityDetailsResponse struct { - AccessToken string `json:"accessToken"` - ExpiresIn int `json:"expiresIn"` - AccessTokenMaxTTL int `json:"accessTokenMaxTTL"` - TokenType string `json:"tokenType"` -} - -type ServiceAccountWorkspacePermission struct { - ID string `json:"_id"` - ServiceAccount string `json:"serviceAccount"` - Workspace struct { - ID string `json:"_id"` - Name string `json:"name"` - AutoCapitalization bool `json:"autoCapitalization"` - Organization string `json:"organization"` - Environments []struct { - Name string `json:"name"` - Slug string `json:"slug"` - ID string `json:"_id"` - } `json:"environments"` - } `json:"workspace"` - Environment string `json:"environment"` - Read bool `json:"read"` - Write bool `json:"write"` -} - -type ServiceAccountWorkspacePermissions struct { - ServiceAccountWorkspacePermission []ServiceAccountWorkspacePermissions `json:"serviceAccountWorkspacePermissions"` -} - -type GetServiceAccountKeysRequest struct { - ServiceAccountId string `json:"id"` -} - -type MachineIdentityUniversalAuthLoginRequest struct { - ClientId string `json:"clientId"` - ClientSecret string `json:"clientSecret"` -} - -type MachineIdentityUniversalAuthRefreshRequest struct { - AccessToken string `json:"accessToken"` -} - -type ServiceAccountKey struct { - ID string `json:"_id"` - EncryptedKey string `json:"encryptedKey"` - Nonce string `json:"nonce"` - Sender string `json:"sender"` - ServiceAccount string `json:"serviceAccount"` - Workspace string `json:"workspace"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} - -type GetServiceAccountKeysResponse struct { - ServiceAccountKeys []ServiceAccountKey `json:"serviceAccountKeys"` -} - -type GetProjectByIDRequest struct { - ProjectID string -} - -type GetProjectByIDResponse struct { - Project model.Project `json:"workspace"` -} - -type SubscribeProjectEventsRequestRegister struct { - Event string `json:"event"` - Conditions *SubscribeProjectEventsRequestCondition `json:"conditions"` -} - -type SubscribeProjectEventsRequestCondition struct { - EnvironmentSlug string `json:"environmentSlug"` - SecretPath string `json:"secretPath"` -} - -type SubscribeProjectEventsRequest struct { - ProjectID string `json:"projectId"` - Register []SubscribeProjectEventsRequestRegister `json:"register"` -} - -type SubscribeProjectEventsResponse struct{} diff --git a/k8-operator/internal/api/variables.go b/k8-operator/internal/api/variables.go deleted file mode 100644 index 1dd255d422..0000000000 --- a/k8-operator/internal/api/variables.go +++ /dev/null @@ -1,4 +0,0 @@ -package api - -var API_HOST_URL string = "https://app.infisical.com/api" -var API_CA_CERTIFICATE string = "" diff --git a/k8-operator/internal/constants/constants.go b/k8-operator/internal/constants/constants.go deleted file mode 100644 index e5e2d8ff8d..0000000000 --- a/k8-operator/internal/constants/constants.go +++ /dev/null @@ -1,42 +0,0 @@ -package constants - -import "errors" - -const SERVICE_ACCOUNT_ACCESS_KEY = "serviceAccountAccessKey" -const SERVICE_ACCOUNT_PUBLIC_KEY = "serviceAccountPublicKey" -const SERVICE_ACCOUNT_PRIVATE_KEY = "serviceAccountPrivateKey" - -const INFISICAL_MACHINE_IDENTITY_CLIENT_ID = "clientId" -const INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET = "clientSecret" - -const INFISICAL_TOKEN_SECRET_KEY_NAME = "infisicalToken" -const SECRET_VERSION_ANNOTATION = "secrets.infisical.com/version" // used to set the version of secrets via Etag -const OPERATOR_SETTINGS_CONFIGMAP_NAME = "infisical-config" -const OPERATOR_SETTINGS_CONFIGMAP_NAMESPACE = "infisical-operator-system" -const INFISICAL_DOMAIN = "https://app.infisical.com/api" - -const INFISICAL_PUSH_SECRET_FINALIZER_NAME = "pushsecret.secrets.infisical.com/finalizer" -const INFISICAL_DYNAMIC_SECRET_FINALIZER_NAME = "dynamicsecret.secrets.infisical.com/finalizer" - -type PushSecretReplacePolicy string -type PushSecretDeletionPolicy string - -const ( - PUSH_SECRET_REPLACE_POLICY_ENABLED PushSecretReplacePolicy = "Replace" - PUSH_SECRET_DELETE_POLICY_ENABLED PushSecretDeletionPolicy = "Delete" -) - -type ManagedKubeResourceType string - -const ( - MANAGED_KUBE_RESOURCE_TYPE_SECRET ManagedKubeResourceType = "Secret" - MANAGED_KUBE_RESOURCE_TYPE_CONFIG_MAP ManagedKubeResourceType = "ConfigMap" -) - -type DynamicSecretLeaseRevocationPolicy string - -const ( - DYNAMIC_SECRET_LEASE_REVOCATION_POLICY_ENABLED DynamicSecretLeaseRevocationPolicy = "Revoke" -) - -var ErrInvalidLease = errors.New("invalid dynamic secret lease") diff --git a/k8-operator/internal/controller/infisicaldynamicsecret_controller.go b/k8-operator/internal/controller/infisicaldynamicsecret_controller.go deleted file mode 100644 index f63723c7d4..0000000000 --- a/k8-operator/internal/controller/infisicaldynamicsecret_controller.go +++ /dev/null @@ -1,238 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "fmt" - "math/rand" - "time" - - infisicaldynamicsecret "github.com/Infisical/infisical/k8-operator/internal/services/infisicaldynamicsecret" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/controllerhelpers" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" -) - -// InfisicalDynamicSecretReconciler reconciles a InfisicalDynamicSecret object -type InfisicalDynamicSecretReconciler struct { - client.Client - BaseLogger logr.Logger - Scheme *runtime.Scheme - Random *rand.Rand - Namespace string - IsNamespaceScoped bool -} - -var infisicalDynamicSecretsResourceVariablesMap map[string]util.ResourceVariables = make(map[string]util.ResourceVariables) - -func (r *InfisicalDynamicSecretReconciler) GetLogger(req ctrl.Request) logr.Logger { - return r.BaseLogger.WithValues("infisicaldynamicsecret", req.NamespacedName) -} - -// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/finalizers,verbs=update -// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete -// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;get;update -// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch -//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list -//+kubebuilder:rbac:groups="authentication.k8s.io",resources=tokenreviews,verbs=create -//+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create - -func (r *InfisicalDynamicSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - - logger := r.GetLogger(req) - - var infisicalDynamicSecretCRD secretsv1alpha1.InfisicalDynamicSecret - requeueTime := time.Second * 5 - - err := r.Get(ctx, req.NamespacedName, &infisicalDynamicSecretCRD) - if err != nil { - if errors.IsNotFound(err) { - logger.Info("Infisical Dynamic Secret CRD not found") - return ctrl.Result{ - Requeue: false, - }, nil - } else { - logger.Error(err, "Unable to fetch Infisical Dynamic Secret CRD from cluster") - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - } - - // Add finalizer if it doesn't exist - if !controllerutil.ContainsFinalizer(&infisicalDynamicSecretCRD, constants.INFISICAL_DYNAMIC_SECRET_FINALIZER_NAME) { - controllerutil.AddFinalizer(&infisicalDynamicSecretCRD, constants.INFISICAL_DYNAMIC_SECRET_FINALIZER_NAME) - if err := r.Update(ctx, &infisicalDynamicSecretCRD); err != nil { - return ctrl.Result{}, err - } - } - - // Check if it's being deleted - if !infisicalDynamicSecretCRD.DeletionTimestamp.IsZero() { - logger.Info("Handling deletion of InfisicalDynamicSecret") - if controllerutil.ContainsFinalizer(&infisicalDynamicSecretCRD, constants.INFISICAL_DYNAMIC_SECRET_FINALIZER_NAME) { - // We remove finalizers before running deletion logic to be completely safe from stuck resources - infisicalDynamicSecretCRD.ObjectMeta.Finalizers = []string{} - if err := r.Update(ctx, &infisicalDynamicSecretCRD); err != nil { - logger.Error(err, fmt.Sprintf("Error removing finalizers from InfisicalDynamicSecret %s", infisicalDynamicSecretCRD.Name)) - return ctrl.Result{}, err - } - - // Initialize the business logic handler - handler := infisicaldynamicsecret.NewInfisicalDynamicSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - - err := handler.HandleLeaseRevocation(ctx, logger, &infisicalDynamicSecretCRD, infisicalDynamicSecretsResourceVariablesMap) - - if infisicalDynamicSecretsResourceVariablesMap != nil { - if rv, ok := infisicalDynamicSecretsResourceVariablesMap[string(infisicalDynamicSecretCRD.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalDynamicSecretsResourceVariablesMap, string(infisicalDynamicSecretCRD.GetUID())) - } - } - - if err != nil { - return ctrl.Result{}, err // Even if this fails, we still want to delete the CRD - } - - } - return ctrl.Result{}, nil - } - - // Get modified/default config - infisicalConfig, err := controllerhelpers.GetInfisicalConfigMap(ctx, r.Client, r.IsNamespaceScoped) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to fetch infisical-config. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - // Initialize the business logic handler - handler := infisicaldynamicsecret.NewInfisicalDynamicSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - - // Setup API configuration through business logic - err = handler.SetupAPIConfig(infisicalDynamicSecretCRD, infisicalConfig) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to setup API configuration. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - // Handle CA certificate through business logic - err = handler.HandleCACertificate(ctx, infisicalDynamicSecretCRD) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to handle CA certificate. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - nextReconcile, err := handler.ReconcileInfisicalDynamicSecret(ctx, logger, &infisicalDynamicSecretCRD, infisicalDynamicSecretsResourceVariablesMap) - handler.SetReconcileConditionStatus(ctx, logger, &infisicalDynamicSecretCRD, err) - - if err == nil && nextReconcile.Seconds() >= 5 { - requeueTime = nextReconcile - } - - if err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile Infisical Dynamic Secret. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - numDeployments, err := controllerhelpers.ReconcileDeploymentsWithManagedSecrets(ctx, r.Client, logger, infisicalDynamicSecretCRD.Spec.ManagedSecretReference, r.IsNamespaceScoped) - handler.SetReconcileAutoRedeploymentConditionStatus(ctx, logger, &infisicalDynamicSecretCRD, numDeployments, err) - - if err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile auto redeployment. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - // Sync again after the specified time - logger.Info(fmt.Sprintf("Next reconciliation in [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil -} - -func (r *InfisicalDynamicSecretReconciler) SetupWithManager(mgr ctrl.Manager) error { - - // Custom predicate that allows both spec changes and deletions - specChangeOrDelete := predicate.Funcs{ - UpdateFunc: func(e event.UpdateEvent) bool { - // Only reconcile if spec/generation changed - - isSpecOrGenerationChange := e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration() - - if isSpecOrGenerationChange { - if infisicalDynamicSecretsResourceVariablesMap != nil { - if rv, ok := infisicalDynamicSecretsResourceVariablesMap[string(e.ObjectNew.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalDynamicSecretsResourceVariablesMap, string(e.ObjectNew.GetUID())) - } - } - } - - return isSpecOrGenerationChange - }, - DeleteFunc: func(e event.DeleteEvent) bool { - // Always reconcile on deletion - - if infisicalDynamicSecretsResourceVariablesMap != nil { - if rv, ok := infisicalDynamicSecretsResourceVariablesMap[string(e.Object.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalDynamicSecretsResourceVariablesMap, string(e.Object.GetUID())) - } - } - - return true - }, - CreateFunc: func(e event.CreateEvent) bool { - // Reconcile on creation - return true - }, - GenericFunc: func(e event.GenericEvent) bool { - // Ignore generic events - return false - }, - } - - return ctrl.NewControllerManagedBy(mgr). - For(&secretsv1alpha1.InfisicalDynamicSecret{}, builder.WithPredicates( - specChangeOrDelete, - )). - Complete(r) -} diff --git a/k8-operator/internal/controller/infisicaldynamicsecret_controller_test.go b/k8-operator/internal/controller/infisicaldynamicsecret_controller_test.go deleted file mode 100644 index 11b9442052..0000000000 --- a/k8-operator/internal/controller/infisicaldynamicsecret_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" -) - -var _ = Describe("InfisicalDynamicSecret Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - infisicaldynamicsecret := &secretsv1alpha1.InfisicalDynamicSecret{} - - BeforeEach(func() { - By("creating the custom resource for the Kind InfisicalDynamicSecret") - err := k8sClient.Get(ctx, typeNamespacedName, infisicaldynamicsecret) - if err != nil && errors.IsNotFound(err) { - resource := &secretsv1alpha1.InfisicalDynamicSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &secretsv1alpha1.InfisicalDynamicSecret{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance InfisicalDynamicSecret") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &InfisicalDynamicSecretReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/k8-operator/internal/controller/infisicalpushsecret_controller.go b/k8-operator/internal/controller/infisicalpushsecret_controller.go deleted file mode 100644 index 73f7b3b75d..0000000000 --- a/k8-operator/internal/controller/infisicalpushsecret_controller.go +++ /dev/null @@ -1,349 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "fmt" - "time" - - infisicalpushsecret "github.com/Infisical/infisical/k8-operator/internal/services/infisicalpushsecret" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/controllerhelpers" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" -) - -// InfisicalPushSecretReconciler reconciles a InfisicalPushSecret object -type InfisicalPushSecretReconciler struct { - client.Client - BaseLogger logr.Logger - Scheme *runtime.Scheme - IsNamespaceScoped bool - Namespace string -} - -var infisicalPushSecretResourceVariablesMap map[string]util.ResourceVariables = make(map[string]util.ResourceVariables) - -func (r *InfisicalPushSecretReconciler) GetLogger(req ctrl.Request) logr.Logger { - return r.BaseLogger.WithValues("infisicalpushsecret", req.NamespacedName) -} - -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalpushsecrets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalpushsecrets/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalpushsecrets/finalizers,verbs=update -//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete -//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete -//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;get;update -//+kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch -//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list -//+kubebuilder:rbac:groups="authentication.k8s.io",resources=tokenreviews,verbs=create -//+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=clustergenerators,verbs=get;list;watch;create;update;patch;delete - -func (r *InfisicalPushSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - - logger := r.GetLogger(req) - - var infisicalPushSecretCRD secretsv1alpha1.InfisicalPushSecret - requeueTime := time.Minute // seconds - - err := r.Get(ctx, req.NamespacedName, &infisicalPushSecretCRD) - if err != nil { - if errors.IsNotFound(err) { - logger.Info("Infisical Push Secret CRD not found") - // Initialize the business logic handler - handler := infisicalpushsecret.NewInfisicalPushSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - handler.DeleteManagedSecrets(ctx, logger, &infisicalPushSecretCRD, infisicalPushSecretResourceVariablesMap) - - return ctrl.Result{ - Requeue: false, - }, nil - } else { - logger.Error(err, "Unable to fetch Infisical Secret CRD from cluster") - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - } - - // Add finalizer if it doesn't exist - if !controllerutil.ContainsFinalizer(&infisicalPushSecretCRD, constants.INFISICAL_PUSH_SECRET_FINALIZER_NAME) { - controllerutil.AddFinalizer(&infisicalPushSecretCRD, constants.INFISICAL_PUSH_SECRET_FINALIZER_NAME) - if err := r.Update(ctx, &infisicalPushSecretCRD); err != nil { - return ctrl.Result{}, err - } - } - - // Check if it's being deleted - if !infisicalPushSecretCRD.DeletionTimestamp.IsZero() { - logger.Info("Handling deletion of InfisicalPushSecret") - if controllerutil.ContainsFinalizer(&infisicalPushSecretCRD, constants.INFISICAL_PUSH_SECRET_FINALIZER_NAME) { - // We remove finalizers before running deletion logic to be completely safe from stuck resources - infisicalPushSecretCRD.ObjectMeta.Finalizers = []string{} - if err := r.Update(ctx, &infisicalPushSecretCRD); err != nil { - logger.Error(err, fmt.Sprintf("Error removing finalizers from InfisicalPushSecret %s", infisicalPushSecretCRD.Name)) - return ctrl.Result{}, err - } - - // Initialize the business logic handler - handler := infisicalpushsecret.NewInfisicalPushSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - - if err := handler.DeleteManagedSecrets(ctx, logger, &infisicalPushSecretCRD, infisicalPushSecretResourceVariablesMap); err != nil { - return ctrl.Result{}, err // Even if this fails, we still want to delete the CRD - } - - } - return ctrl.Result{}, nil - } - - if infisicalPushSecretCRD.Spec.Push.Secret == nil && infisicalPushSecretCRD.Spec.Push.Generators == nil { - logger.Info("No secret or generators found, skipping reconciliation. Please define ") - return ctrl.Result{}, nil - } - - duration, err := util.ConvertIntervalToDuration(infisicalPushSecretCRD.Spec.ResyncInterval) - - if err != nil { - // if resyncInterval is nil, we don't want to reconcile automatically - if infisicalPushSecretCRD.Spec.ResyncInterval != nil { - logger.Error(err, fmt.Sprintf("unable to convert resync interval to duration. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Error(err, "unable to convert resync interval to duration") - return ctrl.Result{}, err - } - } - - requeueTime = duration - - if requeueTime != 0 { - logger.Info(fmt.Sprintf("Manual re-sync interval set. Interval: %v", requeueTime)) - } - - // Check if the resource is already marked for deletion - if infisicalPushSecretCRD.GetDeletionTimestamp() != nil { - return ctrl.Result{ - Requeue: false, - }, nil - } - - // Get modified/default config - infisicalConfig, err := controllerhelpers.GetInfisicalConfigMap(ctx, r.Client, r.IsNamespaceScoped) - if err != nil { - if requeueTime != 0 { - logger.Error(err, fmt.Sprintf("unable to fetch infisical-config. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Error(err, "unable to fetch infisical-config") - return ctrl.Result{}, err - } - } - - // Initialize the business logic handler - handler := infisicalpushsecret.NewInfisicalPushSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - - // Setup API configuration through business logic - err = handler.SetupAPIConfig(infisicalPushSecretCRD, infisicalConfig) - if err != nil { - if requeueTime != 0 { - logger.Error(err, fmt.Sprintf("unable to setup API configuration. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Error(err, "unable to setup API configuration") - return ctrl.Result{}, err - } - } - - // Handle CA certificate through business logic - err = handler.HandleCACertificate(ctx, infisicalPushSecretCRD) - if err != nil { - if requeueTime != 0 { - logger.Error(err, fmt.Sprintf("unable to fetch CA certificate. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Error(err, "unable to fetch CA certificate") - return ctrl.Result{}, err - } - } - - err = handler.ReconcileInfisicalPushSecret(ctx, logger, &infisicalPushSecretCRD, infisicalPushSecretResourceVariablesMap) - handler.SetReconcileStatusCondition(ctx, &infisicalPushSecretCRD, err) - - if err != nil { - if requeueTime != 0 { - logger.Error(err, fmt.Sprintf("unable to reconcile Infisical Push Secret. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Error(err, "unable to reconcile Infisical Push Secret") - return ctrl.Result{}, err - } - } - - // Sync again after the specified time - if requeueTime != 0 { - logger.Info(fmt.Sprintf("Operator will requeue after [%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } else { - logger.Info("Operator will reconcile on next spec change") - return ctrl.Result{}, nil - } -} - -func (r *InfisicalPushSecretReconciler) SetupWithManager(mgr ctrl.Manager) error { - // Custom predicate that allows both spec changes and deletions - specChangeOrDelete := predicate.Funcs{ - UpdateFunc: func(e event.UpdateEvent) bool { - // Only reconcile if spec/generation changed - - isSpecOrGenerationChange := e.ObjectOld.GetGeneration() != e.ObjectNew.GetGeneration() - - if isSpecOrGenerationChange { - if infisicalPushSecretResourceVariablesMap != nil { - if rv, ok := infisicalPushSecretResourceVariablesMap[string(e.ObjectNew.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalPushSecretResourceVariablesMap, string(e.ObjectNew.GetUID())) - } - } - } - - return isSpecOrGenerationChange - }, - DeleteFunc: func(e event.DeleteEvent) bool { - // Always reconcile on deletion - - if infisicalPushSecretResourceVariablesMap != nil { - if rv, ok := infisicalPushSecretResourceVariablesMap[string(e.Object.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalPushSecretResourceVariablesMap, string(e.Object.GetUID())) - } - } - - return true - }, - CreateFunc: func(e event.CreateEvent) bool { - // Reconcile on creation - return true - }, - GenericFunc: func(e event.GenericEvent) bool { - // Ignore generic events - return false - }, - } - - controllerManager := ctrl.NewControllerManagedBy(mgr). - For(&secretsv1alpha1.InfisicalPushSecret{}, builder.WithPredicates( - specChangeOrDelete, - )). - Watches( - &corev1.Secret{}, - handler.EnqueueRequestsFromMapFunc(r.findPushSecretsForSecret), - ) - - if !r.IsNamespaceScoped { - r.BaseLogger.Info("Watching ClusterGenerators for non-namespace scoped operator") - controllerManager.Watches( - &secretsv1alpha1.ClusterGenerator{}, - handler.EnqueueRequestsFromMapFunc(r.findPushSecretsForClusterGenerator), - ) - } else { - r.BaseLogger.Info("Not watching ClusterGenerators for namespace scoped operator") - } - - return controllerManager.Complete(r) -} - -func (r *InfisicalPushSecretReconciler) findPushSecretsForClusterGenerator(ctx context.Context, o client.Object) []reconcile.Request { - pushSecrets := &secretsv1alpha1.InfisicalPushSecretList{} - if err := r.List(ctx, pushSecrets); err != nil { - return []reconcile.Request{} - } - - clusterGenerator, ok := o.(*secretsv1alpha1.ClusterGenerator) - if !ok { - return []reconcile.Request{} - } - - requests := []reconcile.Request{} - - for _, pushSecret := range pushSecrets.Items { - if pushSecret.Spec.Push.Generators != nil { - for _, generator := range pushSecret.Spec.Push.Generators { - if generator.GeneratorRef.Name == clusterGenerator.GetName() { - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: pushSecret.GetName(), - Namespace: pushSecret.GetNamespace(), - }, - }) - break - } - } - } - } - return requests -} - -func (r *InfisicalPushSecretReconciler) findPushSecretsForSecret(ctx context.Context, o client.Object) []reconcile.Request { - pushSecrets := &secretsv1alpha1.InfisicalPushSecretList{} - if err := r.List(ctx, pushSecrets); err != nil { - return []reconcile.Request{} - } - - requests := []reconcile.Request{} - for _, pushSecret := range pushSecrets.Items { - if pushSecret.Spec.Push.Secret != nil && - pushSecret.Spec.Push.Secret.SecretName == o.GetName() && - pushSecret.Spec.Push.Secret.SecretNamespace == o.GetNamespace() { - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: pushSecret.GetName(), - Namespace: pushSecret.GetNamespace(), - }, - }) - } - - } - - return requests -} diff --git a/k8-operator/internal/controller/infisicalpushsecret_controller_test.go b/k8-operator/internal/controller/infisicalpushsecret_controller_test.go deleted file mode 100644 index 92d00f32c8..0000000000 --- a/k8-operator/internal/controller/infisicalpushsecret_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" -) - -var _ = Describe("InfisicalPushSecret Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - infisicalpushsecret := &secretsv1alpha1.InfisicalPushSecret{} - - BeforeEach(func() { - By("creating the custom resource for the Kind InfisicalPushSecret") - err := k8sClient.Get(ctx, typeNamespacedName, infisicalpushsecret) - if err != nil && errors.IsNotFound(err) { - resource := &secretsv1alpha1.InfisicalPushSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &secretsv1alpha1.InfisicalPushSecret{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance InfisicalPushSecret") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &InfisicalPushSecretReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/k8-operator/internal/controller/infisicalsecret_controller.go b/k8-operator/internal/controller/infisicalsecret_controller.go deleted file mode 100644 index 07552f9cfd..0000000000 --- a/k8-operator/internal/controller/infisicalsecret_controller.go +++ /dev/null @@ -1,255 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "fmt" - "time" - - defaultErrors "errors" - - infisicalsecret "github.com/Infisical/infisical/k8-operator/internal/services/infisicalsecret" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/source" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/controllerhelpers" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" -) - -// InfisicalSecretReconciler reconciles a InfisicalSecret object -type InfisicalSecretReconciler struct { - client.Client - BaseLogger logr.Logger - Scheme *runtime.Scheme - - SourceCh chan event.TypedGenericEvent[client.Object] - Namespace string - IsNamespaceScoped bool -} - -var infisicalSecretResourceVariablesMap map[string]util.ResourceVariables = make(map[string]util.ResourceVariables) - -func (r *InfisicalSecretReconciler) GetLogger(req ctrl.Request) logr.Logger { - return r.BaseLogger.WithValues("infisicalsecret", req.NamespacedName) -} - -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicalsecrets/finalizers,verbs=update -//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete -//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete -//+kubebuilder:rbac:groups=apps,resources=deployments;daemonsets;statefulsets,verbs=list;watch;get;update -//+kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch -//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list -//+kubebuilder:rbac:groups="authentication.k8s.io",resources=tokenreviews,verbs=create -//+kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the InfisicalSecret object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/reconcile -func (r *InfisicalSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := r.GetLogger(req) - - var infisicalSecretCRD secretsv1alpha1.InfisicalSecret - requeueTime := time.Minute // seconds - - err := r.Get(ctx, req.NamespacedName, &infisicalSecretCRD) - if err != nil { - if errors.IsNotFound(err) { - return ctrl.Result{ - Requeue: false, - }, nil - } else { - logger.Error(err, "unable to fetch Infisical Secret CRD from cluster") - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - } - - // It's important we don't directly modify the CRD object, so we create a copy of it and move existing data into it. - managedKubeSecretReferences := infisicalSecretCRD.Spec.ManagedKubeSecretReferences - managedKubeConfigMapReferences := infisicalSecretCRD.Spec.ManagedKubeConfigMapReferences - - if infisicalSecretCRD.Spec.ManagedSecretReference.SecretName != "" && managedKubeSecretReferences != nil && len(managedKubeSecretReferences) > 0 { - errMessage := "InfisicalSecret CRD cannot have both managedSecretReference and managedKubeSecretReferences" - logger.Error(defaultErrors.New(errMessage), errMessage) - return ctrl.Result{}, defaultErrors.New(errMessage) - } - - if infisicalSecretCRD.Spec.ManagedSecretReference.SecretName != "" { - logger.Info("\n\n\nThe field `managedSecretReference` will be deprecated in the near future, please use `managedKubeSecretReferences` instead.\n\nRefer to the documentation for more information: https://infisical.com/docs/integrations/platforms/kubernetes/infisical-secret-crd\n\n\n") - - if managedKubeSecretReferences == nil { - managedKubeSecretReferences = []secretsv1alpha1.ManagedKubeSecretConfig{} - } - managedKubeSecretReferences = append(managedKubeSecretReferences, infisicalSecretCRD.Spec.ManagedSecretReference) - } - - if len(managedKubeSecretReferences) == 0 && len(managedKubeConfigMapReferences) == 0 { - errMessage := "InfisicalSecret CRD must have at least one managed secret reference set in the `managedKubeSecretReferences` or `managedKubeConfigMapReferences` field" - logger.Error(defaultErrors.New(errMessage), errMessage) - return ctrl.Result{}, defaultErrors.New(errMessage) - } - - // Remove finalizers if they exist. This is to support previous InfisicalSecret CRD's that have finalizers on them. - // In order to delete secrets with finalizers, we first remove the finalizers so we can use the simplified and improved deletion process - if !infisicalSecretCRD.ObjectMeta.DeletionTimestamp.IsZero() && len(infisicalSecretCRD.ObjectMeta.Finalizers) > 0 { - infisicalSecretCRD.ObjectMeta.Finalizers = []string{} - if err := r.Update(ctx, &infisicalSecretCRD); err != nil { - logger.Error(err, fmt.Sprintf("Error removing finalizers from Infisical Secret %s", infisicalSecretCRD.Name)) - return ctrl.Result{}, err - } - // Our finalizers have been removed, so the reconciler can do nothing. - return ctrl.Result{}, nil - } - - if infisicalSecretCRD.Spec.ResyncInterval != 0 { - requeueTime = time.Second * time.Duration(infisicalSecretCRD.Spec.ResyncInterval) - logger.Info(fmt.Sprintf("Manual re-sync interval set. Interval: %v", requeueTime)) - - } else { - logger.Info(fmt.Sprintf("Re-sync interval set. Interval: %v", requeueTime)) - } - - // Check if the resource is already marked for deletion - if infisicalSecretCRD.GetDeletionTimestamp() != nil { - return ctrl.Result{ - Requeue: false, - }, nil - } - - // Get modified/default config - infisicalConfig, err := controllerhelpers.GetInfisicalConfigMap(ctx, r.Client, r.IsNamespaceScoped) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to fetch infisical-config. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - // Initialize the business logic handler - handler := infisicalsecret.NewInfisicalSecretHandler(r.Client, r.Scheme, r.IsNamespaceScoped) - - // Setup API configuration through business logic - err = handler.SetupAPIConfig(infisicalSecretCRD, infisicalConfig) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to setup API configuration. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - // Handle CA certificate through business logic - err = handler.HandleCACertificate(ctx, infisicalSecretCRD) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to handle CA certificate. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - secretsCount, err := handler.ReconcileInfisicalSecret(ctx, logger, &infisicalSecretCRD, managedKubeSecretReferences, managedKubeConfigMapReferences, infisicalSecretResourceVariablesMap) - handler.SetReadyToSyncSecretsConditions(ctx, logger, &infisicalSecretCRD, secretsCount, err) - - if err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile InfisicalSecret. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - numDeployments, err := controllerhelpers.ReconcileDeploymentsWithMultipleManagedSecrets(ctx, r.Client, logger, managedKubeSecretReferences, r.IsNamespaceScoped) - handler.SetInfisicalAutoRedeploymentReady(ctx, logger, &infisicalSecretCRD, numDeployments, err) - - if err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile auto redeployment. Will requeue after [requeueTime=%v]", requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - if infisicalSecretCRD.Spec.InstantUpdates { - if err := handler.OpenInstantUpdatesStream(ctx, logger, &infisicalSecretCRD, infisicalSecretResourceVariablesMap, r.SourceCh); err != nil { - requeueTime = time.Second * 10 - logger.Info(fmt.Sprintf("event stream failed. Will requeue after [requeueTime=%v] [error=%s]", requeueTime, err.Error())) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil - } - - logger.Info("Instant updates are enabled") - } else { - handler.CloseInstantUpdatesStream(ctx, logger, &infisicalSecretCRD, infisicalSecretResourceVariablesMap) - } - - // Sync again after the specified time - logger.Info(fmt.Sprintf("Successfully synced %d secrets. Operator will requeue after [%v]", secretsCount, requeueTime)) - return ctrl.Result{ - RequeueAfter: requeueTime, - }, nil -} - -func (r *InfisicalSecretReconciler) SetupWithManager(mgr ctrl.Manager) error { - r.SourceCh = make(chan event.TypedGenericEvent[client.Object]) - - return ctrl.NewControllerManagedBy(mgr). - WatchesRawSource( - source.Channel[client.Object](r.SourceCh, &util.EnqueueDelayedEventHandler{Delay: time.Second * 10}), - ). - For(&secretsv1alpha1.InfisicalSecret{}, builder.WithPredicates(predicate.Funcs{ - UpdateFunc: func(e event.UpdateEvent) bool { - if e.ObjectOld.GetGeneration() == e.ObjectNew.GetGeneration() { - return false // Skip reconciliation for status-only changes - } - - if infisicalSecretResourceVariablesMap != nil { - if rv, ok := infisicalSecretResourceVariablesMap[string(e.ObjectNew.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalSecretResourceVariablesMap, string(e.ObjectNew.GetUID())) - } - } - return true - }, - DeleteFunc: func(e event.DeleteEvent) bool { - if infisicalSecretResourceVariablesMap != nil { - if rv, ok := infisicalSecretResourceVariablesMap[string(e.Object.GetUID())]; ok { - rv.CancelCtx() - delete(infisicalSecretResourceVariablesMap, string(e.Object.GetUID())) - } - } - return true - }, - })). - Complete(r) - -} diff --git a/k8-operator/internal/controller/infisicalsecret_controller_test.go b/k8-operator/internal/controller/infisicalsecret_controller_test.go deleted file mode 100644 index dd45e584d2..0000000000 --- a/k8-operator/internal/controller/infisicalsecret_controller_test.go +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" -) - -var _ = Describe("InfisicalSecret Controller", func() { - Context("When reconciling a resource", func() { - const resourceName = "test-resource" - - ctx := context.Background() - - typeNamespacedName := types.NamespacedName{ - Name: resourceName, - Namespace: "default", // TODO(user):Modify as needed - } - infisicalsecret := &secretsv1alpha1.InfisicalSecret{} - - BeforeEach(func() { - By("creating the custom resource for the Kind InfisicalSecret") - err := k8sClient.Get(ctx, typeNamespacedName, infisicalsecret) - if err != nil && errors.IsNotFound(err) { - resource := &secretsv1alpha1.InfisicalSecret{ - ObjectMeta: metav1.ObjectMeta{ - Name: resourceName, - Namespace: "default", - }, - // TODO(user): Specify other spec details if needed. - } - Expect(k8sClient.Create(ctx, resource)).To(Succeed()) - } - }) - - AfterEach(func() { - // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &secretsv1alpha1.InfisicalSecret{} - err := k8sClient.Get(ctx, typeNamespacedName, resource) - Expect(err).NotTo(HaveOccurred()) - - By("Cleanup the specific resource instance InfisicalSecret") - Expect(k8sClient.Delete(ctx, resource)).To(Succeed()) - }) - It("should successfully reconcile the resource", func() { - By("Reconciling the created resource") - controllerReconciler := &InfisicalSecretReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespacedName, - }) - Expect(err).NotTo(HaveOccurred()) - // TODO(user): Add more specific assertions depending on your controller's reconciliation logic. - // Example: If you expect a certain status condition after reconciliation, verify it here. - }) - }) -}) diff --git a/k8-operator/internal/controller/suite_test.go b/k8-operator/internal/controller/suite_test.go deleted file mode 100644 index d1459e9aa0..0000000000 --- a/k8-operator/internal/controller/suite_test.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "context" - "os" - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - // +kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var ( - ctx context.Context - cancel context.CancelFunc - testEnv *envtest.Environment - cfg *rest.Config - k8sClient client.Client -) - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - ctx, cancel = context.WithCancel(context.TODO()) - - var err error - err = secretsv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - // +kubebuilder:scaffold:scheme - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - } - - // Retrieve the first found binary directory to allow running tests from IDEs - if getFirstFoundEnvTestBinaryDir() != "" { - testEnv.BinaryAssetsDirectory = getFirstFoundEnvTestBinaryDir() - } - - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) - -// getFirstFoundEnvTestBinaryDir locates the first binary in the specified path. -// ENVTEST-based tests depend on specific binaries, usually located in paths set by -// controller-runtime. When running tests directly (e.g., via an IDE) without using -// Makefile targets, the 'BinaryAssetsDirectory' must be explicitly configured. -// -// This function streamlines the process by finding the required binaries, similar to -// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are -// properly set up, run 'make setup-envtest' beforehand. -func getFirstFoundEnvTestBinaryDir() string { - basePath := filepath.Join("..", "..", "bin", "k8s") - entries, err := os.ReadDir(basePath) - if err != nil { - logf.Log.Error(err, "Failed to read directory", "path", basePath) - return "" - } - for _, entry := range entries { - if entry.IsDir() { - return filepath.Join(basePath, entry.Name()) - } - } - return "" -} diff --git a/k8-operator/internal/controllerhelpers/controllerhelpers.go b/k8-operator/internal/controllerhelpers/controllerhelpers.go deleted file mode 100644 index d33097c379..0000000000 --- a/k8-operator/internal/controllerhelpers/controllerhelpers.go +++ /dev/null @@ -1,304 +0,0 @@ -package controllerhelpers - -import ( - "context" - "fmt" - "sync" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - v1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - k8Errors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - controllerClient "sigs.k8s.io/controller-runtime/pkg/client" -) - -const DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX = "secrets.infisical.com/managed-secret" -const AUTO_RELOAD_DEPLOYMENT_ANNOTATION = "secrets.infisical.com/auto-reload" // needs to be set to true for a deployment to start auto redeploying - -func ReconcileDeploymentsWithManagedSecrets(ctx context.Context, client controllerClient.Client, logger logr.Logger, managedSecret v1alpha1.ManagedKubeSecretConfig, isNamespaceScoped bool) (int, error) { - listOfDeployments := &v1.DeploymentList{} - - err := client.List(ctx, listOfDeployments, &controllerClient.ListOptions{Namespace: managedSecret.SecretNamespace}) - if err != nil { - return 0, fmt.Errorf("unable to get deployments in the [namespace=%v] [err=%v]", managedSecret.SecretNamespace, err) - } - - listOfDaemonSets := &v1.DaemonSetList{} - err = client.List(ctx, listOfDaemonSets, &controllerClient.ListOptions{Namespace: managedSecret.SecretNamespace}) - if err != nil { - return 0, fmt.Errorf("unable to get daemonSets in the [namespace=%v] [err=%v]", managedSecret.SecretNamespace, err) - } - - listOfStatefulSets := &v1.StatefulSetList{} - err = client.List(ctx, listOfStatefulSets, &controllerClient.ListOptions{Namespace: managedSecret.SecretNamespace}) - if err != nil { - return 0, fmt.Errorf("unable to get statefulSets in the [namespace=%v] [err=%v]", managedSecret.SecretNamespace, err) - } - - managedKubeSecretNameAndNamespace := types.NamespacedName{ - Namespace: managedSecret.SecretNamespace, - Name: managedSecret.SecretName, - } - - managedKubeSecret := &corev1.Secret{} - err = client.Get(ctx, managedKubeSecretNameAndNamespace, managedKubeSecret) - if err != nil { - if util.IsNamespaceScopedError(err, isNamespaceScoped) { - return 0, fmt.Errorf("unable to fetch Kubernetes secret to update deployment. Your Operator is namespace scoped, and cannot read secrets outside of its namespace. Please ensure the secret is in the same namespace as the operator. [err=%v]", err) - } - - return 0, fmt.Errorf("unable to fetch Kubernetes secret to update deployment: %v", err) - } - - var wg sync.WaitGroup - - // Iterate over the deployments and check if they use the managed secret - for _, deployment := range listOfDeployments.Items { - deployment := deployment - if deployment.Annotations[AUTO_RELOAD_DEPLOYMENT_ANNOTATION] == "true" && IsDeploymentUsingManagedSecret(deployment, managedSecret) { - // Start a goroutine to reconcile the deployment - wg.Add(1) - go func(deployment v1.Deployment, managedSecret corev1.Secret) { - defer wg.Done() - if err := ReconcileDeployment(ctx, client, logger, deployment, managedSecret); err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile deployment with [name=%v]. Will try next requeue", deployment.ObjectMeta.Name)) - } - }(deployment, *managedKubeSecret) - } - } - - // Iterate over the daemonSets and check if they use the managed secret - for _, daemonSet := range listOfDaemonSets.Items { - daemonSet := daemonSet - if daemonSet.Annotations[AUTO_RELOAD_DEPLOYMENT_ANNOTATION] == "true" && IsDaemonSetUsingManagedSecret(daemonSet, managedSecret) { - wg.Add(1) - go func(deployment v1.DaemonSet, managedSecret corev1.Secret) { - defer wg.Done() - if err := ReconcileDaemonSet(ctx, client, logger, daemonSet, managedSecret); err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile daemonset with [name=%v]. Will try next requeue", deployment.ObjectMeta.Name)) - } - }(daemonSet, *managedKubeSecret) - } - } - - // Iterate over the statefulSets and check if they use the managed secret - for _, statefulSet := range listOfStatefulSets.Items { - statefulSet := statefulSet - if statefulSet.Annotations[AUTO_RELOAD_DEPLOYMENT_ANNOTATION] == "true" && IsStatefulSetUsingManagedSecret(statefulSet, managedSecret) { - wg.Add(1) - go func(statefulSet v1.StatefulSet, managedSecret corev1.Secret) { - defer wg.Done() - if err := ReconcileStatefulSet(ctx, client, logger, statefulSet, managedSecret); err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile statefulset with [name=%v]. Will try next requeue", statefulSet.ObjectMeta.Name)) - } - }(statefulSet, *managedKubeSecret) - } - } - - wg.Wait() - - return 0, nil -} - -func ReconcileDeploymentsWithMultipleManagedSecrets(ctx context.Context, client controllerClient.Client, logger logr.Logger, managedSecrets []v1alpha1.ManagedKubeSecretConfig, isNamespaceScoped bool) (int, error) { - for _, managedSecret := range managedSecrets { - _, err := ReconcileDeploymentsWithManagedSecrets(ctx, client, logger, managedSecret, isNamespaceScoped) - if err != nil { - logger.Error(err, fmt.Sprintf("unable to reconcile deployments with managed secret [name=%v]", managedSecret.SecretName)) - return 0, err - } - } - return 0, nil -} - -// Check if the deployment uses managed secrets -func IsDeploymentUsingManagedSecret(deployment v1.Deployment, managedSecret v1alpha1.ManagedKubeSecretConfig) bool { - managedSecretName := managedSecret.SecretName - for _, container := range deployment.Spec.Template.Spec.Containers { - for _, envFrom := range container.EnvFrom { - if envFrom.SecretRef != nil && envFrom.SecretRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - for _, env := range container.Env { - if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - } - for _, volume := range deployment.Spec.Template.Spec.Volumes { - if volume.Secret != nil && volume.Secret.SecretName == managedSecretName { - return true - } - } - - return false -} - -func IsDaemonSetUsingManagedSecret(daemonSet v1.DaemonSet, managedSecret v1alpha1.ManagedKubeSecretConfig) bool { - managedSecretName := managedSecret.SecretName - for _, container := range daemonSet.Spec.Template.Spec.Containers { - for _, envFrom := range container.EnvFrom { - if envFrom.SecretRef != nil && envFrom.SecretRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - for _, env := range container.Env { - if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - } - - for _, volume := range daemonSet.Spec.Template.Spec.Volumes { - if volume.Secret != nil && volume.Secret.SecretName == managedSecretName { - return true - } - } - - return false -} - -func IsStatefulSetUsingManagedSecret(statefulSet v1.StatefulSet, managedSecret v1alpha1.ManagedKubeSecretConfig) bool { - managedSecretName := managedSecret.SecretName - for _, container := range statefulSet.Spec.Template.Spec.Containers { - for _, envFrom := range container.EnvFrom { - if envFrom.SecretRef != nil && envFrom.SecretRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - for _, env := range container.Env { - if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil && env.ValueFrom.SecretKeyRef.LocalObjectReference.Name == managedSecretName { - return true - } - } - } - for _, volume := range statefulSet.Spec.Template.Spec.Volumes { - if volume.Secret != nil && volume.Secret.SecretName == managedSecretName { - return true - } - } - - return false -} - -// This function ensures that a deployment is in sync with a Kubernetes secret by comparing their versions. -// If the version of the secret is different from the version annotation on the deployment, the annotation is updated to trigger a restart of the deployment. -func ReconcileDeployment(ctx context.Context, client controllerClient.Client, logger logr.Logger, deployment v1.Deployment, secret corev1.Secret) error { - annotationKey := fmt.Sprintf("%s.%s", DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX, secret.Name) - annotationValue := secret.Annotations[constants.SECRET_VERSION_ANNOTATION] - - if deployment.Annotations[annotationKey] == annotationValue && - deployment.Spec.Template.Annotations[annotationKey] == annotationValue { - logger.Info(fmt.Sprintf("The [deploymentName=%v] is already using the most up to date managed secrets. No action required.", deployment.ObjectMeta.Name)) - return nil - } - - logger.Info(fmt.Sprintf("Deployment is using outdated managed secret. Starting re-deployment [deploymentName=%v]", deployment.ObjectMeta.Name)) - - if deployment.Spec.Template.Annotations == nil { - deployment.Spec.Template.Annotations = make(map[string]string) - } - - deployment.Annotations[annotationKey] = annotationValue - deployment.Spec.Template.Annotations[annotationKey] = annotationValue - - if err := client.Update(ctx, &deployment); err != nil { - return fmt.Errorf("failed to update deployment annotation: %v", err) - } - return nil -} - -func ReconcileDaemonSet(ctx context.Context, client controllerClient.Client, logger logr.Logger, daemonSet v1.DaemonSet, secret corev1.Secret) error { - annotationKey := fmt.Sprintf("%s.%s", DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX, secret.Name) - annotationValue := secret.Annotations[constants.SECRET_VERSION_ANNOTATION] - - if daemonSet.Annotations[annotationKey] == annotationValue && - daemonSet.Spec.Template.Annotations[annotationKey] == annotationValue { - logger.Info(fmt.Sprintf("The [daemonSetName=%v] is already using the most up to date managed secrets. No action required.", daemonSet.ObjectMeta.Name)) - return nil - } - - logger.Info(fmt.Sprintf("DaemonSet is using outdated managed secret. Starting re-deployment [daemonSetName=%v]", daemonSet.ObjectMeta.Name)) - - if daemonSet.Spec.Template.Annotations == nil { - daemonSet.Spec.Template.Annotations = make(map[string]string) - } - - daemonSet.Annotations[annotationKey] = annotationValue - daemonSet.Spec.Template.Annotations[annotationKey] = annotationValue - - if err := client.Update(ctx, &daemonSet); err != nil { - return fmt.Errorf("failed to update daemonSet annotation: %v", err) - } - return nil -} - -func ReconcileStatefulSet(ctx context.Context, client controllerClient.Client, logger logr.Logger, statefulSet v1.StatefulSet, secret corev1.Secret) error { - annotationKey := fmt.Sprintf("%s.%s", DEPLOYMENT_SECRET_NAME_ANNOTATION_PREFIX, secret.Name) - annotationValue := secret.Annotations[constants.SECRET_VERSION_ANNOTATION] - - if statefulSet.Annotations[annotationKey] == annotationValue && - statefulSet.Spec.Template.Annotations[annotationKey] == annotationValue { - logger.Info(fmt.Sprintf("The [statefulSetName=%v] is already using the most up to date managed secrets. No action required.", statefulSet.ObjectMeta.Name)) - return nil - } - - logger.Info(fmt.Sprintf("StatefulSet is using outdated managed secret. Starting re-deployment [statefulSetName=%v]", statefulSet.ObjectMeta.Name)) - - if statefulSet.Spec.Template.Annotations == nil { - statefulSet.Spec.Template.Annotations = make(map[string]string) - } - - statefulSet.Annotations[annotationKey] = annotationValue - statefulSet.Spec.Template.Annotations[annotationKey] = annotationValue - - if err := client.Update(ctx, &statefulSet); err != nil { - return fmt.Errorf("failed to update statefulSet annotation: %v", err) - } - return nil -} - -func GetInfisicalConfigMap(ctx context.Context, client client.Client, isNamespaceScoped bool) (configMap map[string]string, errToReturn error) { - // default key values - defaultConfigMapData := make(map[string]string) - defaultConfigMapData["hostAPI"] = constants.INFISICAL_DOMAIN - - // this will never work if we're namespace scoped, because the operator can't read outside of its namespace by our current RBAC rules. - // This is how it has always worked, but the error has been masked as 'not found' in V3 kubebuilder. - if isNamespaceScoped { - return defaultConfigMapData, nil - } - - kubeConfigMap := &corev1.ConfigMap{} - err := client.Get(ctx, types.NamespacedName{ - Namespace: constants.OPERATOR_SETTINGS_CONFIGMAP_NAMESPACE, - Name: constants.OPERATOR_SETTINGS_CONFIGMAP_NAME, - }, kubeConfigMap) - - if err != nil { - if k8Errors.IsNotFound(err) { - kubeConfigMap = nil - } else { - return nil, fmt.Errorf("GetConfigMapByNamespacedName: unable to fetch config map in [namespacedName=%s] [err=%s]", constants.OPERATOR_SETTINGS_CONFIGMAP_NAMESPACE, err) - } - } - - if kubeConfigMap == nil { - return defaultConfigMapData, nil - } else { - for key, value := range defaultConfigMapData { - _, exists := kubeConfigMap.Data[key] - if !exists { - kubeConfigMap.Data[key] = value - } - } - - return kubeConfigMap.Data, nil - } -} diff --git a/k8-operator/internal/crypto/crypto.go b/k8-operator/internal/crypto/crypto.go deleted file mode 100644 index 810382af1c..0000000000 --- a/k8-operator/internal/crypto/crypto.go +++ /dev/null @@ -1,42 +0,0 @@ -package crypto - -import ( - "crypto/aes" - "crypto/cipher" - "fmt" - "hash/crc32" - - "golang.org/x/crypto/nacl/box" -) - -func DecryptSymmetric(key []byte, encryptedPrivateKey []byte, tag []byte, IV []byte) ([]byte, error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - aesgcm, err := cipher.NewGCMWithNonceSize(block, len(IV)) - if err != nil { - return nil, err - } - - var nonce = IV - var ciphertext = append(encryptedPrivateKey, tag...) - - plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil) - if err != nil { - return nil, err - } - - return plaintext, nil -} - -func DecryptAsymmetric(ciphertext []byte, nonce []byte, publicKey []byte, privateKey []byte) (plainText []byte) { - plainTextToReturn, _ := box.Open(nil, ciphertext, (*[24]byte)(nonce), (*[32]byte)(publicKey), (*[32]byte)(privateKey)) - return plainTextToReturn -} - -func ComputeEtag(data []byte) string { - crc := crc32.ChecksumIEEE(data) - return fmt.Sprintf(`W/"secrets-%d-%08X"`, len(data), crc) -} diff --git a/k8-operator/internal/generator/generator.go b/k8-operator/internal/generator/generator.go deleted file mode 100644 index cc1b290c7f..0000000000 --- a/k8-operator/internal/generator/generator.go +++ /dev/null @@ -1 +0,0 @@ -package generator diff --git a/k8-operator/internal/generator/password.go b/k8-operator/internal/generator/password.go deleted file mode 100644 index d322f10144..0000000000 --- a/k8-operator/internal/generator/password.go +++ /dev/null @@ -1,76 +0,0 @@ -package generator - -import ( - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/sethvargo/go-password/password" -) - -const ( - defaultLength = 24 - defaultSymbolChars = "~!@#$%^&*()_+`-={}|[]\\:\"<>?,./" - digitFactor = 0.25 - symbolFactor = 0.25 -) - -func generateSafePassword( - passLen int, - symbols int, - symbolCharacters string, - digits int, - noUpper bool, - allowRepeat bool, -) (string, error) { - gen, err := password.NewGenerator(&password.GeneratorInput{ - Symbols: symbolCharacters, - }) - if err != nil { - return "", err - } - return gen.Generate( - passLen, - digits, - symbols, - noUpper, - allowRepeat, - ) -} - -func GeneratorPassword(spec v1alpha1.PasswordSpec) (string, error) { - - symbolCharacters := defaultSymbolChars - - if spec.SymbolCharacters != nil && *spec.SymbolCharacters != "" { - symbolCharacters = *spec.SymbolCharacters - } - - passwordLength := defaultLength - - if spec.Length != 0 { - passwordLength = spec.Length - } - - digits := int(float32(passwordLength) * digitFactor) - if spec.Digits != nil { - digits = *spec.Digits - } - - symbols := int(float32(passwordLength) * symbolFactor) - if spec.Symbols != nil { - symbols = *spec.Symbols - } - - pass, err := generateSafePassword( - passwordLength, - symbols, - symbolCharacters, - digits, - spec.NoUpper, - spec.AllowRepeat, - ) - - if err != nil { - return "", err - } - - return pass, nil -} diff --git a/k8-operator/internal/generator/uuid.go b/k8-operator/internal/generator/uuid.go deleted file mode 100644 index b9249f783f..0000000000 --- a/k8-operator/internal/generator/uuid.go +++ /dev/null @@ -1,10 +0,0 @@ -package generator - -import ( - "github.com/google/uuid" -) - -func GeneratorUUID() (string, error) { - uuid := uuid.New().String() - return uuid, nil -} diff --git a/k8-operator/internal/model/model.go b/k8-operator/internal/model/model.go deleted file mode 100644 index 69b987ba76..0000000000 --- a/k8-operator/internal/model/model.go +++ /dev/null @@ -1,42 +0,0 @@ -package model - -type ServiceAccountDetails struct { - AccessKey string - PublicKey string - PrivateKey string -} - -type UniversalAuthIdentityDetails struct { - ClientId string - ClientSecret string -} - -type LdapIdentityDetails struct { - Username string - Password string -} - -type SingleEnvironmentVariable struct { - Key string `json:"key"` - Value string `json:"value"` - SecretPath string `json:"secretPath"` - Type string `json:"type"` - ID string `json:"id"` -} - -type SecretTemplateOptions struct { - Value string `json:"value"` - SecretPath string `json:"secretPath"` -} - -type Project struct { - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - OrgID string `json:"orgId"` - Environments []struct { - Name string `json:"name"` - Slug string `json:"slug"` - ID string `json:"id"` - } -} diff --git a/k8-operator/internal/services/infisicaldynamicsecret/conditions.go b/k8-operator/internal/services/infisicaldynamicsecret/conditions.go deleted file mode 100644 index 0a22354422..0000000000 --- a/k8-operator/internal/services/infisicaldynamicsecret/conditions.go +++ /dev/null @@ -1,146 +0,0 @@ -package infisicaldynamicsecret - -import ( - "context" - "fmt" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func (r *InfisicalDynamicSecretReconciler) SetReconcileAutoRedeploymentConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, numDeployments int, errorToConditionOn error) { - if infisicalDynamicSecret.Status.Conditions == nil { - infisicalDynamicSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/AutoRedeployReady", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: fmt.Sprintf("Infisical has found %v deployments which are ready to be auto redeployed when dynamic secret lease changes", numDeployments), - }) - } else { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/AutoRedeployReady", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed reconcile deployments because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalDynamicSecret) - if err != nil { - logger.Error(err, "Could not set condition for AutoRedeployReady") - } -} - -func (r *InfisicalDynamicSecretReconciler) SetAuthenticatedConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) { - if infisicalDynamicSecret.Status.Conditions == nil { - infisicalDynamicSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Authenticated", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: "Infisical has successfully authenticated with the Infisical API", - }) - } else { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Authenticated", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to authenticate with Infisical API because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalDynamicSecret) - if err != nil { - logger.Error(err, "Could not set condition for Authenticated") - } -} - -func (r *InfisicalDynamicSecretReconciler) SetLeaseRenewalConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) { - if infisicalDynamicSecret.Status.Conditions == nil { - infisicalDynamicSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LeaseRenewal", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: "Infisical has successfully renewed the lease", - }) - } else { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LeaseRenewal", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to renew the lease because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalDynamicSecret) - if err != nil { - logger.Error(err, "Could not set condition for LeaseRenewal") - } -} - -func (r *InfisicalDynamicSecretReconciler) SetCreatedLeaseConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) { - if infisicalDynamicSecret.Status.Conditions == nil { - infisicalDynamicSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LeaseCreated", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: "Infisical has successfully created the lease", - }) - } else { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LeaseCreated", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to create the lease because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalDynamicSecret) - if err != nil { - logger.Error(err, "Could not set condition for LeaseCreated") - } -} - -func (r *InfisicalDynamicSecretReconciler) SetReconcileConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) { - if infisicalDynamicSecret.Status.Conditions == nil { - infisicalDynamicSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Reconcile", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: "Infisical has successfully reconciled the InfisicalDynamicSecret", - }) - } else { - meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Reconcile", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to reconcile the InfisicalDynamicSecret because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalDynamicSecret) - if err != nil { - logger.Error(err, "Could not set condition for Reconcile") - } -} diff --git a/k8-operator/internal/services/infisicaldynamicsecret/handler.go b/k8-operator/internal/services/infisicaldynamicsecret/handler.go deleted file mode 100644 index 1749cf5c02..0000000000 --- a/k8-operator/internal/services/infisicaldynamicsecret/handler.go +++ /dev/null @@ -1,120 +0,0 @@ -package infisicaldynamicsecret - -import ( - "context" - "fmt" - "math/rand" - "time" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - k8Errors "k8s.io/apimachinery/pkg/api/errors" -) - -type InfisicalDynamicSecretHandler struct { - client.Client - Scheme *runtime.Scheme - Random *rand.Rand - IsNamespaceScoped bool -} - -func NewInfisicalDynamicSecretHandler(client client.Client, scheme *runtime.Scheme, isNamespaceScoped bool) *InfisicalDynamicSecretHandler { - return &InfisicalDynamicSecretHandler{ - Client: client, - Scheme: scheme, - Random: rand.New(rand.NewSource(time.Now().UnixNano())), - IsNamespaceScoped: isNamespaceScoped, - } -} - -func (h *InfisicalDynamicSecretHandler) SetupAPIConfig(infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret, infisicalConfig map[string]string) error { - if infisicalDynamicSecret.Spec.HostAPI == "" { - api.API_HOST_URL = infisicalConfig["hostAPI"] - } else { - api.API_HOST_URL = util.AppendAPIEndpoint(infisicalDynamicSecret.Spec.HostAPI) - } - return nil -} - -func (h *InfisicalDynamicSecretHandler) getInfisicalCaCertificateFromKubeSecret(ctx context.Context, infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret) (caCertificate string, err error) { - - caCertificateFromKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, h.Client, types.NamespacedName{ - Namespace: infisicalDynamicSecret.Spec.TLS.CaRef.SecretNamespace, - Name: infisicalDynamicSecret.Spec.TLS.CaRef.SecretName, - }) - - if k8Errors.IsNotFound(err) { - return "", fmt.Errorf("kubernetes secret containing custom CA certificate cannot be found. [err=%s]", err) - } - - if util.IsNamespaceScopedError(err, h.IsNamespaceScoped) { - return "", fmt.Errorf("unable to fetch Kubernetes CA certificate secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the CA certificate secret is in the same namespace as the operator. [err=%v]", err) - } - - if err != nil { - return "", fmt.Errorf("something went wrong when fetching your CA certificate [err=%s]", err) - } - - caCertificateFromSecret := string(caCertificateFromKubeSecret.Data[infisicalDynamicSecret.Spec.TLS.CaRef.SecretKey]) - - return caCertificateFromSecret, nil -} - -func (h *InfisicalDynamicSecretHandler) HandleCACertificate(ctx context.Context, infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret) error { - if infisicalDynamicSecret.Spec.TLS.CaRef.SecretName != "" { - caCert, err := h.getInfisicalCaCertificateFromKubeSecret(ctx, infisicalDynamicSecret) - if err != nil { - return err - } - api.API_CA_CERTIFICATE = caCert - } else { - api.API_CA_CERTIFICATE = "" - } - return nil -} - -func (h *InfisicalDynamicSecretHandler) ReconcileInfisicalDynamicSecret(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, resourceVariablesMap map[string]util.ResourceVariables) (time.Duration, error) { - reconciler := &InfisicalDynamicSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - Random: h.Random, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.ReconcileInfisicalDynamicSecret(ctx, logger, infisicalDynamicSecret, resourceVariablesMap) -} - -func (h *InfisicalDynamicSecretHandler) HandleLeaseRevocation(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - reconciler := &InfisicalDynamicSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - Random: h.Random, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.HandleLeaseRevocation(ctx, logger, infisicalDynamicSecret, resourceVariablesMap) -} - -func (h *InfisicalDynamicSecretHandler) SetReconcileConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) { - reconciler := &InfisicalDynamicSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - Random: h.Random, - IsNamespaceScoped: h.IsNamespaceScoped, - } - reconciler.SetReconcileConditionStatus(ctx, logger, infisicalDynamicSecret, errorToConditionOn) -} - -func (h *InfisicalDynamicSecretHandler) SetReconcileAutoRedeploymentConditionStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, numDeployments int, errorToConditionOn error) { - reconciler := &InfisicalDynamicSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - Random: h.Random, - IsNamespaceScoped: h.IsNamespaceScoped, - } - reconciler.SetReconcileAutoRedeploymentConditionStatus(ctx, logger, infisicalDynamicSecret, numDeployments, errorToConditionOn) -} diff --git a/k8-operator/internal/services/infisicaldynamicsecret/reconciler.go b/k8-operator/internal/services/infisicaldynamicsecret/reconciler.go deleted file mode 100644 index e763e93080..0000000000 --- a/k8-operator/internal/services/infisicaldynamicsecret/reconciler.go +++ /dev/null @@ -1,431 +0,0 @@ -package infisicaldynamicsecret - -import ( - "context" - "fmt" - "math/rand" - "strings" - "time" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - corev1 "k8s.io/api/core/v1" - - infisicalSdk "github.com/infisical/go-sdk" - k8Errors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" -) - -type InfisicalDynamicSecretReconciler struct { - client.Client - Scheme *runtime.Scheme - Random *rand.Rand - IsNamespaceScoped bool -} - -func (r *InfisicalDynamicSecretReconciler) createInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret, versionAnnotationValue string) error { - secretType := infisicalDynamicSecret.Spec.ManagedSecretReference.SecretType - - // copy labels and annotations from InfisicalSecret CRD - labels := map[string]string{} - for k, v := range infisicalDynamicSecret.Labels { - labels[k] = v - } - - annotations := map[string]string{} - systemPrefixes := []string{"kubectl.kubernetes.io/", "kubernetes.io/", "k8s.io/", "helm.sh/"} - for k, v := range infisicalDynamicSecret.Annotations { - isSystem := false - for _, prefix := range systemPrefixes { - if strings.HasPrefix(k, prefix) { - isSystem = true - break - } - } - if !isSystem { - annotations[k] = v - } - } - - annotations[constants.SECRET_VERSION_ANNOTATION] = versionAnnotationValue - - // create a new secret as specified by the managed secret spec of CRD - newKubeSecretInstance := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretName, - Namespace: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretNamespace, - Annotations: annotations, - Labels: labels, - }, - Type: corev1.SecretType(secretType), - } - - if infisicalDynamicSecret.Spec.ManagedSecretReference.CreationPolicy == "Owner" { - // Set InfisicalSecret instance as the owner and controller of the managed secret - err := ctrl.SetControllerReference(&infisicalDynamicSecret, newKubeSecretInstance, r.Scheme) - if err != nil { - return err - } - } - - err := r.Client.Create(ctx, newKubeSecretInstance) - if err != nil { - return fmt.Errorf("unable to create the managed Kubernetes secret : %w", err) - } - - logger.Info(fmt.Sprintf("Successfully created a managed Kubernetes secret. [type: %s]", secretType)) - return nil -} - -func (r *InfisicalDynamicSecretReconciler) getResourceVariables(infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret, resourceVariablesMap map[string]util.ResourceVariables) util.ResourceVariables { - - var resourceVariables util.ResourceVariables - - if _, ok := resourceVariablesMap[string(infisicalDynamicSecret.UID)]; !ok { - - ctx, cancel := context.WithCancel(context.Background()) - - client := infisicalSdk.NewInfisicalClient(ctx, infisicalSdk.Config{ - SiteUrl: api.API_HOST_URL, - CaCertificate: api.API_CA_CERTIFICATE, - UserAgent: api.USER_AGENT_NAME, - }) - - resourceVariablesMap[string(infisicalDynamicSecret.UID)] = util.ResourceVariables{ - InfisicalClient: client, - CancelCtx: cancel, - AuthDetails: util.AuthenticationDetails{}, - } - - resourceVariables = resourceVariablesMap[string(infisicalDynamicSecret.UID)] - - } else { - resourceVariables = resourceVariablesMap[string(infisicalDynamicSecret.UID)] - } - - return resourceVariables -} - -func (r *InfisicalDynamicSecretReconciler) CreateDynamicSecretLease(ctx context.Context, logger logr.Logger, infisicalClient infisicalSdk.InfisicalClientInterface, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, destination *corev1.Secret) error { - project, err := util.GetProjectByID(infisicalClient.Auth().GetAccessToken(), infisicalDynamicSecret.Spec.DynamicSecret.ProjectID) - if err != nil { - return err - } - - request := infisicalSdk.CreateDynamicSecretLeaseOptions{ - DynamicSecretName: infisicalDynamicSecret.Spec.DynamicSecret.SecretName, - ProjectSlug: project.Slug, - SecretPath: infisicalDynamicSecret.Spec.DynamicSecret.SecretPath, - EnvironmentSlug: infisicalDynamicSecret.Spec.DynamicSecret.EnvironmentSlug, - } - - if infisicalDynamicSecret.Spec.LeaseTTL != "" { - request.TTL = infisicalDynamicSecret.Spec.LeaseTTL - } - - leaseData, dynamicSecret, lease, err := infisicalClient.DynamicSecrets().Leases().Create(request) - - if err != nil { - return fmt.Errorf("unable to create lease [err=%s]", err) - } - - newLeaseStatus := &v1alpha1.InfisicalDynamicSecretLease{ - ID: lease.Id, - ExpiresAt: metav1.NewTime(lease.ExpireAt), - CreationTimestamp: metav1.NewTime(time.Now()), - Version: int64(lease.Version), - } - - infisicalDynamicSecret.Status.DynamicSecretID = dynamicSecret.Id - infisicalDynamicSecret.Status.MaxTTL = dynamicSecret.MaxTTL - infisicalDynamicSecret.Status.Lease = newLeaseStatus - - // write the leaseData to the destination secret - destinationData := map[string]string{} - - for key, value := range leaseData { - if strValue, ok := value.(string); ok { - destinationData[key] = strValue - } else { - return fmt.Errorf("unable to convert value to string for key %s", key) - } - } - - destination.StringData = destinationData - destination.Annotations[constants.SECRET_VERSION_ANNOTATION] = fmt.Sprintf("%s-%d", lease.Id, lease.Version) - - if err := r.Client.Update(ctx, destination); err != nil { - return fmt.Errorf("unable to update destination secret [err=%s]", err) - } - - logger.Info(fmt.Sprintf("New lease successfully created [leaseId=%s]", lease.Id)) - return nil -} - -func (r *InfisicalDynamicSecretReconciler) RenewDynamicSecretLease(ctx context.Context, logger logr.Logger, infisicalClient infisicalSdk.InfisicalClientInterface, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, destination *corev1.Secret) error { - project, err := util.GetProjectByID(infisicalClient.Auth().GetAccessToken(), infisicalDynamicSecret.Spec.DynamicSecret.ProjectID) - if err != nil { - return err - } - - request := infisicalSdk.RenewDynamicSecretLeaseOptions{ - LeaseId: infisicalDynamicSecret.Status.Lease.ID, - ProjectSlug: project.Slug, - SecretPath: infisicalDynamicSecret.Spec.DynamicSecret.SecretPath, - EnvironmentSlug: infisicalDynamicSecret.Spec.DynamicSecret.EnvironmentSlug, - } - - if infisicalDynamicSecret.Spec.LeaseTTL != "" { - request.TTL = infisicalDynamicSecret.Spec.LeaseTTL - } - - lease, err := infisicalClient.DynamicSecrets().Leases().RenewById(request) - - if err != nil { - - if strings.Contains(err.Error(), "TTL cannot be larger than max ttl") || // Case 1: TTL is larger than the max TTL - strings.Contains(err.Error(), "Dynamic secret lease with ID") { // Case 2: The lease has already expired and has been deleted - return constants.ErrInvalidLease - } - - return fmt.Errorf("unable to renew lease [err=%s]", err) - } - - infisicalDynamicSecret.Status.Lease.ExpiresAt = metav1.NewTime(lease.ExpireAt) - - // update the infisicalDynamicSecret status - if err := r.Client.Status().Update(ctx, infisicalDynamicSecret); err != nil { - return fmt.Errorf("unable to update InfisicalDynamicSecret status [err=%s]", err) - } - - logger.Info(fmt.Sprintf("Lease successfully renewed [leaseId=%s]", lease.Id)) - return nil - -} - -func (r *InfisicalDynamicSecretReconciler) updateResourceVariables(infisicalDynamicSecret v1alpha1.InfisicalDynamicSecret, resourceVariables util.ResourceVariables, resourceVariablesMap map[string]util.ResourceVariables) { - resourceVariablesMap[string(infisicalDynamicSecret.UID)] = resourceVariables -} - -func (r *InfisicalDynamicSecretReconciler) HandleLeaseRevocation(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - if infisicalDynamicSecret.Spec.LeaseRevocationPolicy != string(constants.DYNAMIC_SECRET_LEASE_REVOCATION_POLICY_ENABLED) { - return nil - } - - resourceVariables := r.getResourceVariables(*infisicalDynamicSecret, resourceVariablesMap) - infisicalClient := resourceVariables.InfisicalClient - - logger.Info("Authenticating for lease revocation") - authDetails, err := util.HandleAuthentication(ctx, util.SecretAuthInput{ - Secret: *infisicalDynamicSecret, - Type: util.SecretCrd.INFISICAL_DYNAMIC_SECRET, - }, r.Client, infisicalClient, r.IsNamespaceScoped) - - if err != nil { - return fmt.Errorf("unable to authenticate for lease revocation [err=%s]", err) - } - - r.updateResourceVariables(*infisicalDynamicSecret, util.ResourceVariables{ - InfisicalClient: infisicalClient, - CancelCtx: resourceVariables.CancelCtx, - AuthDetails: authDetails, - }, resourceVariablesMap) - - if infisicalDynamicSecret.Status.Lease == nil { - return nil - } - - project, err := util.GetProjectByID(infisicalClient.Auth().GetAccessToken(), infisicalDynamicSecret.Spec.DynamicSecret.ProjectID) - - if err != nil { - return err - } - - infisicalClient.DynamicSecrets().Leases().DeleteById(infisicalSdk.DeleteDynamicSecretLeaseOptions{ - LeaseId: infisicalDynamicSecret.Status.Lease.ID, - ProjectSlug: project.Slug, - SecretPath: infisicalDynamicSecret.Spec.DynamicSecret.SecretPath, - EnvironmentSlug: infisicalDynamicSecret.Spec.DynamicSecret.EnvironmentSlug, - }) - - // update the destination data to remove the lease data - destination, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Name: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretName, - Namespace: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretNamespace, - }) - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return fmt.Errorf("unable to fetch Kubernetes destination secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the destination secret is in the same namespace as the operator. [err=%v]", err) - } - return fmt.Errorf("unable to fetch destination secret [err=%s]", err) - } - - destination.Data = map[string][]byte{} - - if err := r.Client.Update(ctx, destination); err != nil { - return fmt.Errorf("unable to update destination secret [err=%s]", err) - } - - logger.Info(fmt.Sprintf("Lease successfully revoked [leaseId=%s]", infisicalDynamicSecret.Status.Lease.ID)) - - return nil -} - -func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, resourceVariablesMap map[string]util.ResourceVariables) (time.Duration, error) { - - resourceVariables := r.getResourceVariables(*infisicalDynamicSecret, resourceVariablesMap) - infisicalClient := resourceVariables.InfisicalClient - cancelCtx := resourceVariables.CancelCtx - authDetails := resourceVariables.AuthDetails - - defaultNextReconcile := 5 * time.Second - nextReconcile := defaultNextReconcile - - var err error - - if authDetails.AuthStrategy == "" { - logger.Info("No authentication strategy found. Attempting to authenticate") - authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{ - Secret: *infisicalDynamicSecret, - Type: util.SecretCrd.INFISICAL_DYNAMIC_SECRET, - }, r.Client, infisicalClient, r.IsNamespaceScoped) - - if err != nil { - return nextReconcile, fmt.Errorf("unable to authenticate [err=%s]", err) - } - - r.updateResourceVariables(*infisicalDynamicSecret, util.ResourceVariables{ - InfisicalClient: infisicalClient, - CancelCtx: cancelCtx, - AuthDetails: authDetails, - }, resourceVariablesMap) - } - - destination, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Name: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretName, - Namespace: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretNamespace, - }) - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return nextReconcile, fmt.Errorf("unable to fetch Kubernetes destination secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the destination secret is in the same namespace as the operator. [err=%v]", err) - } - if k8Errors.IsNotFound(err) { - - annotationValue := "" - if infisicalDynamicSecret.Status.Lease != nil { - annotationValue = fmt.Sprintf("%s-%d", infisicalDynamicSecret.Status.Lease.ID, infisicalDynamicSecret.Status.Lease.Version) - } - - r.createInfisicalManagedKubeSecret(ctx, logger, *infisicalDynamicSecret, annotationValue) - - destination, err = util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Name: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretName, - Namespace: infisicalDynamicSecret.Spec.ManagedSecretReference.SecretNamespace, - }) - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return nextReconcile, fmt.Errorf("unable to fetch Kubernetes destination secret after creation. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the destination secret is in the same namespace as the operator. [err=%v]", err) - } - return nextReconcile, fmt.Errorf("unable to fetch destination secret after creation [err=%s]", err) - } - - } else { - return nextReconcile, fmt.Errorf("unable to fetch destination secret") - } - } - - if infisicalDynamicSecret.Status.Lease == nil { - err := r.CreateDynamicSecretLease(ctx, logger, infisicalClient, infisicalDynamicSecret, destination) - - return defaultNextReconcile, err // Short requeue after creation - } else { - now := time.Now() - leaseExpiresAt := infisicalDynamicSecret.Status.Lease.ExpiresAt.Time - - // Calculate from creation to expiration - originalLeaseDuration := leaseExpiresAt.Sub(infisicalDynamicSecret.Status.Lease.CreationTimestamp.Time) - - // Generate a random percentage between 20% and 30% - jitterPercentage := 20 + r.Random.Intn(11) // Random int from 0 to 10, then add 20 - renewalThreshold := originalLeaseDuration * time.Duration(jitterPercentage) / 100 - timeUntilExpiration := time.Until(leaseExpiresAt) - - nextReconcile = timeUntilExpiration / 2 - - // Max TTL - if infisicalDynamicSecret.Status.MaxTTL != "" { - maxTTLDuration, err := util.ConvertIntervalToDuration(&infisicalDynamicSecret.Status.MaxTTL) - if err != nil { - return defaultNextReconcile, fmt.Errorf("unable to parse MaxTTL duration: %w", err) - } - - // Calculate when this dynamic secret will hit its max TTL - maxTTLExpirationTime := infisicalDynamicSecret.Status.Lease.CreationTimestamp.Add(maxTTLDuration) - - // Calculate remaining time until max TTL - timeUntilMaxTTL := maxTTLExpirationTime.Sub(now) - maxTTLThreshold := maxTTLDuration * 40 / 100 - - // If we have less than 40% of max TTL remaining or have exceeded it, create new lease - if timeUntilMaxTTL <= maxTTLThreshold || now.After(maxTTLExpirationTime) { - logger.Info(fmt.Sprintf("Approaching or exceeded max TTL [timeUntilMaxTTL=%v] [maxTTLThreshold=%v], creating new lease...", - timeUntilMaxTTL, - maxTTLThreshold)) - - err := r.CreateDynamicSecretLease(ctx, logger, infisicalClient, infisicalDynamicSecret, destination) - return defaultNextReconcile, err // Short requeue after creation - } - } - - // Fail-safe: If the lease has expired we create a new dynamic secret directly. - if now.After(leaseExpiresAt) { - logger.Info("Lease has expired, creating new lease...") - err = r.CreateDynamicSecretLease(ctx, logger, infisicalClient, infisicalDynamicSecret, destination) - return defaultNextReconcile, err // Short requeue after creation - } - - if timeUntilExpiration < renewalThreshold || timeUntilExpiration < 30*time.Second { - logger.Info(fmt.Sprintf("Lease renewal needed [leaseId=%s] [timeUntilExpiration=%v] [threshold=%v]", - infisicalDynamicSecret.Status.Lease.ID, - timeUntilExpiration, - renewalThreshold)) - - err = r.RenewDynamicSecretLease(ctx, logger, infisicalClient, infisicalDynamicSecret, destination) - - if err == constants.ErrInvalidLease { - logger.Info("Failed to renew expired lease, creating new lease...") - err = r.CreateDynamicSecretLease(ctx, logger, infisicalClient, infisicalDynamicSecret, destination) - } - return defaultNextReconcile, err // Short requeue after renewal/creation - - } else { - logger.Info(fmt.Sprintf("Lease renewal not needed yet [leaseId=%s] [timeUntilExpiration=%v] [threshold=%v]", - infisicalDynamicSecret.Status.Lease.ID, - timeUntilExpiration, - renewalThreshold)) - } - - // Small buffer (20% of the calculated time) to ensure we don't cut it too close - nextReconcile = nextReconcile * 8 / 10 - - // Minimum and maximum bounds for the reconcile interval (5 min max, 5 min minimum) - nextReconcile = max(5*time.Second, min(nextReconcile, 5*time.Minute)) - } - - if err := r.Client.Status().Update(ctx, infisicalDynamicSecret); err != nil { - return nextReconcile, fmt.Errorf("unable to update InfisicalDynamicSecret status [err=%s]", err) - } - - return nextReconcile, nil -} diff --git a/k8-operator/internal/services/infisicalpushsecret/conditions.go b/k8-operator/internal/services/infisicalpushsecret/conditions.go deleted file mode 100644 index 57227bd646..0000000000 --- a/k8-operator/internal/services/infisicalpushsecret/conditions.go +++ /dev/null @@ -1,156 +0,0 @@ -package infisicalpushsecret - -import ( - "context" - "fmt" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func (r *InfisicalPushSecretReconciler) SetReconcileStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, err error) error { - - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if err != nil { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Reconcile", - Status: metav1.ConditionTrue, - Reason: "Error", - Message: fmt.Sprintf("Reconcile failed, secrets were not pushed to Infisical. Error: %s", err.Error()), - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Reconcile", - Status: metav1.ConditionFalse, - Reason: "OK", - Message: "Reconcile succeeded, secrets were pushed to Infisical", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) - -} - -func (r *InfisicalPushSecretReconciler) SetFailedToReplaceSecretsStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, failMessage string) error { - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if failMessage != "" { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToReplaceSecrets", - Status: metav1.ConditionTrue, - Reason: "Error", - Message: failMessage, - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToReplaceSecrets", - Status: metav1.ConditionFalse, - Reason: "OK", - Message: "No errors, no secrets failed to be replaced in Infisical", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) -} - -func (r *InfisicalPushSecretReconciler) SetFailedToCreateSecretsStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, failMessage string) error { - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if failMessage != "" { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToCreateSecrets", - Status: metav1.ConditionTrue, - Reason: "Error", - Message: failMessage, - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToCreateSecrets", - Status: metav1.ConditionFalse, - Reason: "OK", - Message: "No errors encountered, no secrets failed to be created in Infisical", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) -} - -func (r *InfisicalPushSecretReconciler) SetFailedToUpdateSecretsStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, failMessage string) error { - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if failMessage != "" { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToUpdateSecrets", - Status: metav1.ConditionTrue, - Reason: "Error", - Message: failMessage, - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToUpdateSecrets", - Status: metav1.ConditionFalse, - Reason: "OK", - Message: "No errors encountered, no secrets failed to be updated in Infisical", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) -} - -func (r *InfisicalPushSecretReconciler) SetFailedToDeleteSecretsStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, failMessage string) error { - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if failMessage != "" { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToDeleteSecrets", - Status: metav1.ConditionTrue, - Reason: "Error", - Message: failMessage, - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/FailedToDeleteSecrets", - Status: metav1.ConditionFalse, - Reason: "OK", - Message: "No errors encountered, no secrets failed to be deleted", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) -} - -func (r *InfisicalPushSecretReconciler) SetAuthenticatedStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, errorToConditionOn error) error { - if infisicalPushSecret.Status.Conditions == nil { - infisicalPushSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn != nil { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Authenticated", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: "Failed to authenticate with Infisical API. This can be caused by invalid service token or an invalid API host that is set. Check operator logs for more info", - }) - } else { - meta.SetStatusCondition(&infisicalPushSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/Authenticated", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: "Successfully authenticated with Infisical API", - }) - } - - return r.Client.Status().Update(ctx, infisicalPushSecret) -} diff --git a/k8-operator/internal/services/infisicalpushsecret/handler.go b/k8-operator/internal/services/infisicalpushsecret/handler.go deleted file mode 100644 index 476b2bda2a..0000000000 --- a/k8-operator/internal/services/infisicalpushsecret/handler.go +++ /dev/null @@ -1,103 +0,0 @@ -package infisicalpushsecret - -import ( - "context" - "fmt" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - k8Errors "k8s.io/apimachinery/pkg/api/errors" -) - -type InfisicalPushSecretHandler struct { - client.Client - Scheme *runtime.Scheme - IsNamespaceScoped bool -} - -func NewInfisicalPushSecretHandler(client client.Client, scheme *runtime.Scheme, isNamespaceScoped bool) *InfisicalPushSecretHandler { - return &InfisicalPushSecretHandler{ - Client: client, - Scheme: scheme, - IsNamespaceScoped: isNamespaceScoped, - } -} - -func (h *InfisicalPushSecretHandler) SetupAPIConfig(infisicalPushSecret v1alpha1.InfisicalPushSecret, infisicalConfig map[string]string) error { - if infisicalPushSecret.Spec.HostAPI == "" { - api.API_HOST_URL = infisicalConfig["hostAPI"] - } else { - api.API_HOST_URL = util.AppendAPIEndpoint(infisicalPushSecret.Spec.HostAPI) - } - return nil -} - -func (h *InfisicalPushSecretHandler) getInfisicalCaCertificateFromKubeSecret(ctx context.Context, infisicalPushSecret v1alpha1.InfisicalPushSecret) (caCertificate string, err error) { - - caCertificateFromKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, h.Client, types.NamespacedName{ - Namespace: infisicalPushSecret.Spec.TLS.CaRef.SecretNamespace, - Name: infisicalPushSecret.Spec.TLS.CaRef.SecretName, - }) - - if k8Errors.IsNotFound(err) { - return "", fmt.Errorf("kubernetes secret containing custom CA certificate cannot be found. [err=%s]", err) - } - - if util.IsNamespaceScopedError(err, h.IsNamespaceScoped) { - return "", fmt.Errorf("unable to fetch Kubernetes CA certificate secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the CA certificate secret is in the same namespace as the operator. [err=%v]", err) - } - - if err != nil { - return "", fmt.Errorf("something went wrong when fetching your CA certificate [err=%s]", err) - } - - caCertificateFromSecret := string(caCertificateFromKubeSecret.Data[infisicalPushSecret.Spec.TLS.CaRef.SecretKey]) - - return caCertificateFromSecret, nil -} - -func (h *InfisicalPushSecretHandler) HandleCACertificate(ctx context.Context, infisicalPushSecret v1alpha1.InfisicalPushSecret) error { - if infisicalPushSecret.Spec.TLS.CaRef.SecretName != "" { - caCert, err := h.getInfisicalCaCertificateFromKubeSecret(ctx, infisicalPushSecret) - if err != nil { - return err - } - api.API_CA_CERTIFICATE = caCert - } else { - api.API_CA_CERTIFICATE = "" - } - return nil -} - -func (h *InfisicalPushSecretHandler) ReconcileInfisicalPushSecret(ctx context.Context, logger logr.Logger, infisicalPushSecret *v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - reconciler := &InfisicalPushSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.ReconcileInfisicalPushSecret(ctx, logger, infisicalPushSecret, resourceVariablesMap) -} - -func (h *InfisicalPushSecretHandler) DeleteManagedSecrets(ctx context.Context, logger logr.Logger, infisicalPushSecret *v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - reconciler := &InfisicalPushSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.DeleteManagedSecrets(ctx, logger, infisicalPushSecret, resourceVariablesMap) -} - -func (h *InfisicalPushSecretHandler) SetReconcileStatusCondition(ctx context.Context, infisicalPushSecret *v1alpha1.InfisicalPushSecret, err error) { - reconciler := &InfisicalPushSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - reconciler.SetReconcileStatusCondition(ctx, infisicalPushSecret, err) -} diff --git a/k8-operator/internal/services/infisicalpushsecret/reconciler.go b/k8-operator/internal/services/infisicalpushsecret/reconciler.go deleted file mode 100644 index cdfc326bbc..0000000000 --- a/k8-operator/internal/services/infisicalpushsecret/reconciler.go +++ /dev/null @@ -1,573 +0,0 @@ -package infisicalpushsecret - -import ( - "bytes" - "context" - "fmt" - "strings" - tpl "text/template" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/model" - "github.com/Infisical/infisical/k8-operator/internal/template" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - - generatorUtil "github.com/Infisical/infisical/k8-operator/internal/generator" - infisicalSdk "github.com/infisical/go-sdk" - "k8s.io/apimachinery/pkg/runtime" -) - -type InfisicalPushSecretReconciler struct { - client.Client - Scheme *runtime.Scheme - IsNamespaceScoped bool -} - -func (r *InfisicalPushSecretReconciler) getResourceVariables(infisicalPushSecret v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) util.ResourceVariables { - - var resourceVariables util.ResourceVariables - - if _, ok := resourceVariablesMap[string(infisicalPushSecret.UID)]; !ok { - - ctx, cancel := context.WithCancel(context.Background()) - - client := infisicalSdk.NewInfisicalClient(ctx, infisicalSdk.Config{ - SiteUrl: api.API_HOST_URL, - CaCertificate: api.API_CA_CERTIFICATE, - UserAgent: api.USER_AGENT_NAME, - }) - - resourceVariablesMap[string(infisicalPushSecret.UID)] = util.ResourceVariables{ - InfisicalClient: client, - CancelCtx: cancel, - AuthDetails: util.AuthenticationDetails{}, - } - - resourceVariables = resourceVariablesMap[string(infisicalPushSecret.UID)] - - } else { - resourceVariables = resourceVariablesMap[string(infisicalPushSecret.UID)] - } - - return resourceVariables - -} - -func (r *InfisicalPushSecretReconciler) updateResourceVariables(infisicalPushSecret v1alpha1.InfisicalPushSecret, resourceVariables util.ResourceVariables, resourceVariablesMap map[string]util.ResourceVariables) { - resourceVariablesMap[string(infisicalPushSecret.UID)] = resourceVariables -} - -func (r *InfisicalPushSecretReconciler) processGenerators(ctx context.Context, infisicalPushSecret v1alpha1.InfisicalPushSecret) (map[string]string, error) { - - processedSecrets := make(map[string]string) - - if len(infisicalPushSecret.Spec.Push.Generators) == 0 { - return processedSecrets, nil - } - - for _, generator := range infisicalPushSecret.Spec.Push.Generators { - generatorRef := generator.GeneratorRef - - clusterGenerator := &v1alpha1.ClusterGenerator{} - err := r.Client.Get(ctx, types.NamespacedName{Name: generatorRef.Name}, clusterGenerator) - if err != nil { - return nil, fmt.Errorf("unable to get ClusterGenerator resource [err=%s]", err) - } - if generatorRef.Kind == v1alpha1.GeneratorKindPassword { - // get the custom ClusterGenerator resource from the cluster - - if clusterGenerator.Spec.Generator.PasswordSpec == nil { - return nil, fmt.Errorf("password spec is not defined in the ClusterGenerator resource") - } - - password, err := generatorUtil.GeneratorPassword(*clusterGenerator.Spec.Generator.PasswordSpec) - if err != nil { - return nil, fmt.Errorf("unable to generate password [err=%s]", err) - } - - processedSecrets[generator.DestinationSecretName] = password - } - - if generatorRef.Kind == v1alpha1.GeneratorKindUUID { - - uuid, err := generatorUtil.GeneratorUUID() - if err != nil { - return nil, fmt.Errorf("unable to generate UUID [err=%s]", err) - } - - processedSecrets[generator.DestinationSecretName] = uuid - } - } - - return processedSecrets, nil - -} - -func (r *InfisicalPushSecretReconciler) processTemplatedSecrets(infisicalPushSecret v1alpha1.InfisicalPushSecret, kubePushSecret *corev1.Secret, destination v1alpha1.InfisicalPushSecretDestination) (map[string]string, error) { - - processedSecrets := make(map[string]string) - - sourceSecrets := make(map[string]model.SecretTemplateOptions) - for key, value := range kubePushSecret.Data { - - sourceSecrets[key] = model.SecretTemplateOptions{ - Value: string(value), - SecretPath: destination.SecretsPath, - } - } - - if infisicalPushSecret.Spec.Push.Secret.Template == nil || (infisicalPushSecret.Spec.Push.Secret.Template != nil && infisicalPushSecret.Spec.Push.Secret.Template.IncludeAllSecrets) { - for key, value := range kubePushSecret.Data { - processedSecrets[key] = string(value) - } - } - - if infisicalPushSecret.Spec.Push.Secret.Template != nil && - len(infisicalPushSecret.Spec.Push.Secret.Template.Data) > 0 { - - for templateKey, userTemplate := range infisicalPushSecret.Spec.Push.Secret.Template.Data { - - tmpl, err := tpl.New("push-secret-templates").Funcs(template.GetTemplateFunctions()).Parse(userTemplate) - if err != nil { - return nil, fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) - } - - buf := bytes.NewBuffer(nil) - err = tmpl.Execute(buf, sourceSecrets) - if err != nil { - return nil, fmt.Errorf("unable to execute template: %s [err=%v]", templateKey, err) - } - - processedSecrets[templateKey] = buf.String() - } - } - - return processedSecrets, nil -} - -func (r *InfisicalPushSecretReconciler) ReconcileInfisicalPushSecret(ctx context.Context, logger logr.Logger, infisicalPushSecret *v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - - resourceVariables := r.getResourceVariables(*infisicalPushSecret, resourceVariablesMap) - infisicalClient := resourceVariables.InfisicalClient - cancelCtx := resourceVariables.CancelCtx - authDetails := resourceVariables.AuthDetails - var err error - - if authDetails.AuthStrategy == "" { - logger.Info("No authentication strategy found. Attempting to authenticate") - authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{ - Secret: *infisicalPushSecret, - Type: util.SecretCrd.INFISICAL_PUSH_SECRET, - }, r.Client, infisicalClient, r.IsNamespaceScoped) - r.SetAuthenticatedStatusCondition(ctx, infisicalPushSecret, err) - - if err != nil { - return fmt.Errorf("unable to authenticate [err=%s]", err) - } - - r.updateResourceVariables(*infisicalPushSecret, util.ResourceVariables{ - InfisicalClient: infisicalClient, - CancelCtx: cancelCtx, - AuthDetails: authDetails, - }, resourceVariablesMap) - } - - processedSecrets := make(map[string]string) - - if infisicalPushSecret.Spec.Push.Secret != nil { - kubePushSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Namespace: infisicalPushSecret.Spec.Push.Secret.SecretNamespace, - Name: infisicalPushSecret.Spec.Push.Secret.SecretName, - }) - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return fmt.Errorf("unable to fetch Kubernetes destination secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the destination secret is in the same namespace as the operator. [err=%v]", err) - } - - return fmt.Errorf("unable to fetch kube secret [err=%s]", err) - } - - processedSecrets, err = r.processTemplatedSecrets(*infisicalPushSecret, kubePushSecret, infisicalPushSecret.Spec.Destination) - if err != nil { - return fmt.Errorf("unable to process templated secrets [err=%s]", err) - } - } - - generatorSecrets, err := r.processGenerators(ctx, *infisicalPushSecret) - if err != nil { - return fmt.Errorf("unable to process generators [err=%s]", err) - } - - for key, value := range generatorSecrets { - processedSecrets[key] = value - } - - destination := infisicalPushSecret.Spec.Destination - existingSecrets, err := infisicalClient.Secrets().List(infisicalSdk.ListSecretsOptions{ - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - IncludeImports: false, - }) - - getExistingSecretByKey := func(key string) *infisicalSdk.Secret { - for _, secret := range existingSecrets { - if secret.SecretKey == key { - return &secret - } - } - return nil - } - - getExistingSecretById := func(id string) *infisicalSdk.Secret { - for _, secret := range existingSecrets { - if secret.ID == id { - return &secret - } - } - return nil - } - - updateExistingSecretByKey := func(key string, newSecretValue string) { - for i := range existingSecrets { - if existingSecrets[i].SecretKey == key { - existingSecrets[i].SecretValue = newSecretValue - break - } - } - } - - if err != nil { - return fmt.Errorf("unable to list secrets [err=%s]", err) - } - - updatePolicy := infisicalPushSecret.Spec.UpdatePolicy - - var secretsFailedToCreate []string - var secretsFailedToUpdate []string - var secretsFailedToDelete []string - var secretsFailedToReplaceById []string - - // If the ManagedSecrets are nil, we know this is the first time the InfisicalPushSecret is being reconciled. - if infisicalPushSecret.Status.ManagedSecrets == nil { - - infisicalPushSecret.Status.ManagedSecrets = make(map[string]string) // (string[id], string[key] ) - - for secretKey, secretValue := range processedSecrets { - if exists := getExistingSecretByKey(secretKey); exists != nil { - - if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) { - updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{ - SecretKey: secretKey, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - NewSecretValue: secretValue, - }) - - if err != nil { - secretsFailedToUpdate = append(secretsFailedToUpdate, secretKey) - logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", secretKey, err)) - continue - } - - infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = secretKey - } - } else { - createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{ - SecretKey: secretKey, - SecretValue: secretValue, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToCreate = append(secretsFailedToCreate, secretKey) - logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", secretKey, err)) - continue - } - - infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = secretKey - } - } - } else { - - // Loop over all the managed secrets, and find the corresponding existingSecret that has the same ID. If the key doesn't match, delete the secret, and re-create it with the correct key/value - for managedSecretId, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets { - - existingSecret := getExistingSecretById(managedSecretId) - - if existingSecret != nil { - - if existingSecret.SecretKey != managedSecretKey { - // Secret key has changed, lets delete the secret and re-create it with the correct key - - logger.Info(fmt.Sprintf("Secret with ID [id=%s] has changed key from [%s] to [%s]. Deleting and re-creating secret", managedSecretId, managedSecretKey, existingSecret.SecretKey)) - - deletedSecret, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{ - SecretKey: existingSecret.SecretKey, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToReplaceById = append(secretsFailedToReplaceById, managedSecretKey) - logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err)) - continue - } - - createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{ - SecretKey: managedSecretKey, - SecretValue: existingSecret.SecretValue, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToReplaceById = append(secretsFailedToReplaceById, managedSecretKey) - logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", managedSecretKey, err)) - continue - } - - delete(infisicalPushSecret.Status.ManagedSecrets, deletedSecret.ID) - infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = managedSecretKey - } - - } - } - - // We need to check if any of the secrets have been removed in the new kube secret - for _, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets { - - if _, ok := processedSecrets[managedSecretKey]; !ok { - - // Secret has been removed, verify that the secret is managed by the operator - if getExistingSecretByKey(managedSecretKey) != nil { - logger.Info(fmt.Sprintf("Secret with key [key=%s] has been removed from the kube secret. Deleting secret from Infisical", managedSecretKey)) - - deletedSecret, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{ - SecretKey: managedSecretKey, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToDelete = append(secretsFailedToDelete, managedSecretKey) - logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err)) - continue - } - - delete(infisicalPushSecret.Status.ManagedSecrets, deletedSecret.ID) - } - } - } - - // We need to check if any new secrets have been added in the kube secret - for currentSecretKey := range processedSecrets { - - if exists := getExistingSecretByKey(currentSecretKey); exists == nil { - - // Some secrets has been added, verify that the secret that has been added is not already managed by the operator - if _, ok := infisicalPushSecret.Status.ManagedSecrets[currentSecretKey]; !ok { - - // Secret was not managed by the operator, lets add it - logger.Info(fmt.Sprintf("Secret with key [key=%s] has been added to the kube secret. Creating secret in Infisical", currentSecretKey)) - - createdSecret, err := infisicalClient.Secrets().Create(infisicalSdk.CreateSecretOptions{ - SecretKey: currentSecretKey, - SecretValue: processedSecrets[currentSecretKey], - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToCreate = append(secretsFailedToCreate, currentSecretKey) - logger.Info(fmt.Sprintf("unable to create secret [key=%s] [err=%s]", currentSecretKey, err)) - continue - } - - infisicalPushSecret.Status.ManagedSecrets[createdSecret.ID] = currentSecretKey - } - } else { - if updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) { - - existingSecret := getExistingSecretByKey(currentSecretKey) - - if existingSecret != nil && existingSecret.SecretValue != processedSecrets[currentSecretKey] { - logger.Info(fmt.Sprintf("Secret with key [key=%s] has changed value. Updating secret in Infisical", currentSecretKey)) - - updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{ - SecretKey: currentSecretKey, - NewSecretValue: processedSecrets[currentSecretKey], - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToUpdate = append(secretsFailedToUpdate, currentSecretKey) - logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", currentSecretKey, err)) - continue - } - - updateExistingSecretByKey(currentSecretKey, processedSecrets[currentSecretKey]) - infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = currentSecretKey - } - } - } - } - - // Check if any of the existing secrets values have changed - for secretKey, secretValue := range processedSecrets { - - existingSecret := getExistingSecretByKey(secretKey) - - if existingSecret != nil { - - _, managedByOperator := infisicalPushSecret.Status.ManagedSecrets[existingSecret.ID] - - if secretValue != existingSecret.SecretValue { - - if managedByOperator || updatePolicy == string(constants.PUSH_SECRET_REPLACE_POLICY_ENABLED) { - logger.Info(fmt.Sprintf("Secret with key [key=%s] has changed value. Updating secret in Infisical", secretKey)) - - updatedSecret, err := infisicalClient.Secrets().Update(infisicalSdk.UpdateSecretOptions{ - SecretKey: secretKey, - NewSecretValue: secretValue, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - secretsFailedToUpdate = append(secretsFailedToUpdate, secretKey) - logger.Info(fmt.Sprintf("unable to update secret [key=%s] [err=%s]", secretKey, err)) - continue - } - - infisicalPushSecret.Status.ManagedSecrets[updatedSecret.ID] = secretKey - } - } - } - } - } - - var errorMessage string - if len(secretsFailedToCreate) > 0 { - errorMessage = fmt.Sprintf("Failed to create secrets: [%s]", strings.Join(secretsFailedToCreate, ", ")) - } else { - errorMessage = "" - } - r.SetFailedToCreateSecretsStatusCondition(ctx, infisicalPushSecret, fmt.Sprintf("Failed to create secrets: [%s]", errorMessage)) - - if len(secretsFailedToUpdate) > 0 { - errorMessage = fmt.Sprintf("Failed to update secrets: [%s]", strings.Join(secretsFailedToUpdate, ", ")) - } else { - errorMessage = "" - } - r.SetFailedToUpdateSecretsStatusCondition(ctx, infisicalPushSecret, fmt.Sprintf("Failed to update secrets: [%s]", errorMessage)) - - if len(secretsFailedToDelete) > 0 { - errorMessage = fmt.Sprintf("Failed to delete secrets: [%s]", strings.Join(secretsFailedToDelete, ", ")) - } else { - errorMessage = "" - } - r.SetFailedToDeleteSecretsStatusCondition(ctx, infisicalPushSecret, errorMessage) - - if len(secretsFailedToReplaceById) > 0 { - errorMessage = fmt.Sprintf("Failed to replace secrets: [%s]", strings.Join(secretsFailedToReplaceById, ", ")) - } else { - errorMessage = "" - } - r.SetFailedToReplaceSecretsStatusCondition(ctx, infisicalPushSecret, errorMessage) - - // Update the status of the InfisicalPushSecret - if err := r.Client.Status().Update(ctx, infisicalPushSecret); err != nil { - return fmt.Errorf("unable to update status of InfisicalPushSecret [err=%s]", err) - } - - return nil - -} - -func (r *InfisicalPushSecretReconciler) DeleteManagedSecrets(ctx context.Context, logger logr.Logger, infisicalPushSecret *v1alpha1.InfisicalPushSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - if infisicalPushSecret.Spec.DeletionPolicy != string(constants.PUSH_SECRET_DELETE_POLICY_ENABLED) { - return nil - } - - resourceVariables := r.getResourceVariables(*infisicalPushSecret, resourceVariablesMap) - infisicalClient := resourceVariables.InfisicalClient - cancelCtx := resourceVariables.CancelCtx - authDetails := resourceVariables.AuthDetails - var err error - - if authDetails.AuthStrategy == "" { - logger.Info("No authentication strategy found. Attempting to authenticate") - authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{ - Secret: *infisicalPushSecret, - Type: util.SecretCrd.INFISICAL_PUSH_SECRET, - }, r.Client, infisicalClient, r.IsNamespaceScoped) - r.SetAuthenticatedStatusCondition(ctx, infisicalPushSecret, err) - - if err != nil { - return fmt.Errorf("unable to authenticate [err=%s]", err) - } - - r.updateResourceVariables(*infisicalPushSecret, util.ResourceVariables{ - InfisicalClient: infisicalClient, - CancelCtx: cancelCtx, - AuthDetails: authDetails, - }, resourceVariablesMap) - } - - destination := infisicalPushSecret.Spec.Destination - existingSecrets, err := resourceVariables.InfisicalClient.Secrets().List(infisicalSdk.ListSecretsOptions{ - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - IncludeImports: false, - }) - - if err != nil { - return fmt.Errorf("unable to list secrets [err=%s]", err) - } - - existingSecretsMappedById := make(map[string]infisicalSdk.Secret) - for _, secret := range existingSecrets { - existingSecretsMappedById[secret.ID] = secret - } - - for managedSecretId, managedSecretKey := range infisicalPushSecret.Status.ManagedSecrets { - - if _, ok := existingSecretsMappedById[managedSecretId]; ok { - logger.Info(fmt.Sprintf("Deleting secret with key [key=%s]", managedSecretKey)) - - _, err := infisicalClient.Secrets().Delete(infisicalSdk.DeleteSecretOptions{ - SecretKey: managedSecretKey, - ProjectID: destination.ProjectID, - Environment: destination.EnvironmentSlug, - SecretPath: destination.SecretsPath, - }) - - if err != nil { - logger.Info(fmt.Sprintf("unable to delete secret [key=%s] [err=%s]", managedSecretKey, err)) - continue - } - } - - } - - return nil -} diff --git a/k8-operator/internal/services/infisicalsecret/conditions.go b/k8-operator/internal/services/infisicalsecret/conditions.go deleted file mode 100644 index 9feb57383e..0000000000 --- a/k8-operator/internal/services/infisicalsecret/conditions.go +++ /dev/null @@ -1,100 +0,0 @@ -package infisicalsecret - -import ( - "context" - "fmt" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func (r *InfisicalSecretReconciler) SetReadyToSyncSecretsConditions(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, secretsCount int, errorToConditionOn error) { - if infisicalSecret.Status.Conditions == nil { - infisicalSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn != nil { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/ReadyToSyncSecrets", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to sync secrets. This can be caused by invalid access token or an invalid API host that is set. Error: %v", errorToConditionOn), - }) - - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/AutoRedeployReady", - Status: metav1.ConditionFalse, - Reason: "Stopped", - Message: fmt.Sprintf("Auto redeployment has been stopped because the operator failed to sync secrets. Error: %v", errorToConditionOn), - }) - } else { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/ReadyToSyncSecrets", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: fmt.Sprintf("Infisical controller has started syncing your secrets. Last reconcile synced %d secrets", secretsCount), - }) - } - - err := r.Client.Status().Update(ctx, infisicalSecret) - if err != nil { - logger.Error(err, "Could not set condition for ReadyToSyncSecrets") - } -} - -func (r *InfisicalSecretReconciler) SetInfisicalTokenLoadCondition(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, authStrategy util.AuthStrategyType, errorToConditionOn error) { - if infisicalSecret.Status.Conditions == nil { - infisicalSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LoadedInfisicalToken", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: fmt.Sprintf("Infisical controller has loaded the Infisical token in provided Kubernetes secret, using %v authentication strategy", authStrategy), - }) - } else { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/LoadedInfisicalToken", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed to load Infisical Token from the provided Kubernetes secret because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalSecret) - if err != nil { - logger.Error(err, "Could not set condition for LoadedInfisicalToken") - } -} - -func (r *InfisicalSecretReconciler) SetInfisicalAutoRedeploymentReady(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, numDeployments int, errorToConditionOn error) { - if infisicalSecret.Status.Conditions == nil { - infisicalSecret.Status.Conditions = []metav1.Condition{} - } - - if errorToConditionOn == nil { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/AutoRedeployReady", - Status: metav1.ConditionTrue, - Reason: "OK", - Message: fmt.Sprintf("Infisical has found %v deployments which are ready to be auto redeployed when secrets change", numDeployments), - }) - } else { - meta.SetStatusCondition(&infisicalSecret.Status.Conditions, metav1.Condition{ - Type: "secrets.infisical.com/AutoRedeployReady", - Status: metav1.ConditionFalse, - Reason: "Error", - Message: fmt.Sprintf("Failed reconcile deployments because: %v", errorToConditionOn), - }) - } - - err := r.Client.Status().Update(ctx, infisicalSecret) - if err != nil { - logger.Error(err, "Could not set condition for AutoRedeployReady") - } -} diff --git a/k8-operator/internal/services/infisicalsecret/handler.go b/k8-operator/internal/services/infisicalsecret/handler.go deleted file mode 100644 index 7fa75581aa..0000000000 --- a/k8-operator/internal/services/infisicalsecret/handler.go +++ /dev/null @@ -1,122 +0,0 @@ -package infisicalsecret - -import ( - "context" - "fmt" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/go-logr/logr" - k8Errors "k8s.io/apimachinery/pkg/api/errors" -) - -type InfisicalSecretHandler struct { - client.Client - Scheme *runtime.Scheme - IsNamespaceScoped bool -} - -func NewInfisicalSecretHandler(client client.Client, scheme *runtime.Scheme, isNamespaceScoped bool) *InfisicalSecretHandler { - return &InfisicalSecretHandler{ - Client: client, - Scheme: scheme, - IsNamespaceScoped: isNamespaceScoped, - } -} - -func (h *InfisicalSecretHandler) SetupAPIConfig(infisicalSecret v1alpha1.InfisicalSecret, infisicalConfig map[string]string) error { - if infisicalSecret.Spec.HostAPI == "" { - api.API_HOST_URL = infisicalConfig["hostAPI"] - } else { - api.API_HOST_URL = util.AppendAPIEndpoint(infisicalSecret.Spec.HostAPI) - } - return nil -} - -func (h *InfisicalSecretHandler) getInfisicalCaCertificateFromKubeSecret(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (caCertificate string, err error) { - - caCertificateFromKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, h.Client, types.NamespacedName{ - Namespace: infisicalSecret.Spec.TLS.CaRef.SecretNamespace, - Name: infisicalSecret.Spec.TLS.CaRef.SecretName, - }) - - if k8Errors.IsNotFound(err) { - return "", fmt.Errorf("kubernetes secret containing custom CA certificate cannot be found. [err=%s]", err) - } - - if err != nil { - if util.IsNamespaceScopedError(err, h.IsNamespaceScoped) { - return "", fmt.Errorf("unable to fetch Kubernetes CA certificate secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the CA certificate secret is in the same namespace as the operator. [err=%v]", err) - } - return "", fmt.Errorf("something went wrong when fetching your CA certificate [err=%s]", err) - } - - caCertificateFromSecret := string(caCertificateFromKubeSecret.Data[infisicalSecret.Spec.TLS.CaRef.SecretKey]) - - return caCertificateFromSecret, nil -} - -func (h *InfisicalSecretHandler) HandleCACertificate(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) error { - if infisicalSecret.Spec.TLS.CaRef.SecretName != "" { - caCert, err := h.getInfisicalCaCertificateFromKubeSecret(ctx, infisicalSecret) - if err != nil { - return err - } - api.API_CA_CERTIFICATE = caCert - } else { - api.API_CA_CERTIFICATE = "" - } - return nil -} - -func (h *InfisicalSecretHandler) ReconcileInfisicalSecret(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, managedKubeSecretReferences []v1alpha1.ManagedKubeSecretConfig, managedKubeConfigMapReferences []v1alpha1.ManagedKubeConfigMapConfig, resourceVariablesMap map[string]util.ResourceVariables) (int, error) { - reconciler := &InfisicalSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.ReconcileInfisicalSecret(ctx, logger, infisicalSecret, managedKubeSecretReferences, managedKubeConfigMapReferences, resourceVariablesMap) -} - -func (h *InfisicalSecretHandler) SetReadyToSyncSecretsConditions(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, secretsCount int, errorToConditionOn error) { - reconciler := &InfisicalSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - reconciler.SetReadyToSyncSecretsConditions(ctx, logger, infisicalSecret, secretsCount, errorToConditionOn) -} - -func (h *InfisicalSecretHandler) SetInfisicalAutoRedeploymentReady(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, numDeployments int, errorToConditionOn error) { - reconciler := &InfisicalSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - reconciler.SetInfisicalAutoRedeploymentReady(ctx, logger, infisicalSecret, numDeployments, errorToConditionOn) -} - -func (h *InfisicalSecretHandler) CloseInstantUpdatesStream(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - reconciler := &InfisicalSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.CloseInstantUpdatesStream(ctx, logger, infisicalSecret, resourceVariablesMap) -} - -// Ensures that SSE stream is open, incase if the stream is already opened - this is a noop -func (h *InfisicalSecretHandler) OpenInstantUpdatesStream(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, resourceVariablesMap map[string]util.ResourceVariables, eventCh chan<- event.TypedGenericEvent[client.Object]) error { - reconciler := &InfisicalSecretReconciler{ - Client: h.Client, - Scheme: h.Scheme, - IsNamespaceScoped: h.IsNamespaceScoped, - } - return reconciler.OpenInstantUpdatesStream(ctx, logger, infisicalSecret, resourceVariablesMap, eventCh) -} diff --git a/k8-operator/internal/services/infisicalsecret/reconciler.go b/k8-operator/internal/services/infisicalsecret/reconciler.go deleted file mode 100644 index 3bd9de34a8..0000000000 --- a/k8-operator/internal/services/infisicalsecret/reconciler.go +++ /dev/null @@ -1,623 +0,0 @@ -package infisicalsecret - -import ( - "bytes" - "context" - "errors" - "fmt" - "net/http" - "strings" - tpl "text/template" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/crypto" - "github.com/Infisical/infisical/k8-operator/internal/model" - "github.com/Infisical/infisical/k8-operator/internal/template" - "github.com/Infisical/infisical/k8-operator/internal/util" - "github.com/Infisical/infisical/k8-operator/internal/util/sse" - "github.com/go-logr/logr" - "github.com/go-resty/resty/v2" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - - infisicalSdk "github.com/infisical/go-sdk" - corev1 "k8s.io/api/core/v1" - k8Errors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ctrl "sigs.k8s.io/controller-runtime" -) - -const FINALIZER_NAME = "secrets.finalizers.infisical.com" - -type InfisicalSecretReconciler struct { - client.Client - Scheme *runtime.Scheme - IsNamespaceScoped bool -} - -func (r *InfisicalSecretReconciler) getInfisicalTokenFromKubeSecret(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (string, error) { - // default to new secret ref structure - secretName := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretName - secretNamespace := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretNamespace - // fall back to previous secret ref - if secretName == "" { - secretName = infisicalSecret.Spec.TokenSecretReference.SecretName - } - - if secretNamespace == "" { - secretNamespace = infisicalSecret.Spec.TokenSecretReference.SecretNamespace - } - - tokenSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Namespace: secretNamespace, - Name: secretName, - }) - - if k8Errors.IsNotFound(err) || (secretNamespace == "" && secretName == "") { - return "", nil - } - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return "", fmt.Errorf("unable to fetch Kubernetes CA certificate secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the CA certificate secret is in the same namespace as the operator. [err=%v]", err) - } - return "", fmt.Errorf("failed to read Infisical token secret from secret named [%s] in namespace [%s]: with error [%w]", infisicalSecret.Spec.TokenSecretReference.SecretName, infisicalSecret.Spec.TokenSecretReference.SecretNamespace, err) - } - - infisicalServiceToken := tokenSecret.Data[constants.INFISICAL_TOKEN_SECRET_KEY_NAME] - - return strings.Replace(string(infisicalServiceToken), " ", "", -1), nil -} - -// Fetches service account credentials from a Kubernetes secret specified in the infisicalSecret object, extracts the access key, public key, and private key from the secret, and returns them as a ServiceAccountCredentials object. -// If any keys are missing or an error occurs, returns an empty object or an error object, respectively. -func (r *InfisicalSecretReconciler) getInfisicalServiceAccountCredentialsFromKubeSecret(ctx context.Context, infisicalSecret v1alpha1.InfisicalSecret) (serviceAccountDetails model.ServiceAccountDetails, err error) { - - secretNamespace := infisicalSecret.Spec.Authentication.ServiceAccount.ServiceAccountSecretReference.SecretNamespace - secretName := infisicalSecret.Spec.Authentication.ServiceAccount.ServiceAccountSecretReference.SecretName - - serviceAccountCredsFromKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Namespace: secretNamespace, - Name: secretName, - }) - - if k8Errors.IsNotFound(err) || (secretNamespace == "" && secretName == "") { - return model.ServiceAccountDetails{}, nil - } - - if err != nil { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return model.ServiceAccountDetails{}, fmt.Errorf("unable to fetch Kubernetes service account credentials secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the service account credentials secret is in the same namespace as the operator. [err=%v]", err) - } - return model.ServiceAccountDetails{}, fmt.Errorf("something went wrong when fetching your service account credentials [err=%s]", err) - } - - accessKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_ACCESS_KEY] - publicKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_PUBLIC_KEY] - privateKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_PRIVATE_KEY] - - if accessKeyFromSecret == nil || publicKeyFromSecret == nil || privateKeyFromSecret == nil { - return model.ServiceAccountDetails{}, nil - } - - return model.ServiceAccountDetails{AccessKey: string(accessKeyFromSecret), PrivateKey: string(privateKeyFromSecret), PublicKey: string(publicKeyFromSecret)}, nil -} - -func convertBinaryToStringMap(binaryMap map[string][]byte) map[string]string { - stringMap := make(map[string]string) - for k, v := range binaryMap { - stringMap[k] = string(v) - } - return stringMap -} - -func (r *InfisicalSecretReconciler) createInfisicalManagedKubeResource(ctx context.Context, logger logr.Logger, infisicalSecret v1alpha1.InfisicalSecret, managedSecretReferenceInterface interface{}, secretsFromAPI []model.SingleEnvironmentVariable, ETag string, resourceType constants.ManagedKubeResourceType) error { - plainProcessedSecrets := make(map[string][]byte) - - var managedTemplateData *v1alpha1.SecretTemplate - - if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_SECRET { - managedTemplateData = managedSecretReferenceInterface.(v1alpha1.ManagedKubeSecretConfig).Template - } else if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_CONFIG_MAP { - managedTemplateData = managedSecretReferenceInterface.(v1alpha1.ManagedKubeConfigMapConfig).Template - } - - if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets { - for _, secret := range secretsFromAPI { - plainProcessedSecrets[secret.Key] = []byte(secret.Value) // plain process - } - } - - if managedTemplateData != nil { - secretKeyValue := make(map[string]model.SecretTemplateOptions) - for _, secret := range secretsFromAPI { - secretKeyValue[secret.Key] = model.SecretTemplateOptions{ - Value: secret.Value, - SecretPath: secret.SecretPath, - } - } - - for templateKey, userTemplate := range managedTemplateData.Data { - tmpl, err := tpl.New("secret-templates").Funcs(template.GetTemplateFunctions()).Parse(userTemplate) - if err != nil { - return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) - } - - buf := bytes.NewBuffer(nil) - err = tmpl.Execute(buf, secretKeyValue) - if err != nil { - return fmt.Errorf("unable to execute template: %s [err=%v]", templateKey, err) - } - plainProcessedSecrets[templateKey] = buf.Bytes() - } - } - - // copy labels and annotations from InfisicalSecret CRD - labels := map[string]string{} - for k, v := range infisicalSecret.Labels { - labels[k] = v - } - - annotations := map[string]string{} - systemPrefixes := []string{"kubectl.kubernetes.io/", "kubernetes.io/", "k8s.io/", "helm.sh/"} - for k, v := range infisicalSecret.Annotations { - isSystem := false - for _, prefix := range systemPrefixes { - if strings.HasPrefix(k, prefix) { - isSystem = true - break - } - } - if !isSystem { - annotations[k] = v - } - } - - if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_SECRET { - - managedSecretReference := managedSecretReferenceInterface.(v1alpha1.ManagedKubeSecretConfig) - - annotations[constants.SECRET_VERSION_ANNOTATION] = ETag - // create a new secret as specified by the managed secret spec of CRD - newKubeSecretInstance := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: managedSecretReference.SecretName, - Namespace: managedSecretReference.SecretNamespace, - Annotations: annotations, - Labels: labels, - }, - Type: corev1.SecretType(managedSecretReference.SecretType), - Data: plainProcessedSecrets, - } - - if managedSecretReference.CreationPolicy == "Owner" { - // Set InfisicalSecret instance as the owner and controller of the managed secret - err := ctrl.SetControllerReference(&infisicalSecret, newKubeSecretInstance, r.Scheme) - if err != nil { - return err - } - } - - err := r.Client.Create(ctx, newKubeSecretInstance) - if err != nil { - return fmt.Errorf("unable to create the managed Kubernetes secret : %w", err) - } - logger.Info(fmt.Sprintf("Successfully created a managed Kubernetes secret with your Infisical secrets. Type: %s", managedSecretReference.SecretType)) - return nil - } else if resourceType == constants.MANAGED_KUBE_RESOURCE_TYPE_CONFIG_MAP { - - managedSecretReference := managedSecretReferenceInterface.(v1alpha1.ManagedKubeConfigMapConfig) - - // create a new config map as specified by the managed secret spec of CRD - newKubeConfigMapInstance := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: managedSecretReference.ConfigMapName, - Namespace: managedSecretReference.ConfigMapNamespace, - Annotations: annotations, - Labels: labels, - }, - Data: convertBinaryToStringMap(plainProcessedSecrets), - } - - if managedSecretReference.CreationPolicy == "Owner" { - // Set InfisicalSecret instance as the owner and controller of the managed config map - err := ctrl.SetControllerReference(&infisicalSecret, newKubeConfigMapInstance, r.Scheme) - if err != nil { - return err - } - } - - err := r.Client.Create(ctx, newKubeConfigMapInstance) - if err != nil { - return fmt.Errorf("unable to create the managed Kubernetes config map : %w", err) - } - logger.Info(fmt.Sprintf("Successfully created a managed Kubernetes config map with your Infisical secrets. Type: %s", managedSecretReference.ConfigMapName)) - return nil - - } - return fmt.Errorf("invalid resource type") - -} - -func (r *InfisicalSecretReconciler) updateInfisicalManagedKubeSecret(ctx context.Context, logger logr.Logger, managedSecretReference v1alpha1.ManagedKubeSecretConfig, managedKubeSecret corev1.Secret, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error { - managedTemplateData := managedSecretReference.Template - - plainProcessedSecrets := make(map[string][]byte) - if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets { - for _, secret := range secretsFromAPI { - plainProcessedSecrets[secret.Key] = []byte(secret.Value) - } - } - - if managedTemplateData != nil { - secretKeyValue := make(map[string]model.SecretTemplateOptions) - for _, secret := range secretsFromAPI { - secretKeyValue[secret.Key] = model.SecretTemplateOptions{ - Value: secret.Value, - SecretPath: secret.SecretPath, - } - } - - for templateKey, userTemplate := range managedTemplateData.Data { - tmpl, err := tpl.New("secret-templates").Funcs(template.GetTemplateFunctions()).Parse(userTemplate) - if err != nil { - return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) - } - - buf := bytes.NewBuffer(nil) - err = tmpl.Execute(buf, secretKeyValue) - if err != nil { - return fmt.Errorf("unable to execute template: %s [err=%v]", templateKey, err) - } - plainProcessedSecrets[templateKey] = buf.Bytes() - } - } - - // Initialize the Annotations map if it's nil - if managedKubeSecret.ObjectMeta.Annotations == nil { - managedKubeSecret.ObjectMeta.Annotations = make(map[string]string) - } - - managedKubeSecret.Data = plainProcessedSecrets - managedKubeSecret.ObjectMeta.Annotations[constants.SECRET_VERSION_ANNOTATION] = ETag - - err := r.Client.Update(ctx, &managedKubeSecret) - if err != nil { - return fmt.Errorf("unable to update Kubernetes secret because [%w]", err) - } - - logger.Info("successfully updated managed Kubernetes secret") - return nil -} - -func (r *InfisicalSecretReconciler) updateInfisicalManagedConfigMap(ctx context.Context, logger logr.Logger, managedConfigMapReference v1alpha1.ManagedKubeConfigMapConfig, managedConfigMap corev1.ConfigMap, secretsFromAPI []model.SingleEnvironmentVariable, ETag string) error { - managedTemplateData := managedConfigMapReference.Template - - plainProcessedSecrets := make(map[string][]byte) - if managedTemplateData == nil || managedTemplateData.IncludeAllSecrets { - for _, secret := range secretsFromAPI { - plainProcessedSecrets[secret.Key] = []byte(secret.Value) - } - } - - if managedTemplateData != nil { - secretKeyValue := make(map[string]model.SecretTemplateOptions) - for _, secret := range secretsFromAPI { - secretKeyValue[secret.Key] = model.SecretTemplateOptions{ - Value: secret.Value, - SecretPath: secret.SecretPath, - } - } - - for templateKey, userTemplate := range managedTemplateData.Data { - tmpl, err := tpl.New("secret-templates").Funcs(template.GetTemplateFunctions()).Parse(userTemplate) - if err != nil { - return fmt.Errorf("unable to compile template: %s [err=%v]", templateKey, err) - } - - buf := bytes.NewBuffer(nil) - err = tmpl.Execute(buf, secretKeyValue) - if err != nil { - return fmt.Errorf("unable to execute template: %s [err=%v]", templateKey, err) - } - plainProcessedSecrets[templateKey] = buf.Bytes() - } - } - - // Initialize the Annotations map if it's nil - if managedConfigMap.ObjectMeta.Annotations == nil { - managedConfigMap.ObjectMeta.Annotations = make(map[string]string) - } - - managedConfigMap.Data = convertBinaryToStringMap(plainProcessedSecrets) - managedConfigMap.ObjectMeta.Annotations[constants.SECRET_VERSION_ANNOTATION] = ETag - - err := r.Client.Update(ctx, &managedConfigMap) - if err != nil { - return fmt.Errorf("unable to update Kubernetes config map because [%w]", err) - } - - logger.Info("successfully updated managed Kubernetes config map") - return nil -} - -func (r *InfisicalSecretReconciler) fetchSecretsFromAPI(ctx context.Context, logger logr.Logger, authDetails util.AuthenticationDetails, infisicalClient infisicalSdk.InfisicalClientInterface, infisicalSecret v1alpha1.InfisicalSecret) ([]model.SingleEnvironmentVariable, error) { - - if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_ACCOUNT { // Service Account // ! Legacy auth method - serviceAccountCreds, err := r.getInfisicalServiceAccountCredentialsFromKubeSecret(ctx, infisicalSecret) - if err != nil { - return nil, fmt.Errorf("ReconcileInfisicalSecret: unable to get service account creds from kube secret [err=%s]", err) - } - - plainTextSecretsFromApi, err := util.GetPlainTextSecretsViaServiceAccount(infisicalClient, serviceAccountCreds, infisicalSecret.Spec.Authentication.ServiceAccount.ProjectId, infisicalSecret.Spec.Authentication.ServiceAccount.EnvironmentName) - if err != nil { - return nil, fmt.Errorf("\nfailed to get secrets because [err=%v]", err) - } - - logger.Info("ReconcileInfisicalSecret: Fetched secrets via service account") - - return plainTextSecretsFromApi, nil - - } else if authDetails.AuthStrategy == util.AuthStrategy.SERVICE_TOKEN { // Service Tokens // ! Legacy / Deprecated auth method - infisicalToken, err := r.getInfisicalTokenFromKubeSecret(ctx, infisicalSecret) - if err != nil { - return nil, fmt.Errorf("ReconcileInfisicalSecret: unable to get service token from kube secret [err=%s]", err) - } - - envSlug := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.EnvSlug - secretsPath := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.SecretsPath - recursive := infisicalSecret.Spec.Authentication.ServiceToken.SecretsScope.Recursive - - plainTextSecretsFromApi, err := util.GetPlainTextSecretsViaServiceToken(infisicalClient, infisicalToken, envSlug, secretsPath, recursive) - if err != nil { - return nil, fmt.Errorf("\nfailed to get secrets because [err=%v]", err) - } - - logger.Info("ReconcileInfisicalSecret: Fetched secrets via [type=SERVICE_TOKEN]") - - return plainTextSecretsFromApi, nil - - } else if authDetails.IsMachineIdentityAuth { // * Machine Identity authentication, the SDK will be authenticated at this point - plainTextSecretsFromApi, err := util.GetPlainTextSecretsViaMachineIdentity(infisicalClient, authDetails.MachineIdentityScope) - - if err != nil { - return nil, fmt.Errorf("\nfailed to get secrets because [err=%v]", err) - } - - logger.Info(fmt.Sprintf("ReconcileInfisicalSecret: Fetched secrets via machine identity [type=%v]", authDetails.AuthStrategy)) - - return plainTextSecretsFromApi, nil - - } else { - return nil, errors.New("no authentication method provided. Please configure a authentication method then try again") - } -} - -func (r *InfisicalSecretReconciler) getResourceVariables(infisicalSecret v1alpha1.InfisicalSecret, resourceVariablesMap map[string]util.ResourceVariables) util.ResourceVariables { - - var resourceVariables util.ResourceVariables - - if _, ok := resourceVariablesMap[string(infisicalSecret.UID)]; !ok { - - ctx, cancel := context.WithCancel(context.Background()) - - client := infisicalSdk.NewInfisicalClient(ctx, infisicalSdk.Config{ - SiteUrl: api.API_HOST_URL, - CaCertificate: api.API_CA_CERTIFICATE, - UserAgent: api.USER_AGENT_NAME, - }) - - resourceVariablesMap[string(infisicalSecret.UID)] = util.ResourceVariables{ - InfisicalClient: client, - CancelCtx: cancel, - AuthDetails: util.AuthenticationDetails{}, - ServerSentEvents: sse.NewConnectionRegistry(ctx), - } - - resourceVariables = resourceVariablesMap[string(infisicalSecret.UID)] - - } else { - resourceVariables = resourceVariablesMap[string(infisicalSecret.UID)] - } - - return resourceVariables -} - -func (r *InfisicalSecretReconciler) updateResourceVariables(infisicalSecret v1alpha1.InfisicalSecret, resourceVariables util.ResourceVariables, resourceVariablesMap map[string]util.ResourceVariables) { - resourceVariablesMap[string(infisicalSecret.UID)] = resourceVariables -} - -func (r *InfisicalSecretReconciler) ReconcileInfisicalSecret(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, managedKubeSecretReferences []v1alpha1.ManagedKubeSecretConfig, managedKubeConfigMapReferences []v1alpha1.ManagedKubeConfigMapConfig, resourceVariablesMap map[string]util.ResourceVariables) (int, error) { - - if infisicalSecret == nil { - return 0, fmt.Errorf("infisicalSecret is nil") - } - - resourceVariables := r.getResourceVariables(*infisicalSecret, resourceVariablesMap) - infisicalClient := resourceVariables.InfisicalClient - cancelCtx := resourceVariables.CancelCtx - authDetails := resourceVariables.AuthDetails - var err error - - if authDetails.AuthStrategy == "" { - logger.Info("No authentication strategy found. Attempting to authenticate") - authDetails, err = util.HandleAuthentication(ctx, util.SecretAuthInput{ - Secret: *infisicalSecret, - Type: util.SecretCrd.INFISICAL_SECRET, - }, r.Client, infisicalClient, r.IsNamespaceScoped) - - r.SetInfisicalTokenLoadCondition(ctx, logger, infisicalSecret, authDetails.AuthStrategy, err) - - if err != nil { - return 0, fmt.Errorf("unable to authenticate [err=%s]", err) - } - - r.updateResourceVariables(*infisicalSecret, util.ResourceVariables{ - InfisicalClient: infisicalClient, - CancelCtx: cancelCtx, - AuthDetails: authDetails, - ServerSentEvents: sse.NewConnectionRegistry(ctx), - }, resourceVariablesMap) - } - - plainTextSecretsFromApi, err := r.fetchSecretsFromAPI(ctx, logger, authDetails, infisicalClient, *infisicalSecret) - - if err != nil { - return 0, fmt.Errorf("failed to fetch secrets from API for managed secrets [err=%s]", err) - } - secretsCount := len(plainTextSecretsFromApi) - - if len(managedKubeSecretReferences) > 0 { - for _, managedSecretReference := range managedKubeSecretReferences { - // Look for managed secret by name and namespace - managedKubeSecret, err := util.GetKubeSecretByNamespacedName(ctx, r.Client, types.NamespacedName{ - Name: managedSecretReference.SecretName, - Namespace: managedSecretReference.SecretNamespace, - }) - - if err != nil && !k8Errors.IsNotFound(err) { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return 0, fmt.Errorf("unable to fetch Kubernetes secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the secret is in the same namespace as the operator. [err=%v]", err) - } - return 0, fmt.Errorf("something went wrong when fetching the managed Kubernetes secret [%w]", err) - } - - newEtag := crypto.ComputeEtag([]byte(fmt.Sprintf("%v", plainTextSecretsFromApi))) - if managedKubeSecret == nil { - if err := r.createInfisicalManagedKubeResource(ctx, logger, *infisicalSecret, managedSecretReference, plainTextSecretsFromApi, newEtag, constants.MANAGED_KUBE_RESOURCE_TYPE_SECRET); err != nil { - return 0, fmt.Errorf("failed to create managed secret [err=%s]", err) - } - } else { - if err := r.updateInfisicalManagedKubeSecret(ctx, logger, managedSecretReference, *managedKubeSecret, plainTextSecretsFromApi, newEtag); err != nil { - return 0, fmt.Errorf("failed to update managed secret [err=%s]", err) - } - } - } - } - - if len(managedKubeConfigMapReferences) > 0 { - for _, managedConfigMapReference := range managedKubeConfigMapReferences { - managedKubeConfigMap, err := util.GetKubeConfigMapByNamespacedName(ctx, r.Client, types.NamespacedName{ - Name: managedConfigMapReference.ConfigMapName, - Namespace: managedConfigMapReference.ConfigMapNamespace, - }) - - if err != nil && !k8Errors.IsNotFound(err) { - if util.IsNamespaceScopedError(err, r.IsNamespaceScoped) { - return 0, fmt.Errorf("unable to fetch Kubernetes config map. Your Operator installation is namespace scoped, and cannot read config maps outside of the namespace it is installed in. Please ensure the config map is in the same namespace as the operator. [err=%v]", err) - } - return 0, fmt.Errorf("something went wrong when fetching the managed Kubernetes config map [%w]", err) - } - - newEtag := crypto.ComputeEtag([]byte(fmt.Sprintf("%v", plainTextSecretsFromApi))) - if managedKubeConfigMap == nil { - if err := r.createInfisicalManagedKubeResource(ctx, logger, *infisicalSecret, managedConfigMapReference, plainTextSecretsFromApi, newEtag, constants.MANAGED_KUBE_RESOURCE_TYPE_CONFIG_MAP); err != nil { - return 0, fmt.Errorf("failed to create managed config map [err=%s]", err) - } - } else { - if err := r.updateInfisicalManagedConfigMap(ctx, logger, managedConfigMapReference, *managedKubeConfigMap, plainTextSecretsFromApi, newEtag); err != nil { - return 0, fmt.Errorf("failed to update managed config map [err=%s]", err) - } - } - - } - } - - return secretsCount, nil -} - -func (r *InfisicalSecretReconciler) CloseInstantUpdatesStream(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, resourceVariablesMap map[string]util.ResourceVariables) error { - if infisicalSecret == nil { - return fmt.Errorf("infisicalSecret is nil") - } - - variables := r.getResourceVariables(*infisicalSecret, resourceVariablesMap) - - if !variables.AuthDetails.IsMachineIdentityAuth { - return fmt.Errorf("only machine identity is supported for subscriptions") - } - - conn := variables.ServerSentEvents - - if _, ok := conn.Get(); ok { - conn.Close() - } - - return nil -} - -func (r *InfisicalSecretReconciler) OpenInstantUpdatesStream(ctx context.Context, logger logr.Logger, infisicalSecret *v1alpha1.InfisicalSecret, resourceVariablesMap map[string]util.ResourceVariables, eventCh chan<- event.TypedGenericEvent[client.Object]) error { - if infisicalSecret == nil { - return fmt.Errorf("infisicalSecret is nil") - } - - variables := r.getResourceVariables(*infisicalSecret, resourceVariablesMap) - - if !variables.AuthDetails.IsMachineIdentityAuth { - return fmt.Errorf("only machine identity is supported for subscriptions") - } - - projectSlug := variables.AuthDetails.MachineIdentityScope.ProjectSlug - secretsPath := variables.AuthDetails.MachineIdentityScope.SecretsPath - envSlug := variables.AuthDetails.MachineIdentityScope.EnvSlug - - infiscalClient := variables.InfisicalClient - sseRegistry := variables.ServerSentEvents - - token := infiscalClient.Auth().GetAccessToken() - - project, err := util.GetProjectBySlug(token, projectSlug) - - if err != nil { - return fmt.Errorf("failed to get project [err=%s]", err) - } - - if variables.AuthDetails.MachineIdentityScope.Recursive { - secretsPath = fmt.Sprint(secretsPath, "**") - } - - if err != nil { - return fmt.Errorf("CallSubscribeProjectEvents: unable to marshal body [err=%s]", err) - } - - events, errors, err := sseRegistry.Subscribe(func() (*http.Response, error) { - httpClient := resty.New() - - req, err := api.CallSubscribeProjectEvents(httpClient, project.ID, secretsPath, envSlug, token) - - if err != nil { - return nil, err - } - - return req, nil - }) - - if err != nil { - return fmt.Errorf("unable to connect sse [err=%s]", err) - } - - go func() { - outer: - for { - select { - case ev := <-events: - logger.Info("Received SSE Event", "event", ev) - eventCh <- event.TypedGenericEvent[client.Object]{ - Object: infisicalSecret, - } - case err := <-errors: - logger.Error(err, "Error occurred") - break outer - case <-ctx.Done(): - break outer - } - } - }() - - return nil -} diff --git a/k8-operator/internal/services/infisicalsecret/suite_test.go b/k8-operator/internal/services/infisicalsecret/suite_test.go deleted file mode 100644 index 6b93568a10..0000000000 --- a/k8-operator/internal/services/infisicalsecret/suite_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package infisicalsecret - -import ( - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - secretsv1alpha1 "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = secretsv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/k8-operator/internal/template/base64.go b/k8-operator/internal/template/base64.go deleted file mode 100644 index 3fff06c867..0000000000 --- a/k8-operator/internal/template/base64.go +++ /dev/null @@ -1,18 +0,0 @@ -package template - -import ( - "encoding/base64" - "fmt" -) - -func decodeBase64ToBytes(encodedString string) string { - decoded, err := base64.StdEncoding.DecodeString(encodedString) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - return string(decoded) -} - -func encodeBase64(plainString string) string { - return base64.StdEncoding.EncodeToString([]byte(plainString)) -} diff --git a/k8-operator/internal/template/jwk.go b/k8-operator/internal/template/jwk.go deleted file mode 100644 index 8dbc8f3792..0000000000 --- a/k8-operator/internal/template/jwk.go +++ /dev/null @@ -1,43 +0,0 @@ -package template - -import ( - "crypto/x509" - "fmt" - - "github.com/lestrrat-go/jwx/v2/jwk" -) - -func jwkPublicKeyPem(jwkjson string) string { - k, err := jwk.ParseKey([]byte(jwkjson)) - if err != nil { - panic(fmt.Sprintf("[jwkPublicKeyPem] Error: %v", err)) - } - var rawkey any - err = k.Raw(&rawkey) - if err != nil { - panic(fmt.Sprintf("[jwkPublicKeyPem] Error: %v", err)) - } - mpk, err := x509.MarshalPKIXPublicKey(rawkey) - if err != nil { - panic(fmt.Sprintf("[jwkPublicKeyPem] Error: %v", err)) - } - return pemEncode(mpk, "PUBLIC KEY") -} - -func jwkPrivateKeyPem(jwkjson string) string { - k, err := jwk.ParseKey([]byte(jwkjson)) - if err != nil { - panic(fmt.Sprintf("[jwkPrivateKeyPem] Error: %v", err)) - } - var mpk []byte - var pk any - err = k.Raw(&pk) - if err != nil { - panic(fmt.Sprintf("[jwkPrivateKeyPem] Error: %v", err)) - } - mpk, err = x509.MarshalPKCS8PrivateKey(pk) - if err != nil { - panic(fmt.Sprintf("[jwkPrivateKeyPem] Error: %v", err)) - } - return pemEncode(mpk, "PRIVATE KEY") -} diff --git a/k8-operator/internal/template/pem.go b/k8-operator/internal/template/pem.go deleted file mode 100644 index f37a9d576f..0000000000 --- a/k8-operator/internal/template/pem.go +++ /dev/null @@ -1,98 +0,0 @@ -package template - -import ( - "bytes" - "crypto/x509" - "encoding/pem" - "fmt" - "strings" -) - -const ( - errJunk = "error filtering pem: found junk" - - certTypeLeaf = "leaf" - certTypeIntermediate = "intermediate" - certTypeRoot = "root" -) - -func filterPEM(pemType, input string) string { - data := []byte(input) - var blocks []byte - var block *pem.Block - var rest []byte - for { - block, rest = pem.Decode(data) - data = rest - - if block == nil { - break - } - if !strings.EqualFold(block.Type, pemType) { - continue - } - - var buf bytes.Buffer - err := pem.Encode(&buf, block) - if err != nil { - panic(fmt.Sprintf("[filterPEM] Error: %v", err)) - } - blocks = append(blocks, buf.Bytes()...) - } - - if len(blocks) == 0 && len(rest) != 0 { - panic(fmt.Sprintf("[filterPEM] Error: %v", errJunk)) - } - - return string(blocks) -} - -func filterCertChain(certType, input string) string { - ordered := fetchX509CertChains([]byte(input)) - - switch certType { - case certTypeLeaf: - cert := ordered[0] - if cert.AuthorityKeyId != nil && !bytes.Equal(cert.AuthorityKeyId, cert.SubjectKeyId) { - return pemEncode(ordered[0].Raw, pemTypeCertificate) - } - case certTypeIntermediate: - if len(ordered) < 2 { - return "" - } - var pemData []byte - for _, cert := range ordered[1:] { - if isRootCertificate(cert) { - break - } - b := &pem.Block{ - Type: pemTypeCertificate, - Bytes: cert.Raw, - } - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - return string(pemData) - case certTypeRoot: - cert := ordered[len(ordered)-1] - if isRootCertificate(cert) { - return pemEncode(cert.Raw, pemTypeCertificate) - } - } - - return "" -} - -func isRootCertificate(cert *x509.Certificate) bool { - return cert.AuthorityKeyId == nil || bytes.Equal(cert.AuthorityKeyId, cert.SubjectKeyId) -} - -func pemEncode(thing []byte, kind string) string { - buf := bytes.NewBuffer(nil) - err := pem.Encode(buf, &pem.Block{Type: kind, Bytes: thing}) - - if err != nil { - panic(fmt.Sprintf("[pemEncode] Error: %v", err)) - } - - return buf.String() -} diff --git a/k8-operator/internal/template/pem_chain.go b/k8-operator/internal/template/pem_chain.go deleted file mode 100644 index 00c4f5d3f7..0000000000 --- a/k8-operator/internal/template/pem_chain.go +++ /dev/null @@ -1,117 +0,0 @@ -package template - -import ( - "bytes" - "crypto/x509" - "encoding/pem" - "fmt" -) - -const ( - errNilCert = "certificate is nil" - errFoundDisjunctCert = "found multiple leaf or disjunct certificates" - errNoLeafFound = "no leaf certificate found" - errChainCycle = "constructing chain resulted in cycle" -) - -type node struct { - cert *x509.Certificate - parent *node - isParent bool -} - -func fetchX509CertChains(data []byte) []*x509.Certificate { - var newCertChain []*x509.Certificate - nodes := pemToNodes(data) - - // at the end of this computation, the output will be a single linked list - // the tail of the list will be the root node (which has no parents) - // the head of the list will be the leaf node (whose parent will be intermediate certs) - // (head) leaf -> intermediates -> root (tail) - for i := range nodes { - for j := range nodes { - // ignore same node to prevent generating a cycle - if i == j { - continue - } - // if ith node AuthorityKeyId is same as jth node SubjectKeyId, jth node was used - // to sign the ith certificate - if bytes.Equal(nodes[i].cert.AuthorityKeyId, nodes[j].cert.SubjectKeyId) { - nodes[j].isParent = true - nodes[i].parent = nodes[j] - break - } - } - } - - var foundLeaf bool - var leaf *node - for i := range nodes { - if !nodes[i].isParent { - if foundLeaf { - panic(fmt.Sprintf("[fetchX509CertChains] Error: %v", errFoundDisjunctCert)) - } - // this is the leaf node as it's not a parent for any other node - leaf = nodes[i] - foundLeaf = true - } - } - - if leaf == nil { - panic(fmt.Sprintf("[fetchX509CertChains] Error: %v", errNoLeafFound)) - } - - processedNodes := 0 - // iterate through the directed list and append the nodes to new cert chain - for leaf != nil { - processedNodes++ - // ensure we aren't stuck in a cyclic loop - if processedNodes > len(nodes) { - panic(fmt.Sprintf("[fetchX509CertChains] Error: %v", errChainCycle)) - } - newCertChain = append(newCertChain, leaf.cert) - leaf = leaf.parent - } - return newCertChain -} - -func fetchCertChains(data []byte) []byte { - var pemData []byte - newCertChain := fetchX509CertChains(data) - - for _, cert := range newCertChain { - b := &pem.Block{ - Type: pemTypeCertificate, - Bytes: cert.Raw, - } - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - return pemData -} - -func pemToNodes(data []byte) []*node { - nodes := make([]*node, 0) - for { - // decode pem to der first - block, rest := pem.Decode(data) - data = rest - - if block == nil { - break - } - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - panic(fmt.Sprintf("[pemToNodes] Error: %v", err)) - } - - if cert == nil { - panic(fmt.Sprintf("[pemToNodes] Error: %v", errNilCert)) - } - nodes = append(nodes, &node{ - cert: cert, - parent: nil, - isParent: false, - }) - } - return nodes -} diff --git a/k8-operator/internal/template/pkcs12.go b/k8-operator/internal/template/pkcs12.go deleted file mode 100644 index e6763fc46e..0000000000 --- a/k8-operator/internal/template/pkcs12.go +++ /dev/null @@ -1,144 +0,0 @@ -package template - -import ( - "bytes" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "fmt" - - gopkcs12 "software.sslmate.com/src/go-pkcs12" -) - -func pkcs12keyPass(pass, input string) string { - privateKey, _, _, err := gopkcs12.DecodeChain([]byte(input), pass) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - marshalPrivateKey, err := x509.MarshalPKCS8PrivateKey(privateKey) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - var buf bytes.Buffer - if err := pem.Encode(&buf, &pem.Block{ - Type: pemTypeKey, - Bytes: marshalPrivateKey, - }); err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - return buf.String() -} - -func parsePrivateKey(block []byte) any { - if k, err := x509.ParsePKCS1PrivateKey(block); err == nil { - return k - } - if k, err := x509.ParsePKCS8PrivateKey(block); err == nil { - return k - } - if k, err := x509.ParseECPrivateKey(block); err == nil { - return k - } - panic("Error: unable to parse private key") -} - -func pkcs12key(input string) string { - return pkcs12keyPass("", input) -} - -func pkcs12certPass(pass, input string) string { - _, certificate, caCerts, err := gopkcs12.DecodeChain([]byte(input), pass) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - var pemData []byte - var buf bytes.Buffer - if err := pem.Encode(&buf, &pem.Block{ - Type: pemTypeCertificate, - Bytes: certificate.Raw, - }); err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - pemData = append(pemData, buf.Bytes()...) - - for _, ca := range caCerts { - var buf bytes.Buffer - if err := pem.Encode(&buf, &pem.Block{ - Type: pemTypeCertificate, - Bytes: ca.Raw, - }); err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - pemData = append(pemData, buf.Bytes()...) - } - - // try to order certificate chain. If it fails we return - // the unordered raw pem data. - // This fails if multiple leaf or disjunct certs are provided. - ordered := fetchCertChains(pemData) - - return string(ordered) -} - -func pkcs12cert(input string) string { - return pkcs12certPass("", input) -} - -func pemToPkcs12(cert, key string) string { - return pemToPkcs12Pass(cert, key, "") -} - -func pemToPkcs12Pass(cert, key, pass string) string { - certPem, _ := pem.Decode([]byte(cert)) - - parsedCert, err := x509.ParseCertificate(certPem.Bytes) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - return certsToPkcs12(parsedCert, key, nil, pass) -} - -func fullPemToPkcs12(cert, key string) string { - return fullPemToPkcs12Pass(cert, key, "") -} - -func fullPemToPkcs12Pass(cert, key, pass string) string { - certPem, rest := pem.Decode([]byte(cert)) - - parsedCert, err := x509.ParseCertificate(certPem.Bytes) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - caCerts := make([]*x509.Certificate, 0) - for len(rest) > 0 { - caPem, restBytes := pem.Decode(rest) - rest = restBytes - - caCert, err := x509.ParseCertificate(caPem.Bytes) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - caCerts = append(caCerts, caCert) - } - - return certsToPkcs12(parsedCert, key, caCerts, pass) -} - -func certsToPkcs12(cert *x509.Certificate, key string, caCerts []*x509.Certificate, password string) string { - keyPem, _ := pem.Decode([]byte(key)) - parsedKey := parsePrivateKey(keyPem.Bytes) - - pfx, err := gopkcs12.Modern.Encode(parsedKey, cert, caCerts, password) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - - return base64.StdEncoding.EncodeToString(pfx) -} diff --git a/k8-operator/internal/template/template.go b/k8-operator/internal/template/template.go deleted file mode 100644 index d56b3da5d4..0000000000 --- a/k8-operator/internal/template/template.go +++ /dev/null @@ -1,67 +0,0 @@ -package template - -import ( - tpl "text/template" - - "github.com/Masterminds/sprig/v3" -) - -var customInfisicalSecretTemplateFunctions = tpl.FuncMap{ - "pkcs12key": pkcs12key, - "pkcs12keyPass": pkcs12keyPass, - "pkcs12cert": pkcs12cert, - "pkcs12certPass": pkcs12certPass, - - "pemToPkcs12": pemToPkcs12, - "pemToPkcs12Pass": pemToPkcs12Pass, - "fullPemToPkcs12": fullPemToPkcs12, - "fullPemToPkcs12Pass": fullPemToPkcs12Pass, - - "filterPEM": filterPEM, - "filterCertChain": filterCertChain, - - "jwkPublicKeyPem": jwkPublicKeyPem, - "jwkPrivateKeyPem": jwkPrivateKeyPem, - - "toYaml": toYAML, - "fromYaml": fromYAML, - - "decodeBase64ToBytes": decodeBase64ToBytes, - "encodeBase64": encodeBase64, -} - -const ( - errParse = "unable to parse template at key %s: %s" - errExecute = "unable to execute template at key %s: %s" - errDecodePKCS12WithPass = "unable to decode pkcs12 with password: %s" - errDecodeCertWithPass = "unable to decode pkcs12 certificate with password: %s" - errParsePrivKey = "unable to parse private key type" - errUnmarshalJSON = "unable to unmarshal json: %s" - errMarshalJSON = "unable to marshal json: %s" - - pemTypeCertificate = "CERTIFICATE" - pemTypeKey = "PRIVATE KEY" -) - -func InitializeTemplateFunctions() { - templates := customInfisicalSecretTemplateFunctions - - sprigFuncs := sprig.TxtFuncMap() - // removed for security reasons - delete(sprigFuncs, "env") - delete(sprigFuncs, "expandenv") - - for k, v := range sprigFuncs { - // make sure we aren't overwriting any of our own functions - _, exists := templates[k] - if !exists { - templates[k] = v - } - } - - customInfisicalSecretTemplateFunctions = templates -} - -func GetTemplateFunctions() tpl.FuncMap { - return customInfisicalSecretTemplateFunctions -} diff --git a/k8-operator/internal/template/yaml.go b/k8-operator/internal/template/yaml.go deleted file mode 100644 index 5352d5a023..0000000000 --- a/k8-operator/internal/template/yaml.go +++ /dev/null @@ -1,30 +0,0 @@ -package template - -import ( - "fmt" - "strings" - - "gopkg.in/yaml.v3" -) - -func toYAML(v any) string { - data, err := yaml.Marshal(v) - if err != nil { - panic(fmt.Sprintf("Error: %v", err)) - - } - return strings.TrimSuffix(string(data), "\n") -} - -// fromYAML converts a YAML document into a map[string]any. -// -// This is not a general-purpose YAML parser, and will not parse all valid -// YAML documents. -func fromYAML(str string) map[string]any { - mapData := map[string]any{} - - if err := yaml.Unmarshal([]byte(str), &mapData); err != nil { - panic(fmt.Sprintf("Error: %v", err)) - } - return mapData -} diff --git a/k8-operator/internal/util/auth.go b/k8-operator/internal/util/auth.go deleted file mode 100644 index 81e57def3a..0000000000 --- a/k8-operator/internal/util/auth.go +++ /dev/null @@ -1,630 +0,0 @@ -package util - -import ( - "context" - "fmt" - - "errors" - - corev1 "k8s.io/api/core/v1" - - authenticationv1 "k8s.io/api/authentication/v1" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/aws/smithy-go/ptr" - infisicalSdk "github.com/infisical/go-sdk" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func GetServiceAccountToken(k8sClient client.Client, namespace string, serviceAccountName string, autoCreateServiceAccountToken bool, serviceAccountTokenAudiences []string, isNamespaceScoped bool) (string, error) { - - if autoCreateServiceAccountToken { - restClient, err := GetRestClientFromClient() - if err != nil { - return "", fmt.Errorf("failed to get REST client: %w", err) - } - - tokenRequest := &authenticationv1.TokenRequest{ - Spec: authenticationv1.TokenRequestSpec{ - ExpirationSeconds: ptr.Int64(600), // 10 minutes. the token only needs to be valid for when we do the initial k8s login. - }, - } - - if len(serviceAccountTokenAudiences) > 0 { - // Conditionally add the audiences if they are specified. - // Failing to do this causes a default audience to be used, which is not what we want if the user doesn't specify any. - tokenRequest.Spec.Audiences = serviceAccountTokenAudiences - } - - result := &authenticationv1.TokenRequest{} - err = restClient. - Post(). - Namespace(namespace). - Resource("serviceaccounts"). - Name(serviceAccountName). - SubResource("token"). - Body(tokenRequest). - Do(context.Background()). - Into(result) - - if err != nil { - return "", fmt.Errorf("failed to create token: %w", err) - } - - return result.Status.Token, nil - } - - serviceAccount := &corev1.ServiceAccount{} - err := k8sClient.Get(context.TODO(), client.ObjectKey{Name: serviceAccountName, Namespace: namespace}, serviceAccount) - if err != nil { - if IsNamespaceScopedError(err, isNamespaceScoped) { - return "", fmt.Errorf("unable to fetch service account. Your Operator is namespace scoped, and cannot read secrets outside of its namespace. Please ensure the service account is in the same namespace as the operator. [err=%v]", err) - } - return "", err - } - - if len(serviceAccount.Secrets) == 0 { - return "", fmt.Errorf("no secrets found for service account %s", serviceAccountName) - } - - secretName := serviceAccount.Secrets[0].Name - - secret := &corev1.Secret{} - err = k8sClient.Get(context.TODO(), client.ObjectKey{Name: secretName, Namespace: namespace}, secret) - if err != nil { - if IsNamespaceScopedError(err, isNamespaceScoped) { - return "", fmt.Errorf("unable to fetch service account token secret. Your Operator is namespace scoped, and cannot read secrets outside of its namespace. Please ensure the service account token secret is in the same namespace as the operator. [err=%v]", err) - } - return "", err - } - - token := secret.Data["token"] - - return string(token), nil -} - -type AuthStrategyType string - -var AuthStrategy = struct { - SERVICE_TOKEN AuthStrategyType - SERVICE_ACCOUNT AuthStrategyType - UNIVERSAL_MACHINE_IDENTITY AuthStrategyType - KUBERNETES_MACHINE_IDENTITY AuthStrategyType - AWS_IAM_MACHINE_IDENTITY AuthStrategyType - AZURE_MACHINE_IDENTITY AuthStrategyType - GCP_ID_TOKEN_MACHINE_IDENTITY AuthStrategyType - GCP_IAM_MACHINE_IDENTITY AuthStrategyType - LDAP_MACHINE_IDENTITY AuthStrategyType -}{ - SERVICE_TOKEN: "SERVICE_TOKEN", - SERVICE_ACCOUNT: "SERVICE_ACCOUNT", - UNIVERSAL_MACHINE_IDENTITY: "UNIVERSAL_MACHINE_IDENTITY", - KUBERNETES_MACHINE_IDENTITY: "KUBERNETES_AUTH_MACHINE_IDENTITY", - AWS_IAM_MACHINE_IDENTITY: "AWS_IAM_MACHINE_IDENTITY", - AZURE_MACHINE_IDENTITY: "AZURE_MACHINE_IDENTITY", - GCP_ID_TOKEN_MACHINE_IDENTITY: "GCP_ID_TOKEN_MACHINE_IDENTITY", - GCP_IAM_MACHINE_IDENTITY: "GCP_IAM_MACHINE_IDENTITY", - LDAP_MACHINE_IDENTITY: "LDAP_MACHINE_IDENTITY", -} - -type SecretCrdType string - -var SecretCrd = struct { - INFISICAL_SECRET SecretCrdType - INFISICAL_PUSH_SECRET SecretCrdType - INFISICAL_DYNAMIC_SECRET SecretCrdType -}{ - INFISICAL_SECRET: "INFISICAL_SECRET", - INFISICAL_PUSH_SECRET: "INFISICAL_PUSH_SECRET", - INFISICAL_DYNAMIC_SECRET: "INFISICAL_DYNAMIC_SECRET", -} - -type SecretAuthInput struct { - Secret interface{} - Type SecretCrdType -} - -type AuthenticationDetails struct { - AuthStrategy AuthStrategyType - MachineIdentityScope v1alpha1.MachineIdentityScopeInWorkspace // This will only be set if a machine identity auth method is used (e.g. UniversalAuth or KubernetesAuth, etc.) - IsMachineIdentityAuth bool - SecretType SecretCrdType -} - -var ErrAuthNotApplicable = errors.New("authentication not applicable") - -func HandleUniversalAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, isNamespaceScoped bool) (AuthenticationDetails, error) { - - var universalAuthSpec v1alpha1.UniversalAuthDetails - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - universalAuthSpec = infisicalSecret.Spec.Authentication.UniversalAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - universalAuthSpec = v1alpha1.UniversalAuthDetails{ - CredentialsRef: infisicalPushSecret.Spec.Authentication.UniversalAuth.CredentialsRef, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - universalAuthSpec = v1alpha1.UniversalAuthDetails{ - CredentialsRef: infisicalDynamicSecret.Spec.Authentication.UniversalAuth.CredentialsRef, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - } - - if universalAuthSpec.CredentialsRef.SecretName == "" || universalAuthSpec.CredentialsRef.SecretNamespace == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - universalAuthKubeSecret, err := GetInfisicalUniversalAuthFromKubeSecret(ctx, reconcilerClient, v1alpha1.KubeSecretReference{ - SecretNamespace: universalAuthSpec.CredentialsRef.SecretNamespace, - SecretName: universalAuthSpec.CredentialsRef.SecretName, - }, isNamespaceScoped) - - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get machine identity creds from kube secret [err=%s]", err) - } - - if universalAuthKubeSecret.ClientId == "" && universalAuthKubeSecret.ClientSecret == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err = infisicalClient.Auth().UniversalAuthLogin(universalAuthKubeSecret.ClientId, universalAuthKubeSecret.ClientSecret) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with machine identity credentials [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.UNIVERSAL_MACHINE_IDENTITY, - MachineIdentityScope: universalAuthSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil -} - -func HandleLdapAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, isNamespaceScoped bool) (AuthenticationDetails, error) { - - var ldapAuthSpec v1alpha1.LdapAuthDetails - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - ldapAuthSpec = infisicalSecret.Spec.Authentication.LdapAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - ldapAuthSpec = v1alpha1.LdapAuthDetails{ - CredentialsRef: infisicalPushSecret.Spec.Authentication.LdapAuth.CredentialsRef, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - IdentityID: infisicalPushSecret.Spec.Authentication.LdapAuth.IdentityID, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - ldapAuthSpec = v1alpha1.LdapAuthDetails{ - CredentialsRef: infisicalDynamicSecret.Spec.Authentication.LdapAuth.CredentialsRef, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - IdentityID: infisicalDynamicSecret.Spec.Authentication.LdapAuth.IdentityID, - } - } - - if ldapAuthSpec.CredentialsRef.SecretName == "" || ldapAuthSpec.CredentialsRef.SecretNamespace == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - ldapAuthKubeSecret, err := GetInfisicalLdapAuthFromKubeSecret(ctx, reconcilerClient, v1alpha1.KubeSecretReference{ - SecretNamespace: ldapAuthSpec.CredentialsRef.SecretNamespace, - SecretName: ldapAuthSpec.CredentialsRef.SecretName, - }, isNamespaceScoped) - - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get machine identity creds from kube secret [err=%s]", err) - } - - if ldapAuthKubeSecret.Username == "" && ldapAuthKubeSecret.Password == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err = infisicalClient.Auth().LdapAuthLogin(ldapAuthSpec.IdentityID, ldapAuthKubeSecret.Username, ldapAuthKubeSecret.Password) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with machine identity credentials [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.LDAP_MACHINE_IDENTITY, - MachineIdentityScope: ldapAuthSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil -} - -func HandleKubernetesAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, isNamespaceScoped bool) (AuthenticationDetails, error) { - var kubernetesAuthSpec v1alpha1.KubernetesAuthDetails - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - kubernetesAuthSpec = infisicalSecret.Spec.Authentication.KubernetesAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - kubernetesAuthSpec = v1alpha1.KubernetesAuthDetails{ - IdentityID: infisicalPushSecret.Spec.Authentication.KubernetesAuth.IdentityID, - ServiceAccountRef: v1alpha1.KubernetesServiceAccountRef{ - Namespace: infisicalPushSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Namespace, - Name: infisicalPushSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Name, - }, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - AutoCreateServiceAccountToken: infisicalPushSecret.Spec.Authentication.KubernetesAuth.AutoCreateServiceAccountToken, - ServiceAccountTokenAudiences: infisicalPushSecret.Spec.Authentication.KubernetesAuth.ServiceAccountTokenAudiences, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - kubernetesAuthSpec = v1alpha1.KubernetesAuthDetails{ - IdentityID: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.IdentityID, - ServiceAccountRef: v1alpha1.KubernetesServiceAccountRef{ - Namespace: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Namespace, - Name: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.ServiceAccountRef.Name, - }, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - AutoCreateServiceAccountToken: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.AutoCreateServiceAccountToken, - ServiceAccountTokenAudiences: infisicalDynamicSecret.Spec.Authentication.KubernetesAuth.ServiceAccountTokenAudiences, - } - } - - if kubernetesAuthSpec.IdentityID == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - serviceAccountToken, err := GetServiceAccountToken( - reconcilerClient, - kubernetesAuthSpec.ServiceAccountRef.Namespace, - kubernetesAuthSpec.ServiceAccountRef.Name, - kubernetesAuthSpec.AutoCreateServiceAccountToken, - kubernetesAuthSpec.ServiceAccountTokenAudiences, - isNamespaceScoped, - ) - - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to get service account token [err=%s]", err) - } - - _, err = infisicalClient.Auth().KubernetesRawServiceAccountTokenLogin(kubernetesAuthSpec.IdentityID, serviceAccountToken) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with Kubernetes native auth [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.KUBERNETES_MACHINE_IDENTITY, - MachineIdentityScope: kubernetesAuthSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil - -} - -func HandleAwsIamAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, _ bool) (AuthenticationDetails, error) { - awsIamAuthSpec := v1alpha1.AWSIamAuthDetails{} - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - - awsIamAuthSpec = infisicalSecret.Spec.Authentication.AwsIamAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - awsIamAuthSpec = v1alpha1.AWSIamAuthDetails{ - IdentityID: infisicalPushSecret.Spec.Authentication.AwsIamAuth.IdentityID, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - awsIamAuthSpec = v1alpha1.AWSIamAuthDetails{ - IdentityID: infisicalDynamicSecret.Spec.Authentication.AwsIamAuth.IdentityID, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - } - - if awsIamAuthSpec.IdentityID == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err := infisicalClient.Auth().AwsIamAuthLogin(awsIamAuthSpec.IdentityID) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with AWS IAM auth [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.AWS_IAM_MACHINE_IDENTITY, - MachineIdentityScope: awsIamAuthSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil - -} - -func HandleAzureAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, _ bool) (AuthenticationDetails, error) { - azureAuthSpec := v1alpha1.AzureAuthDetails{} - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - - azureAuthSpec = infisicalSecret.Spec.Authentication.AzureAuth - - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - azureAuthSpec = v1alpha1.AzureAuthDetails{ - IdentityID: infisicalPushSecret.Spec.Authentication.AzureAuth.IdentityID, - Resource: infisicalPushSecret.Spec.Authentication.AzureAuth.Resource, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - azureAuthSpec = v1alpha1.AzureAuthDetails{ - IdentityID: infisicalDynamicSecret.Spec.Authentication.AzureAuth.IdentityID, - Resource: infisicalDynamicSecret.Spec.Authentication.AzureAuth.Resource, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - } - - if azureAuthSpec.IdentityID == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err := infisicalClient.Auth().AzureAuthLogin(azureAuthSpec.IdentityID, azureAuthSpec.Resource) // If resource is empty(""), it will default to "https://management.azure.com/" in the SDK. - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with Azure auth [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.AZURE_MACHINE_IDENTITY, - MachineIdentityScope: azureAuthSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil - -} - -func HandleGcpIdTokenAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, _ bool) (AuthenticationDetails, error) { - gcpIdTokenSpec := v1alpha1.GCPIdTokenAuthDetails{} - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - - gcpIdTokenSpec = infisicalSecret.Spec.Authentication.GcpIdTokenAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - gcpIdTokenSpec = v1alpha1.GCPIdTokenAuthDetails{ - IdentityID: infisicalPushSecret.Spec.Authentication.GcpIdTokenAuth.IdentityID, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - gcpIdTokenSpec = v1alpha1.GCPIdTokenAuthDetails{ - IdentityID: infisicalDynamicSecret.Spec.Authentication.GcpIdTokenAuth.IdentityID, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - } - - if gcpIdTokenSpec.IdentityID == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err := infisicalClient.Auth().GcpIdTokenAuthLogin(gcpIdTokenSpec.IdentityID) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with GCP Id Token auth [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY, - MachineIdentityScope: gcpIdTokenSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil - -} - -func HandleGcpIamAuth(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, _ bool) (AuthenticationDetails, error) { - gcpIamSpec := v1alpha1.GcpIamAuthDetails{} - - switch secretCrd.Type { - case SecretCrd.INFISICAL_SECRET: - infisicalSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - - gcpIamSpec = infisicalSecret.Spec.Authentication.GcpIamAuth - case SecretCrd.INFISICAL_PUSH_SECRET: - infisicalPushSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalPushSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalPushSecret") - } - - gcpIamSpec = v1alpha1.GcpIamAuthDetails{ - IdentityID: infisicalPushSecret.Spec.Authentication.GcpIamAuth.IdentityID, - ServiceAccountKeyFilePath: infisicalPushSecret.Spec.Authentication.GcpIamAuth.ServiceAccountKeyFilePath, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - - case SecretCrd.INFISICAL_DYNAMIC_SECRET: - infisicalDynamicSecret, ok := secretCrd.Secret.(v1alpha1.InfisicalDynamicSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalDynamicSecret") - } - - gcpIamSpec = v1alpha1.GcpIamAuthDetails{ - IdentityID: infisicalDynamicSecret.Spec.Authentication.GcpIamAuth.IdentityID, - ServiceAccountKeyFilePath: infisicalDynamicSecret.Spec.Authentication.GcpIamAuth.ServiceAccountKeyFilePath, - SecretsScope: v1alpha1.MachineIdentityScopeInWorkspace{}, - } - } - - if gcpIamSpec.IdentityID == "" && gcpIamSpec.ServiceAccountKeyFilePath == "" { - return AuthenticationDetails{}, ErrAuthNotApplicable - } - - _, err := infisicalClient.Auth().GcpIamAuthLogin(gcpIamSpec.IdentityID, gcpIamSpec.ServiceAccountKeyFilePath) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("unable to login with GCP IAM auth [err=%s]", err) - } - - return AuthenticationDetails{ - AuthStrategy: AuthStrategy.GCP_IAM_MACHINE_IDENTITY, - MachineIdentityScope: gcpIamSpec.SecretsScope, - IsMachineIdentityAuth: true, - SecretType: secretCrd.Type, - }, nil -} - -func HandleAuthentication(ctx context.Context, secretInput SecretAuthInput, reconcilerClient client.Client, infisicalClient infisicalSdk.InfisicalClientInterface, isNamespaceScoped bool) (AuthenticationDetails, error) { - - // We only support legacy auth for InfisicalSecret CRD - if secretInput.Type == SecretCrd.INFISICAL_SECRET { - infisicalSecret, ok := secretInput.Secret.(v1alpha1.InfisicalSecret) - - if !ok { - return AuthenticationDetails{}, errors.New("unable to cast secret to InfisicalSecret") - } - - // ? Legacy support, service token auth - infisicalToken, err := GetInfisicalTokenFromKubeSecret(ctx, reconcilerClient, infisicalSecret) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get service token from kube secret [err=%s]", err) - } - if infisicalToken != "" { - infisicalClient.Auth().SetAccessToken(infisicalToken) - return AuthenticationDetails{AuthStrategy: AuthStrategy.SERVICE_TOKEN}, nil - } - - // ? Legacy support, service account auth - serviceAccountCreds, err := GetInfisicalServiceAccountCredentialsFromKubeSecret(ctx, reconcilerClient, infisicalSecret) - if err != nil { - return AuthenticationDetails{}, fmt.Errorf("ReconcileInfisicalSecret: unable to get service account creds from kube secret [err=%s]", err) - } - - if serviceAccountCreds.AccessKey != "" || serviceAccountCreds.PrivateKey != "" || serviceAccountCreds.PublicKey != "" { - infisicalClient.Auth().SetAccessToken(serviceAccountCreds.AccessKey) - return AuthenticationDetails{AuthStrategy: AuthStrategy.SERVICE_ACCOUNT}, nil - } - } - - authStrategies := map[AuthStrategyType]func(ctx context.Context, reconcilerClient client.Client, secretCrd SecretAuthInput, infisicalClient infisicalSdk.InfisicalClientInterface, isNamespaceScoped bool) (AuthenticationDetails, error){ - AuthStrategy.UNIVERSAL_MACHINE_IDENTITY: HandleUniversalAuth, - AuthStrategy.KUBERNETES_MACHINE_IDENTITY: HandleKubernetesAuth, - AuthStrategy.AWS_IAM_MACHINE_IDENTITY: HandleAwsIamAuth, - AuthStrategy.AZURE_MACHINE_IDENTITY: HandleAzureAuth, - AuthStrategy.GCP_ID_TOKEN_MACHINE_IDENTITY: HandleGcpIdTokenAuth, - AuthStrategy.GCP_IAM_MACHINE_IDENTITY: HandleGcpIamAuth, - AuthStrategy.LDAP_MACHINE_IDENTITY: HandleLdapAuth, - } - - for authStrategy, authHandler := range authStrategies { - authDetails, err := authHandler(ctx, reconcilerClient, secretInput, infisicalClient, isNamespaceScoped) - - if err == nil { - return authDetails, nil - } - - if !errors.Is(err, ErrAuthNotApplicable) { - return AuthenticationDetails{}, fmt.Errorf("authentication failed for strategy [%s] [err=%w]", authStrategy, err) - } - } - - return AuthenticationDetails{}, fmt.Errorf("no authentication method provided") - -} diff --git a/k8-operator/internal/util/handler.go b/k8-operator/internal/util/handler.go deleted file mode 100644 index d1cc86562a..0000000000 --- a/k8-operator/internal/util/handler.go +++ /dev/null @@ -1,59 +0,0 @@ -package util - -import ( - "context" - "math/rand" - "time" - - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -// computeMaxJitterDuration returns a random duration between 0 and max. -// This is useful for introducing jitter to event processing. -func computeMaxJitterDuration(max time.Duration) (time.Duration, time.Duration) { - if max <= 0 { - return 0, 0 - } - jitter := time.Duration(rand.Int63n(int64(max))) - return max, jitter -} - -// EnqueueDelayedEventHandler enqueues reconcile requests with a random delay (jitter) -// to spread the load and avoid thundering herd issues. -type EnqueueDelayedEventHandler struct { - Delay time.Duration -} - -func (e *EnqueueDelayedEventHandler) Create(_ context.Context, _ event.TypedCreateEvent[client.Object], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) { -} - -func (e *EnqueueDelayedEventHandler) Update(_ context.Context, _ event.TypedUpdateEvent[client.Object], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) { -} - -func (e *EnqueueDelayedEventHandler) Delete(_ context.Context, _ event.TypedDeleteEvent[client.Object], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) { -} - -func (e *EnqueueDelayedEventHandler) Generic(_ context.Context, evt event.TypedGenericEvent[client.Object], q workqueue.TypedRateLimitingInterface[reconcile.Request]) { - if evt.Object == nil { - return - } - - req := reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: evt.Object.GetNamespace(), - Name: evt.Object.GetName(), - }, - } - - _, delay := computeMaxJitterDuration(e.Delay) - - if delay > 0 { - q.AddAfter(req, delay) - } else { - q.Add(req) - } -} diff --git a/k8-operator/internal/util/helpers.go b/k8-operator/internal/util/helpers.go deleted file mode 100644 index c292caf3fd..0000000000 --- a/k8-operator/internal/util/helpers.go +++ /dev/null @@ -1,60 +0,0 @@ -package util - -import ( - "fmt" - "strconv" - "strings" - "time" -) - -func ConvertIntervalToDuration(resyncInterval *string) (time.Duration, error) { - - if resyncInterval == nil || *resyncInterval == "" { - return 0, nil - } - - length := len(*resyncInterval) - if length < 2 { - return 0, fmt.Errorf("invalid format") - } - - unit := (*resyncInterval)[length-1:] - numberPart := (*resyncInterval)[:length-1] - - number, err := strconv.Atoi(numberPart) - if err != nil { - return 0, err - } - - switch unit { - case "s": - if number < 5 { - return 0, fmt.Errorf("resync interval must be at least 5 seconds") - } - return time.Duration(number) * time.Second, nil - case "m": - return time.Duration(number) * time.Minute, nil - case "h": - return time.Duration(number) * time.Hour, nil - case "d": - return time.Duration(number) * 24 * time.Hour, nil - case "w": - return time.Duration(number) * 7 * 24 * time.Hour, nil - default: - return 0, fmt.Errorf("invalid time unit") - } -} - -func AppendAPIEndpoint(address string) string { - if strings.HasSuffix(address, "/api") { - return address - } - if address[len(address)-1] == '/' { - return address + "api" - } - return address + "/api" -} - -func IsNamespaceScopedError(err error, isNamespaceScoped bool) bool { - return isNamespaceScoped && err != nil && strings.Contains(err.Error(), "unknown namespace for the cache") -} diff --git a/k8-operator/internal/util/kubernetes.go b/k8-operator/internal/util/kubernetes.go deleted file mode 100644 index 2f0dd0d9e4..0000000000 --- a/k8-operator/internal/util/kubernetes.go +++ /dev/null @@ -1,183 +0,0 @@ -package util - -import ( - "context" - "fmt" - "strings" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/constants" - "github.com/Infisical/infisical/k8-operator/internal/model" - corev1 "k8s.io/api/core/v1" - k8Errors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const INFISICAL_MACHINE_IDENTITY_CLIENT_ID = "clientId" -const INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET = "clientSecret" - -const INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME = "username" -const INFISICAL_MACHINE_IDENTITY_LDAP_PASSWORD = "password" - -func GetKubeSecretByNamespacedName(ctx context.Context, reconcilerClient client.Client, namespacedName types.NamespacedName) (*corev1.Secret, error) { - kubeSecret := &corev1.Secret{} - err := reconcilerClient.Get(ctx, namespacedName, kubeSecret) - if err != nil { - kubeSecret = nil - } - - return kubeSecret, err -} - -func GetKubeConfigMapByNamespacedName(ctx context.Context, reconcilerClient client.Client, namespacedName types.NamespacedName) (*corev1.ConfigMap, error) { - kubeConfigMap := &corev1.ConfigMap{} - err := reconcilerClient.Get(ctx, namespacedName, kubeConfigMap) - if err != nil { - kubeConfigMap = nil - } - - return kubeConfigMap, err -} - -func GetInfisicalUniversalAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, universalAuthRef v1alpha1.KubeSecretReference, isNamespaceScoped bool) (machineIdentityDetails model.UniversalAuthIdentityDetails, err error) { - - universalAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{ - Namespace: universalAuthRef.SecretNamespace, - Name: universalAuthRef.SecretName, - }) - - if k8Errors.IsNotFound(err) { - return model.UniversalAuthIdentityDetails{}, nil - } - - if err != nil { - if IsNamespaceScopedError(err, isNamespaceScoped) { - return model.UniversalAuthIdentityDetails{}, fmt.Errorf("unable to fetch Kubernetes secret. Your Operator installation is namespace scoped, and cannot read secrets outside of the namespace it is installed in. Please ensure the secret is in the same namespace as the operator. [err=%v]", err) - } - return model.UniversalAuthIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err) - } - - clientIdFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_ID] - clientSecretFromSecret := universalAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_CLIENT_SECRET] - - return model.UniversalAuthIdentityDetails{ClientId: string(clientIdFromSecret), ClientSecret: string(clientSecretFromSecret)}, nil - -} - -func GetInfisicalLdapAuthFromKubeSecret(ctx context.Context, reconcilerClient client.Client, ldapAuthRef v1alpha1.KubeSecretReference, isNamespaceScoped bool) (machineIdentityDetails model.LdapIdentityDetails, err error) { - - ldapAuthCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{ - Namespace: ldapAuthRef.SecretNamespace, - Name: ldapAuthRef.SecretName, - }) - - if k8Errors.IsNotFound(err) { - return model.LdapIdentityDetails{}, nil - } - - if err != nil { - if IsNamespaceScopedError(err, isNamespaceScoped) { - return model.LdapIdentityDetails{}, fmt.Errorf("unable to fetch Kubernetes secret. Your Operator is namespace scoped, and cannot read secrets outside of its namespace. Please ensure the secret is in the same namespace as the operator. [err=%v]", err) - } - return model.LdapIdentityDetails{}, fmt.Errorf("something went wrong when fetching your machine identity credentials [err=%s]", err) - } - - usernameFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_USERNAME] - passwordFromSecret := ldapAuthCredsFromKubeSecret.Data[INFISICAL_MACHINE_IDENTITY_LDAP_PASSWORD] - - return model.LdapIdentityDetails{Username: string(usernameFromSecret), Password: string(passwordFromSecret)}, nil - -} - -func getKubeClusterConfig() (*rest.Config, error) { - config, err := rest.InClusterConfig() - if err != nil { - - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - configOverrides := &clientcmd.ConfigOverrides{} - kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides) - return kubeConfig.ClientConfig() - } - - return config, nil -} - -func GetRestClientFromClient() (rest.Interface, error) { - - config, err := getKubeClusterConfig() - if err != nil { - return nil, err - } - - clientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, err - } - - return clientset.CoreV1().RESTClient(), nil - -} - -func GetInfisicalTokenFromKubeSecret(ctx context.Context, reconcilerClient client.Client, infisicalSecret v1alpha1.InfisicalSecret) (string, error) { - // default to new secret ref structure - secretName := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretName - secretNamespace := infisicalSecret.Spec.Authentication.ServiceToken.ServiceTokenSecretReference.SecretNamespace - // fall back to previous secret ref - if secretName == "" { - secretName = infisicalSecret.Spec.TokenSecretReference.SecretName - } - - if secretNamespace == "" { - secretNamespace = infisicalSecret.Spec.TokenSecretReference.SecretNamespace - } - - tokenSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{ - Namespace: secretNamespace, - Name: secretName, - }) - - if k8Errors.IsNotFound(err) || (secretNamespace == "" && secretName == "") { - return "", nil - } - - if err != nil { - return "", fmt.Errorf("failed to read Infisical token secret from secret named [%s] in namespace [%s]: with error [%w]", infisicalSecret.Spec.TokenSecretReference.SecretName, infisicalSecret.Spec.TokenSecretReference.SecretNamespace, err) - } - - infisicalServiceToken := tokenSecret.Data[constants.INFISICAL_TOKEN_SECRET_KEY_NAME] - - return strings.Replace(string(infisicalServiceToken), " ", "", -1), nil -} - -func GetInfisicalServiceAccountCredentialsFromKubeSecret(ctx context.Context, reconcilerClient client.Client, infisicalSecret v1alpha1.InfisicalSecret) (serviceAccountDetails model.ServiceAccountDetails, err error) { - - secretNamespace := infisicalSecret.Spec.Authentication.ServiceAccount.ServiceAccountSecretReference.SecretNamespace - secretName := infisicalSecret.Spec.Authentication.ServiceAccount.ServiceAccountSecretReference.SecretName - - serviceAccountCredsFromKubeSecret, err := GetKubeSecretByNamespacedName(ctx, reconcilerClient, types.NamespacedName{ - Namespace: secretNamespace, - Name: secretName, - }) - - if k8Errors.IsNotFound(err) || (secretNamespace == "" && secretName == "") { - return model.ServiceAccountDetails{}, nil - } - - if err != nil { - return model.ServiceAccountDetails{}, fmt.Errorf("something went wrong when fetching your service account credentials [err=%s]", err) - } - - accessKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_ACCESS_KEY] - publicKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_PUBLIC_KEY] - privateKeyFromSecret := serviceAccountCredsFromKubeSecret.Data[constants.SERVICE_ACCOUNT_PRIVATE_KEY] - - if accessKeyFromSecret == nil || publicKeyFromSecret == nil || privateKeyFromSecret == nil { - return model.ServiceAccountDetails{}, nil - } - - return model.ServiceAccountDetails{AccessKey: string(accessKeyFromSecret), PrivateKey: string(privateKeyFromSecret), PublicKey: string(publicKeyFromSecret)}, nil -} diff --git a/k8-operator/internal/util/models.go b/k8-operator/internal/util/models.go deleted file mode 100644 index e583858fa5..0000000000 --- a/k8-operator/internal/util/models.go +++ /dev/null @@ -1,15 +0,0 @@ -package util - -import ( - "context" - - "github.com/Infisical/infisical/k8-operator/internal/util/sse" - infisicalSdk "github.com/infisical/go-sdk" -) - -type ResourceVariables struct { - InfisicalClient infisicalSdk.InfisicalClientInterface - CancelCtx context.CancelFunc - AuthDetails AuthenticationDetails - ServerSentEvents *sse.ConnectionRegistry -} diff --git a/k8-operator/internal/util/secrets.go b/k8-operator/internal/util/secrets.go deleted file mode 100644 index 88aa342e9e..0000000000 --- a/k8-operator/internal/util/secrets.go +++ /dev/null @@ -1,186 +0,0 @@ -package util - -import ( - "fmt" - "strings" - - "github.com/Infisical/infisical/k8-operator/api/v1alpha1" - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/model" - "github.com/go-resty/resty/v2" - infisical "github.com/infisical/go-sdk" -) - -type DecodedSymmetricEncryptionDetails = struct { - Cipher []byte - IV []byte - Tag []byte - Key []byte -} - -func VerifyServiceToken(serviceToken string) (string, error) { - serviceTokenParts := strings.SplitN(serviceToken, ".", 4) - if len(serviceTokenParts) < 4 { - return "", fmt.Errorf("invalid service token entered. Please double check your service token and try again") - } - - serviceToken = fmt.Sprintf("%v.%v.%v", serviceTokenParts[0], serviceTokenParts[1], serviceTokenParts[2]) - return serviceToken, nil -} - -func GetServiceTokenDetails(infisicalToken string) (api.GetServiceTokenDetailsResponse, error) { - serviceTokenParts := strings.SplitN(infisicalToken, ".", 4) - if len(serviceTokenParts) < 4 { - return api.GetServiceTokenDetailsResponse{}, fmt.Errorf("invalid service token entered. Please double check your service token and try again") - } - - serviceToken := fmt.Sprintf("%v.%v.%v", serviceTokenParts[0], serviceTokenParts[1], serviceTokenParts[2]) - - httpClient := resty.New() - httpClient.SetAuthToken(serviceToken). - SetHeader("Accept", "application/json") - - serviceTokenDetails, err := api.CallGetServiceTokenDetailsV2(httpClient) - if err != nil { - return api.GetServiceTokenDetailsResponse{}, fmt.Errorf("unable to get service token details. [err=%v]", err) - } - - return serviceTokenDetails, nil -} - -func GetPlainTextSecretsViaMachineIdentity(infisicalClient infisical.InfisicalClientInterface, secretScope v1alpha1.MachineIdentityScopeInWorkspace) ([]model.SingleEnvironmentVariable, error) { - - secrets, err := infisicalClient.Secrets().List(infisical.ListSecretsOptions{ - ProjectSlug: secretScope.ProjectSlug, - Environment: secretScope.EnvSlug, - Recursive: secretScope.Recursive, - SecretPath: secretScope.SecretsPath, - IncludeImports: true, - ExpandSecretReferences: true, - }) - - if err != nil { - return nil, fmt.Errorf("unable to get secrets. [err=%v]", err) - } - - var environmentVariables []model.SingleEnvironmentVariable - - for _, secret := range secrets { - - environmentVariables = append(environmentVariables, model.SingleEnvironmentVariable{ - Key: secret.SecretKey, - Value: secret.SecretValue, - Type: secret.Type, - ID: secret.ID, - SecretPath: secret.SecretPath, - }) - } - - return environmentVariables, nil -} - -func GetPlainTextSecretsViaServiceToken(infisicalClient infisical.InfisicalClientInterface, fullServiceToken string, envSlug string, secretPath string, recursive bool) ([]model.SingleEnvironmentVariable, error) { - serviceTokenParts := strings.SplitN(fullServiceToken, ".", 4) - if len(serviceTokenParts) < 4 { - return nil, fmt.Errorf("invalid service token entered. Please double check your service token and try again") - } - - serviceToken := fmt.Sprintf("%v.%v.%v", serviceTokenParts[0], serviceTokenParts[1], serviceTokenParts[2]) - - httpClient := resty.New() - - httpClient.SetAuthToken(serviceToken). - SetHeader("Accept", "application/json") - - serviceTokenDetails, err := api.CallGetServiceTokenDetailsV2(httpClient) - if err != nil { - return nil, fmt.Errorf("unable to get service token details. [err=%v]", err) - } - - secrets, err := infisicalClient.Secrets().List(infisical.ListSecretsOptions{ - ProjectID: serviceTokenDetails.Workspace, - Environment: envSlug, - Recursive: recursive, - SecretPath: secretPath, - IncludeImports: true, - ExpandSecretReferences: true, - }) - - if err != nil { - return nil, err - } - - var environmentVariables []model.SingleEnvironmentVariable - - for _, secret := range secrets { - - environmentVariables = append(environmentVariables, model.SingleEnvironmentVariable{ - Key: secret.SecretKey, - Value: secret.SecretValue, - Type: secret.Type, - ID: secret.ID, - SecretPath: secret.SecretPath, - }) - } - - return environmentVariables, nil - -} - -// Fetches plaintext secrets from an API endpoint using a service account. -// The function fetches the service account details and keys, decrypts the workspace key, fetches the encrypted secrets for the specified project and environment, and decrypts the secrets using the decrypted workspace key. -// Returns the plaintext secrets, encrypted secrets response, and any errors that occurred during the process. -func GetPlainTextSecretsViaServiceAccount(infisicalClient infisical.InfisicalClientInterface, serviceAccountCreds model.ServiceAccountDetails, projectId string, environmentName string) ([]model.SingleEnvironmentVariable, error) { - httpClient := resty.New() - httpClient.SetAuthToken(serviceAccountCreds.AccessKey). - SetHeader("Accept", "application/json") - - serviceAccountDetails, err := api.CallGetServiceTokenAccountDetailsV2(httpClient) - if err != nil { - return nil, fmt.Errorf("GetPlainTextSecretsViaServiceAccount: unable to get service account details. [err=%v]", err) - } - - serviceAccountKeys, err := api.CallGetServiceAccountKeysV2(httpClient, api.GetServiceAccountKeysRequest{ServiceAccountId: serviceAccountDetails.ServiceAccount.ID}) - if err != nil { - return nil, fmt.Errorf("GetPlainTextSecretsViaServiceAccount: unable to get service account key details. [err=%v]", err) - } - - // find key for requested project - var workspaceServiceAccountKey api.ServiceAccountKey - for _, serviceAccountKey := range serviceAccountKeys.ServiceAccountKeys { - if serviceAccountKey.Workspace == projectId { - workspaceServiceAccountKey = serviceAccountKey - } - } - - if workspaceServiceAccountKey.ID == "" || workspaceServiceAccountKey.EncryptedKey == "" || workspaceServiceAccountKey.Nonce == "" || serviceAccountCreds.PublicKey == "" || serviceAccountCreds.PrivateKey == "" { - return nil, fmt.Errorf("unable to find key for [projectId=%s] [err=%v]. Ensure that the given service account has access to given projectId", projectId, err) - } - - secrets, err := infisicalClient.Secrets().List(infisical.ListSecretsOptions{ - ProjectID: projectId, - Environment: environmentName, - Recursive: false, - SecretPath: "/", - IncludeImports: true, - ExpandSecretReferences: true, - }) - - if err != nil { - return nil, err - } - - var environmentVariables []model.SingleEnvironmentVariable - - for _, secret := range secrets { - environmentVariables = append(environmentVariables, model.SingleEnvironmentVariable{ - Key: secret.SecretKey, - Value: secret.SecretValue, - Type: secret.Type, - ID: secret.ID, - SecretPath: secret.SecretPath, - }) - } - - return environmentVariables, nil -} diff --git a/k8-operator/internal/util/sse/sse.go b/k8-operator/internal/util/sse/sse.go deleted file mode 100644 index 7bfbcef885..0000000000 --- a/k8-operator/internal/util/sse/sse.go +++ /dev/null @@ -1,331 +0,0 @@ -package sse - -import ( - "bufio" - "context" - "io" - "net/http" - "strings" - "sync" - "sync/atomic" - "time" -) - -// Event represents a Server-Sent Event -type Event struct { - ID string - Event string - Data string - Retry int -} - -// ConnectionMeta holds metadata about an SSE connection -type ConnectionMeta struct { - EventChan <-chan Event - ErrorChan <-chan error - lastPingAt atomic.Value // stores time.Time - cancel context.CancelFunc -} - -// LastPing returns the last ping time -func (c *ConnectionMeta) LastPing() time.Time { - if t, ok := c.lastPingAt.Load().(time.Time); ok { - return t - } - return time.Time{} -} - -// UpdateLastPing atomically updates the last ping time -func (c *ConnectionMeta) UpdateLastPing() { - c.lastPingAt.Store(time.Now()) -} - -// Cancel terminates the connection -func (c *ConnectionMeta) Cancel() { - if c.cancel != nil { - c.cancel() - } -} - -// ConnectionRegistry manages SSE connections with high performance -type ConnectionRegistry struct { - mu sync.RWMutex - conn *ConnectionMeta - - monitorOnce sync.Once - monitorStop chan struct{} - - onPing func() // Callback for ping events -} - -// NewConnectionRegistry creates a new high-performance connection registry -func NewConnectionRegistry(ctx context.Context) *ConnectionRegistry { - r := &ConnectionRegistry{ - monitorStop: make(chan struct{}), - } - - // Configure ping handler - r.onPing = func() { - r.UpdateLastPing() - } - - return r -} - -// Subscribe provides SSE events, creating a connection if needed -func (r *ConnectionRegistry) Subscribe(request func() (*http.Response, error)) (<-chan Event, <-chan error, error) { - // Fast path: check if connection exists - if conn := r.getConnection(); conn != nil { - return conn.EventChan, conn.ErrorChan, nil - } - - // Slow path: create new connection under lock - r.mu.Lock() - defer r.mu.Unlock() - - // Double-check after acquiring lock - if r.conn != nil { - return r.conn.EventChan, r.conn.ErrorChan, nil - } - - res, err := request() - if err != nil { - return nil, nil, err - } - - conn, err := r.createStream(res) - if err != nil { - return nil, nil, err - } - - r.conn = conn - - // Start monitor once - r.monitorOnce.Do(func() { - go r.monitorConnections() - }) - - return conn.EventChan, conn.ErrorChan, nil -} - -// Get retrieves the current connection -func (r *ConnectionRegistry) Get() (*ConnectionMeta, bool) { - conn := r.getConnection() - return conn, conn != nil -} - -// IsConnected checks if there's an active connection -func (r *ConnectionRegistry) IsConnected() bool { - return r.getConnection() != nil -} - -// UpdateLastPing updates the last ping time for the current connection -func (r *ConnectionRegistry) UpdateLastPing() { - if conn := r.getConnection(); conn != nil { - conn.UpdateLastPing() - } -} - -// Close gracefully shuts down the registry -func (r *ConnectionRegistry) Close() { - // Stop monitor first - select { - case <-r.monitorStop: - // Already closed - default: - close(r.monitorStop) - } - - // Close connection - r.mu.Lock() - if r.conn != nil { - r.conn.Cancel() - r.conn = nil - } - r.mu.Unlock() -} - -// getConnection returns the current connection without locking -func (r *ConnectionRegistry) getConnection() *ConnectionMeta { - r.mu.RLock() - conn := r.conn - r.mu.RUnlock() - return conn -} - -func (r *ConnectionRegistry) createStream(res *http.Response) (*ConnectionMeta, error) { - ctx, cancel := context.WithCancel(context.Background()) - - eventChan, errorChan, err := r.stream(ctx, res) - if err != nil { - cancel() - return nil, err - } - - meta := &ConnectionMeta{ - EventChan: eventChan, - ErrorChan: errorChan, - cancel: cancel, - } - meta.UpdateLastPing() - - return meta, nil -} - -// stream processes SSE data from an HTTP response -func (r *ConnectionRegistry) stream(ctx context.Context, res *http.Response) (<-chan Event, <-chan error, error) { - eventChan := make(chan Event, 10) - errorChan := make(chan error, 1) - - go r.processStream(ctx, res.Body, eventChan, errorChan) - - return eventChan, errorChan, nil -} - -// processStream reads and parses SSE events from the response body -func (r *ConnectionRegistry) processStream(ctx context.Context, body io.ReadCloser, eventChan chan<- Event, errorChan chan<- error) { - defer body.Close() - defer close(eventChan) - defer close(errorChan) - - scanner := bufio.NewScanner(body) - - var currentEvent Event - var dataBuilder strings.Builder - - for scanner.Scan() { - select { - case <-ctx.Done(): - return - default: - } - - line := scanner.Text() - - // Empty line indicates end of event - if len(line) == 0 { - if currentEvent.Data != "" || currentEvent.Event != "" { - // Finalize data - if dataBuilder.Len() > 0 { - currentEvent.Data = dataBuilder.String() - dataBuilder.Reset() - } - - // Handle ping events - if r.isPingEvent(currentEvent) { - if r.onPing != nil { - r.onPing() - } - } else { - // Send non-ping events - select { - case eventChan <- currentEvent: - case <-ctx.Done(): - return - } - } - - // Reset for next event - currentEvent = Event{} - } - continue - } - - // Parse line efficiently - r.parseLine(line, ¤tEvent, &dataBuilder) - } - - if err := scanner.Err(); err != nil { - select { - case errorChan <- err: - case <-ctx.Done(): - } - } -} - -// parseLine efficiently parses SSE protocol lines -func (r *ConnectionRegistry) parseLine(line string, event *Event, dataBuilder *strings.Builder) { - colonIndex := strings.IndexByte(line, ':') - if colonIndex == -1 { - return // Invalid line format - } - - field := line[:colonIndex] - value := line[colonIndex+1:] - - // Trim leading space from value (SSE spec) - if len(value) > 0 && value[0] == ' ' { - value = value[1:] - } - - switch field { - case "data": - if dataBuilder.Len() > 0 { - dataBuilder.WriteByte('\n') - } - dataBuilder.WriteString(value) - case "event": - event.Event = value - case "id": - event.ID = value - case "retry": - // Parse retry value if needed - // This could be used to configure reconnection delay - case "": - // Comment line, ignore - } -} - -// isPingEvent checks if an event is a ping/keepalive -func (r *ConnectionRegistry) isPingEvent(event Event) bool { - // Check for common ping patterns - if event.Event == "ping" { - return true - } - - // Check for heartbeat data (common pattern is "1" or similar) - if event.Event == "" && strings.TrimSpace(event.Data) == "1" { - return true - } - - return false -} - -// monitorConnections checks connection health periodically -func (r *ConnectionRegistry) monitorConnections() { - const ( - checkInterval = 30 * time.Second - pingTimeout = 2 * time.Minute - ) - - ticker := time.NewTicker(checkInterval) - defer ticker.Stop() - - for { - select { - case <-r.monitorStop: - return - case <-ticker.C: - r.checkConnectionHealth(pingTimeout) - } - } -} - -// checkConnectionHealth verifies connection is still alive -func (r *ConnectionRegistry) checkConnectionHealth(timeout time.Duration) { - conn := r.getConnection() - if conn == nil { - return - } - - if time.Since(conn.LastPing()) > timeout { - // Connection is stale, close it - r.mu.Lock() - if r.conn == conn { // Verify it's still the same connection - r.conn.Cancel() - r.monitorStop <- struct{}{} - r.conn = nil - } - r.mu.Unlock() - } -} diff --git a/k8-operator/internal/util/time.go b/k8-operator/internal/util/time.go deleted file mode 100644 index 0b78a16a68..0000000000 --- a/k8-operator/internal/util/time.go +++ /dev/null @@ -1,40 +0,0 @@ -package util - -import ( - "fmt" - "strconv" - "time" -) - -func ConvertResyncIntervalToDuration(resyncInterval string) (time.Duration, error) { - length := len(resyncInterval) - if length < 2 { - return 0, fmt.Errorf("invalid format") - } - - unit := resyncInterval[length-1:] - numberPart := resyncInterval[:length-1] - - number, err := strconv.Atoi(numberPart) - if err != nil { - return 0, err - } - - switch unit { - case "s": - if number < 5 { - return 0, fmt.Errorf("resync interval must be at least 5 seconds") - } - return time.Duration(number) * time.Second, nil - case "m": - return time.Duration(number) * time.Minute, nil - case "h": - return time.Duration(number) * time.Hour, nil - case "d": - return time.Duration(number) * 24 * time.Hour, nil - case "w": - return time.Duration(number) * 7 * 24 * time.Hour, nil - default: - return 0, fmt.Errorf("invalid time unit") - } -} diff --git a/k8-operator/internal/util/workspace.go b/k8-operator/internal/util/workspace.go deleted file mode 100644 index d014a4c4ef..0000000000 --- a/k8-operator/internal/util/workspace.go +++ /dev/null @@ -1,44 +0,0 @@ -package util - -import ( - "fmt" - - "github.com/Infisical/infisical/k8-operator/internal/api" - "github.com/Infisical/infisical/k8-operator/internal/model" - "github.com/go-resty/resty/v2" -) - -func GetProjectByID(accessToken string, projectId string) (model.Project, error) { - httpClient := resty.New() - httpClient. - SetAuthScheme("Bearer"). - SetAuthToken(accessToken). - SetHeader("Accept", "application/json") - - projectDetails, err := api.CallGetProjectByID(httpClient, api.GetProjectByIDRequest{ - ProjectID: projectId, - }) - if err != nil { - return model.Project{}, fmt.Errorf("unable to get project by slug. [err=%v]", err) - } - - return projectDetails.Project, nil -} - -func GetProjectBySlug(accessToken string, projectSlug string) (model.Project, error) { - httpClient := resty.New() - httpClient. - SetAuthScheme("Bearer"). - SetAuthToken(accessToken). - SetHeader("Accept", "application/json") - - project, err := api.CallGetProjectByIDv2(httpClient, api.GetProjectByIDRequest{ - ProjectID: projectSlug, - }) - - if err != nil { - return model.Project{}, fmt.Errorf("unable to get project by slug. [err=%v]", err) - } - - return project, nil -} diff --git a/k8-operator/kubectl-install/install-secrets-operator.yaml b/k8-operator/kubectl-install/install-secrets-operator.yaml deleted file mode 100644 index 2956fe570b..0000000000 --- a/k8-operator/kubectl-install/install-secrets-operator.yaml +++ /dev/null @@ -1,1314 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: system - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: namespace - app.kubernetes.io/part-of: k8-operator - control-plane: controller-manager - name: infisical-operator-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - name: infisicaldynamicsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalDynamicSecret - listKind: InfisicalDynamicSecretList - plural: infisicaldynamicsecrets - singular: infisicaldynamicsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalDynamicSecret is the Schema for the infisicaldynamicsecrets API. - properties: - apiVersion: - description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" - type: string - kind: - description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" - type: string - metadata: - type: object - spec: - description: InfisicalDynamicSecretSpec defines the desired state of InfisicalDynamicSecret. - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - required: - - identityId - type: object - gcpIamAuth: - properties: - identityId: - type: string - serviceAccountKeyFilePath: - type: string - required: - - identityId - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - kubernetesAuth: - properties: - identityId: - type: string - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - required: - - identityId - - serviceAccountRef - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - credentialsRef - type: object - type: object - dynamicSecret: - properties: - environmentSlug: - type: string - projectId: - type: string - secretName: - type: string - secretsPath: - type: string - required: - - environmentSlug - - projectId - - secretName - - secretsPath - type: object - hostAPI: - type: string - leaseRevocationPolicy: - type: string - leaseTTL: - type: string - managedSecretReference: - properties: - creationPolicy: - default: Orphan - description: "The Kubernetes Secret creation policy. Enum with values: 'Owner', 'Orphan'. Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted." - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: "The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types" - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: This injects all retrieved secrets into the top level of your template. Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - required: - - authentication - - dynamicSecret - - leaseRevocationPolicy - - leaseTTL - - managedSecretReference - type: object - status: - description: InfisicalDynamicSecretStatus defines the observed state of InfisicalDynamicSecret. - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - dynamicSecretId: - type: string - lease: - properties: - creationTimestamp: - format: date-time - type: string - expiresAt: - format: date-time - type: string - id: - type: string - version: - format: int64 - type: integer - required: - - creationTimestamp - - expiresAt - - id - - version - type: object - maxTTL: - description: The MaxTTL can be null, if it's null, there's no max TTL and we should never have to renew. - type: string - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - name: infisicalpushsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalPushSecret - listKind: InfisicalPushSecretList - plural: infisicalpushsecrets - singular: infisicalpushsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalPushSecret is the Schema for the infisicalpushsecrets API - properties: - apiVersion: - description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" - type: string - kind: - description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" - type: string - metadata: - type: object - spec: - description: InfisicalPushSecretSpec defines the desired state of InfisicalPushSecret - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - required: - - identityId - type: object - gcpIamAuth: - properties: - identityId: - type: string - serviceAccountKeyFilePath: - type: string - required: - - identityId - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - required: - - identityId - type: object - kubernetesAuth: - properties: - identityId: - type: string - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - required: - - identityId - - serviceAccountRef - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - credentialsRef - type: object - type: object - deletionPolicy: - type: string - destination: - properties: - environmentSlug: - type: string - projectId: - type: string - secretsPath: - type: string - required: - - environmentSlug - - projectId - - secretsPath - type: object - hostAPI: - description: Infisical host to pull secrets from - type: string - push: - properties: - secret: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - secret - type: object - resyncInterval: - type: string - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - updatePolicy: - type: string - required: - - destination - - push - - resyncInterval - type: object - status: - description: InfisicalPushSecretStatus defines the observed state of InfisicalPushSecret - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - managedSecrets: - additionalProperties: - type: string - description: managed secrets is a map where the key is the ID, and the value is the secret key (string[id], string[key] ) - type: object - required: - - conditions - - managedSecrets - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - name: infisicalsecrets.secrets.infisical.com -spec: - group: secrets.infisical.com - names: - kind: InfisicalSecret - listKind: InfisicalSecretList - plural: infisicalsecrets - singular: infisicalsecret - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: InfisicalSecret is the Schema for the infisicalsecrets API - properties: - apiVersion: - description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" - type: string - kind: - description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" - type: string - metadata: - type: object - spec: - description: InfisicalSecretSpec defines the desired state of InfisicalSecret - properties: - authentication: - properties: - awsIamAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - azureAuth: - properties: - identityId: - type: string - resource: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - gcpIamAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - serviceAccountKeyFilePath: - type: string - required: - - identityId - - secretsScope - - serviceAccountKeyFilePath - type: object - gcpIdTokenAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - identityId - - secretsScope - type: object - kubernetesAuth: - properties: - identityId: - type: string - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - serviceAccountRef: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object - required: - - identityId - - secretsScope - - serviceAccountRef - type: object - serviceAccount: - properties: - environmentName: - type: string - projectId: - type: string - serviceAccountSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - environmentName - - projectId - - serviceAccountSecretReference - type: object - serviceToken: - properties: - secretsScope: - properties: - envSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - secretsPath - type: object - serviceTokenSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - secretsScope - - serviceTokenSecretReference - type: object - universalAuth: - properties: - credentialsRef: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - secretsScope: - properties: - envSlug: - type: string - projectSlug: - type: string - recursive: - type: boolean - secretsPath: - type: string - required: - - envSlug - - projectSlug - - secretsPath - type: object - required: - - credentialsRef - - secretsScope - type: object - type: object - hostAPI: - description: Infisical host to pull secrets from - type: string - managedKubeSecretReferences: - items: - properties: - creationPolicy: - default: Orphan - description: "The Kubernetes Secret creation policy. Enum with values: 'Owner', 'Orphan'. Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted." - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: "The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types" - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: This injects all retrieved secrets into the top level of your template. Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - type: array - managedSecretReference: - properties: - creationPolicy: - default: Orphan - description: "The Kubernetes Secret creation policy. Enum with values: 'Owner', 'Orphan'. Owner creates the secret and sets .metadata.ownerReferences of the InfisicalSecret CRD that created it. Orphan will not set the secret owner. This will result in the secret being orphaned and not deleted when the resource is deleted." - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - secretType: - default: Opaque - description: "The Kubernetes Secret type (experimental feature). More info: https://kubernetes.io/docs/concepts/configuration/secret/#secret-types" - type: string - template: - description: The template to transform the secret data - properties: - data: - additionalProperties: - type: string - description: The template key values - type: object - includeAllSecrets: - description: This injects all retrieved secrets into the top level of your template. Secrets defined in the template will take precedence over the injected ones. - type: boolean - type: object - required: - - secretName - - secretNamespace - type: object - resyncInterval: - default: 60 - type: integer - tls: - properties: - caRef: - description: Reference to secret containing CA cert - properties: - key: - description: The name of the secret property with the CA certificate value - type: string - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The namespace where the Kubernetes Secret is located - type: string - required: - - key - - secretName - - secretNamespace - type: object - type: object - tokenSecretReference: - properties: - secretName: - description: The name of the Kubernetes Secret - type: string - secretNamespace: - description: The name space where the Kubernetes Secret is located - type: string - required: - - secretName - - secretNamespace - type: object - required: - - resyncInterval - type: object - status: - description: InfisicalSecretStatus defines the observed state of InfisicalSecret - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: controller-manager - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: serviceaccount - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-controller-manager - namespace: infisical-operator-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: leader-election-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: role - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-leader-election-role - namespace: infisical-operator-system -rules: - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - name: infisical-operator-manager-role -rules: - - apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - delete - - get - - list - - update - - watch - - apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - update - - watch - - apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - get - - list - - watch - - apiGroups: - - apps - resources: - - daemonsets - - deployments - - statefulsets - verbs: - - get - - list - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - get - - list - - update - - watch - - apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/finalizers - verbs: - - update - - apiGroups: - - secrets.infisical.com - resources: - - infisicaldynamicsecrets/status - verbs: - - get - - patch - - update - - apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecrets/finalizers - verbs: - - update - - apiGroups: - - secrets.infisical.com - resources: - - infisicalpushsecrets/status - verbs: - - get - - patch - - update - - apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets/finalizers - verbs: - - update - - apiGroups: - - secrets.infisical.com - resources: - - infisicalsecrets/status - verbs: - - get - - patch - - update ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-metrics-reader -rules: - - nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrole - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-proxy-role -rules: - - apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create - - apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: leader-election-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: rolebinding - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-leader-election-rolebinding - namespace: infisical-operator-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: infisical-operator-leader-election-role -subjects: - - kind: ServiceAccount - name: infisical-operator-controller-manager - namespace: infisical-operator-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: manager-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: infisical-operator-manager-role -subjects: - - kind: ServiceAccount - name: infisical-operator-controller-manager - namespace: infisical-operator-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/part-of: k8-operator - name: infisical-operator-proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: infisical-operator-proxy-role -subjects: - - kind: ServiceAccount - name: infisical-operator-controller-manager - namespace: infisical-operator-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: service - app.kubernetes.io/part-of: k8-operator - control-plane: controller-manager - name: infisical-operator-controller-manager-metrics-service - namespace: infisical-operator-system -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: https - selector: - control-plane: controller-manager ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: k8-operator - app.kubernetes.io/instance: controller-manager - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: deployment - app.kubernetes.io/part-of: k8-operator - control-plane: controller-manager - name: infisical-operator-controller-manager - namespace: infisical-operator-system -spec: - replicas: 1 - selector: - matchLabels: - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - control-plane: controller-manager - spec: - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - arm64 - - ppc64le - - s390x - - key: kubernetes.io/os - operator: In - values: - - linux - containers: - - args: - - --health-probe-bind-address=:8081 - - --metrics-bind-address=127.0.0.1:8080 - - --leader-elect - command: - - /manager - image: infisical/kubernetes-operator:latest - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - securityContext: - runAsNonRoot: true - serviceAccountName: infisical-operator-controller-manager - terminationGracePeriodSeconds: 10 diff --git a/k8-operator/scripts/generate-helm.sh b/k8-operator/scripts/generate-helm.sh deleted file mode 100755 index 87d6ec1fbf..0000000000 --- a/k8-operator/scripts/generate-helm.sh +++ /dev/null @@ -1,487 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail -SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd) -PATH_TO_HELM_CHART="${SCRIPT_DIR}/../../helm-charts/secrets-operator" - -PROJECT_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd) -HELM_DIR="${PROJECT_ROOT}/../helm-charts/secrets-operator" -LOCALBIN="${PROJECT_ROOT}/bin" -KUSTOMIZE="${LOCALBIN}/kustomize" -HELMIFY="${LOCALBIN}/helmify" - -VERSION=$1 -VERSION_WITHOUT_V=$(echo "$VERSION" | sed 's/^v//') # needed to validate semver - - -# Version validation -if [ -z "$VERSION" ]; then - echo "Usage: $0 " - exit 1 -fi - - -if ! [[ "$VERSION_WITHOUT_V" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: Version must follow semantic versioning (e.g. 0.0.1)" - exit 1 -fi - -if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "Error: Version must start with 'v' (e.g. v0.0.1)" - exit 1 -fi - - - -cd "${PROJECT_ROOT}" -# first run the regular helm target to generate base templates -"${KUSTOMIZE}" build config/default | "${HELMIFY}" "${HELM_DIR}" - - - -# ? NOTE: Processes all files that end with crd.yaml (so only actual CRDs) -for crd_file in "${HELM_DIR}"/templates/*crd.yaml; do - # skip if file doesn't exist (pattern doesn't match) - [ -e "$crd_file" ] || continue - - echo "Processing CRD file: ${crd_file}" - - cp "$crd_file" "$crd_file.bkp" - - # if we ever need to run conditional logic based on the CRD kind, we can use this - # CRD_KIND=$(grep -E "kind: [a-zA-Z]+" "$crd_file" | head -n1 | awk '{print $2}') - # echo "Found CRD kind: ${CRD_KIND}" - - # create a new file with the conditional statement, then append the entire original content - echo "{{- if .Values.installCRDs }}" > "$crd_file.new" - cat "$crd_file.bkp" >> "$crd_file.new" - - # make sure the file ends with a newline before adding the end tag (otherwise it might get messed up and end up on the same line as the last line) - # check if file already ends with a newline - if [ "$(tail -c1 "$crd_file.new" | wc -l)" -eq 0 ]; then - # File doesn't end with a newline, add one - echo "" >> "$crd_file.new" - fi - - # add the end tag on a new line - echo "{{- end }}" >> "$crd_file.new" - - # replace the original file with the new one - mv "$crd_file.new" "$crd_file" - - # clean up backup - rm "$crd_file.bkp" - - echo "Completed processing for: ${crd_file}" -done - -# ? NOTE: Processes all files ending in -rbac.yaml, except metrics-reader-rbac.yaml -for rbac_file in "${HELM_DIR}/templates"/*-rbac.yaml; do - if [ -f "$rbac_file" ]; then - if [[ "$(basename "$rbac_file")" == "metrics-reader-rbac.yaml" ]]; then - echo "Skipping metrics-reader-rbac.yaml" - continue - fi - - if [[ "$(basename "$rbac_file")" == "leader-election-rbac.yaml" ]]; then - echo "Skipping infisicaldynamicsecret-admin-rbac.yaml" - continue - fi - - filename=$(basename "$rbac_file") - base_name="${filename%-rbac.yaml}" - - echo "Processing $(basename "$rbac_file") file specifically" - - cp "${rbac_file}" "${rbac_file}.bkp" - - # extract the rules section from the original file - # Extract from 'rules:' until we hit a document separator or another top-level key - - if grep -q "^---" "${rbac_file}.bkp"; then - # File has document separator, extract until --- - rules_section=$(sed -n '/^rules:/,/^---/p' "${rbac_file}.bkp" | sed '$d') - else - # Simple file, extract everything from rules to end - rules_section=$(sed -n '/^rules:/,$ p' "${rbac_file}.bkp") - fi - # extract the original label lines - original_labels=$(sed -n '/^ labels:/,/^roleRef:/p' "${HELM_DIR}/templates/${rbac_file}.bkp" | grep "app.kubernetes.io" || true) - - # create a new file from scratch with exactly what we want - { - # first section: Role/ClusterRole - echo "apiVersion: rbac.authorization.k8s.io/v1" - echo "{{- if and .Values.scopedNamespace .Values.scopedRBAC }}" - echo "kind: Role" - echo "{{- else }}" - echo "kind: ClusterRole" - echo "{{- end }}" - echo "metadata:" - echo " name: {{ include \"secrets-operator.fullname\" . }}-${base_name}-role" - echo " {{- if and .Values.scopedNamespace .Values.scopedRBAC }}" - echo " namespace: {{ .Values.scopedNamespace | quote }}" - echo " {{- end }}" - echo " labels:" - echo " {{- include \"secrets-operator.labels\" . | nindent 4 }}" - - # add the existing rules section from helm-generated file - echo "$rules_section" - - # second section: RoleBinding/ClusterRoleBinding - echo "---" - echo "apiVersion: rbac.authorization.k8s.io/v1" - echo "{{- if and .Values.scopedNamespace .Values.scopedRBAC }}" - echo "kind: RoleBinding" - echo "{{- else }}" - echo "kind: ClusterRoleBinding" - echo "{{- end }}" - echo "metadata:" - echo " name: {{ include \"secrets-operator.fullname\" . }}-${base_name}-rolebinding" - echo " {{- if and .Values.scopedNamespace .Values.scopedRBAC }}" - echo " namespace: {{ .Values.scopedNamespace | quote }}" - echo " {{- end }}" - echo " labels:" - echo "$original_labels" - echo " {{- include \"secrets-operator.labels\" . | nindent 4 }}" - - # add the roleRef section with custom logic - echo "roleRef:" - echo " apiGroup: rbac.authorization.k8s.io" - echo " {{- if and .Values.scopedNamespace .Values.scopedRBAC }}" - echo " kind: Role" - echo " {{- else }}" - echo " kind: ClusterRole" - echo " {{- end }}" - echo " name: '{{ include \"secrets-operator.fullname\" . }}-${base_name}-role'" - - # add the subjects section - sed -n '/^subjects:/,$ p' "${rbac_file}.bkp" - } > "${rbac_file}.new" - - mv "${rbac_file}.new" "${rbac_file}" - rm "${rbac_file}.bkp" - - echo "Completed processing for $(basename "$rbac_file") with both role conditions and metadata applied" - fi -done - -# ? NOTE(Daniel): Processes and metrics-reader-rbac.yaml -for rbac_file in "${HELM_DIR}/templates/metrics-reader-rbac.yaml"; do - if [ -f "$rbac_file" ]; then - echo "Adding scopedNamespace condition to $(basename "$rbac_file")" - - { - echo "{{- if not .Values.scopedNamespace }}" - cat "$rbac_file" - echo "" - echo "{{- end }}" - } > "$rbac_file.new" - - mv "$rbac_file.new" "$rbac_file" - - echo "Completed processing for $(basename "$rbac_file")" - fi -done - - -# ? NOTE(Daniel): Processes metrics-service.yaml -if [ -f "${HELM_DIR}/templates/metrics-service.yaml" ]; then - echo "Processing metrics-service.yaml file specifically" - - metrics_file="${HELM_DIR}/templates/metrics-service.yaml" - touch "${metrics_file}.new" - - while IFS= read -r line; do - if [[ "$line" == *"{{- include \"secrets-operator.selectorLabels\" . | nindent 4 }}"* ]]; then - # keep original indentation for the selector labels line - echo " {{- include \"secrets-operator.selectorLabels\" . | nindent 4 }}" >> "${metrics_file}.new" - elif [[ "$line" == *"{{- .Values.metricsService.ports | toYaml | nindent 2 }}"* ]]; then - # fix indentation for the ports line - use less indentation here - echo " {{- .Values.metricsService.ports | toYaml | nindent 2 }}" >> "${metrics_file}.new" - else - echo "$line" >> "${metrics_file}.new" - fi - done < "${metrics_file}" - - mv "${metrics_file}.new" "${metrics_file}" - echo "Completed processing for metrics_service.yaml" -fi - - - -# ? NOTE(Daniel): Processes deployment.yaml -if [ -f "${HELM_DIR}/templates/deployment.yaml" ]; then - echo "Processing deployment.yaml file" - - touch "${HELM_DIR}/templates/deployment.yaml.new" - - securityContext_replaced=0 - in_first_securityContext=0 - first_securityContext_found=0 - containers_fixed=0 - next_line_needs_dash=0 - imagePullSecrets_added=0 - skip_imagePullSecrets_block=0 - - # process the file line by line - while IFS= read -r line; do - # Fix containers array syntax issue - if [[ "$line" =~ ^[[:space:]]*containers:[[:space:]]*$ ]] && [ "$containers_fixed" -eq 0 ]; then - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - next_line_needs_dash=1 - containers_fixed=1 - continue - fi - - # Add dash to first container item if missing - if [ "$next_line_needs_dash" -eq 1 ]; then - # Check if line already starts with a dash (after whitespace) - if [[ "$line" =~ ^[[:space:]]*-[[:space:]] ]]; then - # Already has dash, just add the line - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - elif [[ "$line" =~ ^[[:space:]]*[a-zA-Z] ]]; then - # No dash but has content, add dash before the content - # Extract indentation and content - indent=$(echo "$line" | sed 's/^\([[:space:]]*\).*/\1/') - content=$(echo "$line" | sed 's/^[[:space:]]*\(.*\)/\1/') - echo "${indent}- ${content}" >> "${HELM_DIR}/templates/deployment.yaml.new" - else - # Empty line or other, just add as-is - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - fi - next_line_needs_dash=0 - continue - fi - - # check if this is the first securityContext line (for kube-rbac-proxy) - if [[ "$line" =~ securityContext.*Values.controllerManager.kubeRbacProxy ]] && [ "$first_securityContext_found" -eq 0 ]; then - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - first_securityContext_found=1 - in_first_securityContext=1 - continue - fi - - # check if this is the args line after the first securityContext - if [ "$in_first_securityContext" -eq 1 ] && [[ "$line" =~ args: ]]; then - # Add our custom args section with conditional logic - echo " - args:" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " {{- toYaml .Values.controllerManager.manager.args | nindent 8 }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " {{- if and .Values.scopedNamespace .Values.scopedRBAC }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " - --namespace={{ .Values.scopedNamespace }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " {{- end }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - in_first_securityContext=0 - continue - fi - - # check if this is the problematic pod securityContext line - if [[ "$line" =~ securityContext.*Values.controllerManager.podSecurityContext ]] && [ "$securityContext_replaced" -eq 0 ]; then - # Replace with our custom securityContext - echo " securityContext:" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " runAsNonRoot: true" >> "${HELM_DIR}/templates/deployment.yaml.new" - securityContext_replaced=1 - continue - fi - - # skip the line if it's just the trailing part of the replacement - if [[ "$securityContext_replaced" -eq 1 ]] && [[ "$line" =~ ^[[:space:]]*[0-9]+[[:space:]]*\}\} ]]; then - # this is the trailing part of the template expression, skip it - securityContext_replaced=0 - continue - fi - - # skip the simplified args line that replaced our custom one - if [[ "$line" =~ args:.*Values.controllerManager.manager.args ]]; then - continue - fi - - - - # check if this is the serviceAccountName line - add imagePullSecrets after it - if [[ "$line" =~ serviceAccountName.*include.*fullname ]] && [ "$imagePullSecrets_added" -eq 0 ]; then - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - # Add imagePullSecrets section - echo " {{- with .Values.imagePullSecrets }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " imagePullSecrets:" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " {{- toYaml . | nindent 8 }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " {{- end }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - imagePullSecrets_added=1 - continue - fi - - # skip existing imagePullSecrets sections to avoid duplicates - if [[ "$line" =~ imagePullSecrets ]] || [[ "$line" =~ "with .Values.imagePullSecrets" ]]; then - # Skip this line and the associated template block - skip_imagePullSecrets_block=1 - continue - fi - - # skip lines that are part of an existing imagePullSecrets block - if [ "$skip_imagePullSecrets_block" -eq 1 ]; then - if [[ "$line" =~ "{{- end }}" ]]; then - skip_imagePullSecrets_block=0 - fi - continue - fi - - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.new" - done < "${HELM_DIR}/templates/deployment.yaml" - - echo " nodeSelector: {{ toYaml .Values.controllerManager.nodeSelector | nindent 8 }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - echo " tolerations: {{ toYaml .Values.controllerManager.tolerations | nindent 8 }}" >> "${HELM_DIR}/templates/deployment.yaml.new" - - mv "${HELM_DIR}/templates/deployment.yaml.new" "${HELM_DIR}/templates/deployment.yaml" - echo "Completed processing for deployment.yaml" -fi - -# ? NOTE(Daniel): Fix args structure in deployment.yaml -if [ -f "${HELM_DIR}/templates/deployment.yaml" ]; then - echo "Fixing args structure in deployment.yaml" - - touch "${HELM_DIR}/templates/deployment.yaml.tmp" - - # process the file line by line - while IFS= read -r line; do - # look for the specific line pattern: "- args: {{- toYaml .Values.controllerManager.manager.args | nindent 8 }}" - if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*args:[[:space:]]*\{\{-.*toYaml.*Values\.controllerManager\.manager\.args.*\}\}[[:space:]]*$ ]]; then - # extract the base indentation (everything before the "- args:") - base_indent=$(echo "$line" | sed 's/^\([[:space:]]*\)-.*/\1/') - - # replace with our multi-line structure - echo "${base_indent}- args:" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - echo "${base_indent} {{- toYaml .Values.controllerManager.manager.args | nindent 8 }}" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - echo "${base_indent} {{- if and .Values.scopedNamespace .Values.scopedRBAC }}" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - echo "${base_indent} - --namespace={{ .Values.scopedNamespace }}" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - echo "${base_indent} {{- end }}" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - else - echo "$line" >> "${HELM_DIR}/templates/deployment.yaml.tmp" - fi - done < "${HELM_DIR}/templates/deployment.yaml" - - mv "${HELM_DIR}/templates/deployment.yaml.tmp" "${HELM_DIR}/templates/deployment.yaml" - echo "Completed args structure fix" -fi - - - - - - - - - - - - - - - -# ? NOTE(Daniel): Processes values.yaml -if [ -f "${HELM_DIR}/values.yaml" ]; then - echo "Processing values.yaml file" - - # Create a temporary file - touch "${HELM_DIR}/values.yaml.new" - - # Flag to track sections - in_resources_section=0 - in_service_account=0 - - previous_line="" - # Process the file line by line - while IFS= read -r line; do - if [[ "$line" =~ resources: ]]; then - in_resources_section=1 - fi - - if [[ "$line" =~ podSecurityContext: ]]; then - # skip this line and continue to the next line - continue - fi - - if [[ "$line" =~ runAsNonRoot: ]] && [ "$in_resources_section" -eq 1 ]; then - # also skip this line and continue to the next line - continue - fi - - if [[ "$line" =~ ^[[:space:]]*serviceAccount: ]]; then - # set the flag to 1 so we can continue to print the associated lines later - in_service_account=1 - # print the current line - echo "$line" >> "${HELM_DIR}/values.yaml.new" - continue - fi - - # process annotations under serviceAccount (only if in_service_account is true) - if [ "$in_service_account" -eq 1 ]; then - # Print the current line (annotations) - echo "$line" >> "${HELM_DIR}/values.yaml.new" - - # if we've processed the annotations, add our new fields - if [[ "$line" =~ annotations: ]]; then - # get the base indentation level (of serviceAccount:) - base_indent=$(echo "$line" | sed 's/\(^[[:space:]]*\).*/\1/') - base_indent=${base_indent%??} # Remove two spaces to get to parent level - - # add nodeSelector and tolerations at the same level as serviceAccount - echo "${base_indent}nodeSelector: {}" >> "${HELM_DIR}/values.yaml.new" - echo "${base_indent}tolerations: []" >> "${HELM_DIR}/values.yaml.new" - fi - - # exit serviceAccount section when we hit the next top-level item - if [[ "$line" =~ ^[[:space:]]{2}[a-zA-Z] ]] && ! [[ "$line" =~ annotations: ]]; then - in_service_account=0 - fi - - continue - fi - - # if we reach this point, we'll exit the resources section, this is the next top-level item - if [ "$in_resources_section" -eq 1 ] && [[ "$line" =~ ^[[:space:]]{2}[a-zA-Z] ]]; then - in_resources_section=0 - fi - - # output the line unchanged - echo "$line" >> "${HELM_DIR}/values.yaml.new" - previous_line="$line" - done < "${HELM_DIR}/values.yaml" - - - - # hacky, just append the kubernetesClusterDomain fields at the end of the file - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version - sed -i '' '/kubernetesClusterDomain: /d' "${HELM_DIR}/values.yaml.new" - else - # Linux version - sed -i '/kubernetesClusterDomain: /d' "${HELM_DIR}/values.yaml.new" - fi - - echo "kubernetesClusterDomain: cluster.local" >> "${HELM_DIR}/values.yaml.new" - echo "scopedNamespace: \"\"" >> "${HELM_DIR}/values.yaml.new" - echo "scopedRBAC: false" >> "${HELM_DIR}/values.yaml.new" - echo "installCRDs: true" >> "${HELM_DIR}/values.yaml.new" - echo "imagePullSecrets: []" >> "${HELM_DIR}/values.yaml.new" - - # replace the original file with the new one - mv "${HELM_DIR}/values.yaml.new" "${HELM_DIR}/values.yaml" - - echo "Completed processing for values.yaml" -fi - -echo "Helm chart generation complete with custom templating applied." - - - - -# For Linux vs macOS sed compatibility -if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version - sed -i '' 's/appVersion: .*/appVersion: "'"$VERSION"'"/g' "${PATH_TO_HELM_CHART}/Chart.yaml" - sed -i '' 's/version: .*/version: '"$VERSION"'/g' "${PATH_TO_HELM_CHART}/Chart.yaml" -else - # Linux version - sed -i 's/appVersion: .*/appVersion: "'"$VERSION"'"/g' "${PATH_TO_HELM_CHART}/Chart.yaml" - sed -i 's/version: .*/version: '"$VERSION"'/g' "${PATH_TO_HELM_CHART}/Chart.yaml" -fi - -echo "Helm chart version updated to ${VERSION}" \ No newline at end of file diff --git a/k8-operator/test/e2e/e2e_suite_test.go b/k8-operator/test/e2e/e2e_suite_test.go deleted file mode 100644 index f4f91405f9..0000000000 --- a/k8-operator/test/e2e/e2e_suite_test.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package e2e - -import ( - "fmt" - "os" - "os/exec" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/Infisical/infisical/k8-operator/test/utils" -) - -var ( - // Optional Environment Variables: - // - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup. - // These variables are useful if CertManager is already installed, avoiding - // re-installation and conflicts. - skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true" - // isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster - isCertManagerAlreadyInstalled = false - - // projectImage is the name of the image which will be build and loaded - // with the code source changes to be tested. - projectImage = "example.com/k8-operator:v0.0.1" -) - -// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated, -// temporary environment to validate project changes with the purpose of being used in CI jobs. -// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs -// CertManager. -func TestE2E(t *testing.T) { - RegisterFailHandler(Fail) - _, _ = fmt.Fprintf(GinkgoWriter, "Starting k8-operator integration test suite\n") - RunSpecs(t, "e2e suite") -} - -var _ = BeforeSuite(func() { - By("building the manager(Operator) image") - cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage)) - _, err := utils.Run(cmd) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image") - - // TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is - // built and available before running the tests. Also, remove the following block. - By("loading the manager(Operator) image on Kind") - err = utils.LoadImageToKindClusterWithName(projectImage) - ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind") - - // The tests-e2e are intended to run on a temporary cluster that is created and destroyed for testing. - // To prevent errors when tests run in environments with CertManager already installed, - // we check for its presence before execution. - // Setup CertManager before the suite if not skipped and if not already installed - if !skipCertManagerInstall { - By("checking if cert manager is installed already") - isCertManagerAlreadyInstalled = utils.IsCertManagerCRDsInstalled() - if !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n") - Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager") - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: CertManager is already installed. Skipping installation...\n") - } - } -}) - -var _ = AfterSuite(func() { - // Teardown CertManager after the suite if not skipped and if it was not already installed - if !skipCertManagerInstall && !isCertManagerAlreadyInstalled { - _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n") - utils.UninstallCertManager() - } -}) diff --git a/k8-operator/test/e2e/e2e_test.go b/k8-operator/test/e2e/e2e_test.go deleted file mode 100644 index 5f3830e453..0000000000 --- a/k8-operator/test/e2e/e2e_test.go +++ /dev/null @@ -1,330 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package e2e - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/Infisical/infisical/k8-operator/test/utils" -) - -// namespace where the project is deployed in -const namespace = "infisical-operator-system" - -// serviceAccountName created for the project -const serviceAccountName = "infisical-operator-controller-manager" - -// metricsServiceName is the name of the metrics service of the project -const metricsServiceName = "infisical-operator-controller-manager-metrics-service" - -// metricsRoleBindingName is the name of the RBAC that will be created to allow get the metrics data -const metricsRoleBindingName = "infisical-operator-metrics-binding" - -var _ = Describe("Manager", Ordered, func() { - var controllerPodName string - - // Before running the tests, set up the environment by creating the namespace, - // enforce the restricted security policy to the namespace, installing CRDs, - // and deploying the controller. - BeforeAll(func() { - By("creating manager namespace") - cmd := exec.Command("kubectl", "create", "ns", namespace) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create namespace") - - By("labeling the namespace to enforce the restricted security policy") - cmd = exec.Command("kubectl", "label", "--overwrite", "ns", namespace, - "pod-security.kubernetes.io/enforce=restricted") - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to label namespace with restricted policy") - - By("installing CRDs") - cmd = exec.Command("make", "install") - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to install CRDs") - - By("deploying the controller-manager") - cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectImage)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to deploy the controller-manager") - }) - - // After all tests have been executed, clean up by undeploying the controller, uninstalling CRDs, - // and deleting the namespace. - AfterAll(func() { - By("cleaning up the curl pod for metrics") - cmd := exec.Command("kubectl", "delete", "pod", "curl-metrics", "-n", namespace) - _, _ = utils.Run(cmd) - - By("undeploying the controller-manager") - cmd = exec.Command("make", "undeploy") - _, _ = utils.Run(cmd) - - By("uninstalling CRDs") - cmd = exec.Command("make", "uninstall") - _, _ = utils.Run(cmd) - - By("removing manager namespace") - cmd = exec.Command("kubectl", "delete", "ns", namespace) - _, _ = utils.Run(cmd) - }) - - // After each test, check for failures and collect logs, events, - // and pod descriptions for debugging. - AfterEach(func() { - specReport := CurrentSpecReport() - if specReport.Failed() { - By("Fetching controller manager pod logs") - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - controllerLogs, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, "Controller logs:\n %s", controllerLogs) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get Controller logs: %s", err) - } - - By("Fetching Kubernetes events") - cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp") - eventsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, "Kubernetes events:\n%s", eventsOutput) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get Kubernetes events: %s", err) - } - - By("Fetching curl-metrics logs") - cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - if err == nil { - _, _ = fmt.Fprintf(GinkgoWriter, "Metrics logs:\n %s", metricsOutput) - } else { - _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get curl-metrics logs: %s", err) - } - - By("Fetching controller manager pod description") - cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace) - podDescription, err := utils.Run(cmd) - if err == nil { - fmt.Println("Pod description:\n", podDescription) - } else { - fmt.Println("Failed to describe controller pod") - } - } - }) - - SetDefaultEventuallyTimeout(2 * time.Minute) - SetDefaultEventuallyPollingInterval(time.Second) - - Context("Manager", func() { - It("should run successfully", func() { - By("validating that the controller-manager pod is running as expected") - verifyControllerUp := func(g Gomega) { - // Get the name of the controller-manager pod - cmd := exec.Command("kubectl", "get", - "pods", "-l", "control-plane=controller-manager", - "-o", "go-template={{ range .items }}"+ - "{{ if not .metadata.deletionTimestamp }}"+ - "{{ .metadata.name }}"+ - "{{ \"\\n\" }}{{ end }}{{ end }}", - "-n", namespace, - ) - - podOutput, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information") - podNames := utils.GetNonEmptyLines(podOutput) - g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running") - controllerPodName = podNames[0] - g.Expect(controllerPodName).To(ContainSubstring("controller-manager")) - - // Validate the pod's status - cmd = exec.Command("kubectl", "get", - "pods", controllerPodName, "-o", "jsonpath={.status.phase}", - "-n", namespace, - ) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status") - } - Eventually(verifyControllerUp).Should(Succeed()) - }) - - It("should ensure the metrics endpoint is serving metrics", func() { - By("creating a ClusterRoleBinding for the service account to allow access to metrics") - cmd := exec.Command("kubectl", "create", "clusterrolebinding", metricsRoleBindingName, - "--clusterrole=infisical-operator-metrics-reader", - fmt.Sprintf("--serviceaccount=%s:%s", namespace, serviceAccountName), - ) - _, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create ClusterRoleBinding") - - By("validating that the metrics service is available") - cmd = exec.Command("kubectl", "get", "service", metricsServiceName, "-n", namespace) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Metrics service should exist") - - By("getting the service account token") - token, err := serviceAccountToken() - Expect(err).NotTo(HaveOccurred()) - Expect(token).NotTo(BeEmpty()) - - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") - } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) - - By("verifying that the controller manager is serving the metrics server") - verifyMetricsServerStarted := func(g Gomega) { - cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), - "Metrics server not yet started") - } - Eventually(verifyMetricsServerStarted).Should(Succeed()) - - By("creating the curl-metrics pod to access the metrics endpoint") - cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", - "--namespace", namespace, - "--image=curlimages/curl:latest", - "--overrides", - fmt.Sprintf(`{ - "spec": { - "containers": [{ - "name": "curl", - "image": "curlimages/curl:latest", - "command": ["/bin/sh", "-c"], - "args": ["curl -v -k -H 'Authorization: Bearer %s' https://%s.%s.svc.cluster.local:8443/metrics"], - "securityContext": { - "readOnlyRootFilesystem": true, - "allowPrivilegeEscalation": false, - "capabilities": { - "drop": ["ALL"] - }, - "runAsNonRoot": true, - "runAsUser": 1000, - "seccompProfile": { - "type": "RuntimeDefault" - } - } - }], - "serviceAccountName": "%s" - } - }`, token, metricsServiceName, namespace, serviceAccountName)) - _, err = utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to create curl-metrics pod") - - By("waiting for the curl-metrics pod to complete.") - verifyCurlUp := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "pods", "curl-metrics", - "-o", "jsonpath={.status.phase}", - "-n", namespace) - output, err := utils.Run(cmd) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status") - } - Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed()) - - By("getting the metrics by checking curl-metrics logs") - metricsOutput := getMetricsOutput() - Expect(metricsOutput).To(ContainSubstring( - "controller_runtime_reconcile_total", - )) - }) - - // +kubebuilder:scaffold:e2e-webhooks-checks - - // TODO: Customize the e2e test suite with scenarios specific to your project. - // Consider applying sample/CR(s) and check their status and/or verifying - // the reconciliation by using the metrics, i.e.: - // metricsOutput := getMetricsOutput() - // Expect(metricsOutput).To(ContainSubstring( - // fmt.Sprintf(`controller_runtime_reconcile_total{controller="%s",result="success"} 1`, - // strings.ToLower(), - // )) - }) -}) - -// serviceAccountToken returns a token for the specified service account in the given namespace. -// It uses the Kubernetes TokenRequest API to generate a token by directly sending a request -// and parsing the resulting token from the API response. -func serviceAccountToken() (string, error) { - const tokenRequestRawString = `{ - "apiVersion": "authentication.k8s.io/v1", - "kind": "TokenRequest" - }` - - // Temporary file to store the token request - secretName := fmt.Sprintf("%s-token-request", serviceAccountName) - tokenRequestFile := filepath.Join("/tmp", secretName) - err := os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o644)) - if err != nil { - return "", err - } - - var out string - verifyTokenCreation := func(g Gomega) { - // Execute kubectl command to create the token - cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf( - "/api/v1/namespaces/%s/serviceaccounts/%s/token", - namespace, - serviceAccountName, - ), "-f", tokenRequestFile) - - output, err := cmd.CombinedOutput() - g.Expect(err).NotTo(HaveOccurred()) - - // Parse the JSON output to extract the token - var token tokenRequest - err = json.Unmarshal(output, &token) - g.Expect(err).NotTo(HaveOccurred()) - - out = token.Status.Token - } - Eventually(verifyTokenCreation).Should(Succeed()) - - return out, err -} - -// getMetricsOutput retrieves and returns the logs from the curl pod used to access the metrics endpoint. -func getMetricsOutput() string { - By("getting the curl-metrics logs") - cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace) - metricsOutput, err := utils.Run(cmd) - Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod") - Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK")) - return metricsOutput -} - -// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response, -// containing only the token field that we need to extract. -type tokenRequest struct { - Status struct { - Token string `json:"token"` - } `json:"status"` -} diff --git a/k8-operator/test/utils/utils.go b/k8-operator/test/utils/utils.go deleted file mode 100644 index 841683609b..0000000000 --- a/k8-operator/test/utils/utils.go +++ /dev/null @@ -1,254 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package utils - -import ( - "bufio" - "bytes" - "fmt" - "os" - "os/exec" - "strings" - - . "github.com/onsi/ginkgo/v2" // nolint:revive,staticcheck -) - -const ( - prometheusOperatorVersion = "v0.77.1" - prometheusOperatorURL = "https://github.com/prometheus-operator/prometheus-operator/" + - "releases/download/%s/bundle.yaml" - - certmanagerVersion = "v1.16.3" - certmanagerURLTmpl = "https://github.com/cert-manager/cert-manager/releases/download/%s/cert-manager.yaml" -) - -func warnError(err error) { - _, _ = fmt.Fprintf(GinkgoWriter, "warning: %v\n", err) -} - -// Run executes the provided command within this context -func Run(cmd *exec.Cmd) (string, error) { - dir, _ := GetProjectDir() - cmd.Dir = dir - - if err := os.Chdir(cmd.Dir); err != nil { - _, _ = fmt.Fprintf(GinkgoWriter, "chdir dir: %q\n", err) - } - - cmd.Env = append(os.Environ(), "GO111MODULE=on") - command := strings.Join(cmd.Args, " ") - _, _ = fmt.Fprintf(GinkgoWriter, "running: %q\n", command) - output, err := cmd.CombinedOutput() - if err != nil { - return string(output), fmt.Errorf("%q failed with error %q: %w", command, string(output), err) - } - - return string(output), nil -} - -// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics. -func InstallPrometheusOperator() error { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "create", "-f", url) - _, err := Run(cmd) - return err -} - -// UninstallPrometheusOperator uninstalls the prometheus -func UninstallPrometheusOperator() { - url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// IsPrometheusCRDsInstalled checks if any Prometheus CRDs are installed -// by verifying the existence of key CRDs related to Prometheus. -func IsPrometheusCRDsInstalled() bool { - // List of common Prometheus CRDs - prometheusCRDs := []string{ - "prometheuses.monitoring.coreos.com", - "prometheusrules.monitoring.coreos.com", - "prometheusagents.monitoring.coreos.com", - } - - cmd := exec.Command("kubectl", "get", "crds", "-o", "custom-columns=NAME:.metadata.name") - output, err := Run(cmd) - if err != nil { - return false - } - crdList := GetNonEmptyLines(output) - for _, crd := range prometheusCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// UninstallCertManager uninstalls the cert manager -func UninstallCertManager() { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "delete", "-f", url) - if _, err := Run(cmd); err != nil { - warnError(err) - } -} - -// InstallCertManager installs the cert manager bundle. -func InstallCertManager() error { - url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion) - cmd := exec.Command("kubectl", "apply", "-f", url) - if _, err := Run(cmd); err != nil { - return err - } - // Wait for cert-manager-webhook to be ready, which can take time if cert-manager - // was re-installed after uninstalling on a cluster. - cmd = exec.Command("kubectl", "wait", "deployment.apps/cert-manager-webhook", - "--for", "condition=Available", - "--namespace", "cert-manager", - "--timeout", "5m", - ) - - _, err := Run(cmd) - return err -} - -// IsCertManagerCRDsInstalled checks if any Cert Manager CRDs are installed -// by verifying the existence of key CRDs related to Cert Manager. -func IsCertManagerCRDsInstalled() bool { - // List of common Cert Manager CRDs - certManagerCRDs := []string{ - "certificates.cert-manager.io", - "issuers.cert-manager.io", - "clusterissuers.cert-manager.io", - "certificaterequests.cert-manager.io", - "orders.acme.cert-manager.io", - "challenges.acme.cert-manager.io", - } - - // Execute the kubectl command to get all CRDs - cmd := exec.Command("kubectl", "get", "crds") - output, err := Run(cmd) - if err != nil { - return false - } - - // Check if any of the Cert Manager CRDs are present - crdList := GetNonEmptyLines(output) - for _, crd := range certManagerCRDs { - for _, line := range crdList { - if strings.Contains(line, crd) { - return true - } - } - } - - return false -} - -// LoadImageToKindClusterWithName loads a local docker image to the kind cluster -func LoadImageToKindClusterWithName(name string) error { - cluster := "kind" - if v, ok := os.LookupEnv("KIND_CLUSTER"); ok { - cluster = v - } - kindOptions := []string{"load", "docker-image", name, "--name", cluster} - cmd := exec.Command("kind", kindOptions...) - _, err := Run(cmd) - return err -} - -// GetNonEmptyLines converts given command output string into individual objects -// according to line breakers, and ignores the empty elements in it. -func GetNonEmptyLines(output string) []string { - var res []string - elements := strings.Split(output, "\n") - for _, element := range elements { - if element != "" { - res = append(res, element) - } - } - - return res -} - -// GetProjectDir will return the directory where the project is -func GetProjectDir() (string, error) { - wd, err := os.Getwd() - if err != nil { - return wd, fmt.Errorf("failed to get current working directory: %w", err) - } - wd = strings.ReplaceAll(wd, "/test/e2e", "") - return wd, nil -} - -// UncommentCode searches for target in the file and remove the comment prefix -// of the target content. The target content may span multiple lines. -func UncommentCode(filename, target, prefix string) error { - // false positive - // nolint:gosec - content, err := os.ReadFile(filename) - if err != nil { - return fmt.Errorf("failed to read file %q: %w", filename, err) - } - strContent := string(content) - - idx := strings.Index(strContent, target) - if idx < 0 { - return fmt.Errorf("unable to find the code %q to be uncomment", target) - } - - out := new(bytes.Buffer) - _, err = out.Write(content[:idx]) - if err != nil { - return fmt.Errorf("failed to write to output: %w", err) - } - - scanner := bufio.NewScanner(bytes.NewBufferString(target)) - if !scanner.Scan() { - return nil - } - for { - if _, err = out.WriteString(strings.TrimPrefix(scanner.Text(), prefix)); err != nil { - return fmt.Errorf("failed to write to output: %w", err) - } - // Avoid writing a newline in case the previous line was the last in target. - if !scanner.Scan() { - break - } - if _, err = out.WriteString("\n"); err != nil { - return fmt.Errorf("failed to write to output: %w", err) - } - } - - if _, err = out.Write(content[idx+len(target):]); err != nil { - return fmt.Errorf("failed to write to output: %w", err) - } - - // false positive - // nolint:gosec - if err = os.WriteFile(filename, out.Bytes(), 0644); err != nil { - return fmt.Errorf("failed to write file %q: %w", filename, err) - } - - return nil -}