Skip to content

Error: Missing workspace id or environment (Status: 400) #40

@maradonam18

Description

@maradonam18

;TLDR;

InfisicalSDK doesn't retive secrets when using a service token with scope /**, but works with service token with scope /.

Context

So, i'm trying to update my company self hosted docker infisical from version v0.77.3-postgres, and I'm having some troubles downloading secrets that are not located in the root directory of the env. Before the upgrade we used a script that retrived the secrets by interrogating the api directly and then decripting them using this script that was ported to python.
The new script downloads and decripts all the secrets from our infisical correctly, if they are located in the root and the scope of the service token is /, but in the moment i use a serivice token with scope /**, or /dir/**, it drops this error

Traceback (most recent call last):
  File "/tmp/infisical_venv/lib64/python3.9/site-packages/infisical_sdk/infisical_requests.py", line 132, in _handle_response
    response.raise_for_status()
  File "/usr/lib/python3.9/site-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http://infisical-upgrade.mydomain.com/api/v3/secrets/raw?workspaceId=&environment=&secretPath=%2F&viewSecretValue=true&expandSecretReferences=true&recursive=true&include_imports=false

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/path/to/my/app/scripts/./get_env.sh", line 181, in <module>
    main()
  File "/path/to/my/app/scripts/./get_env.sh", line 160, in main
    secrets = download_all_secrets(
  File "/path/to/my/app/scripts/./get_env.sh", line 136, in download_all_secrets
    response = client.secrets.list_secrets(
  File "/tmp/infisical_venv/lib64/python3.9/site-packages/infisical_sdk/resources/secrets.py", line 52, in list_secrets
    result = self.requests.get(
  File "/tmp/infisical_venv/lib64/python3.9/site-packages/infisical_sdk/infisical_requests.py", line 88, in wrapper
    return func(*args, **kwargs)
  File "/tmp/infisical_venv/lib64/python3.9/site-packages/infisical_sdk/infisical_requests.py", line 167, in get
    data = self._handle_response(response)
  File "/tmp/infisical_venv/lib64/python3.9/site-packages/infisical_sdk/infisical_requests.py", line 140, in _handle_response
    raise APIError(
infisical_sdk.infisical_requests.APIError: **Missing workspace id or environment** (Status: 400)

Debug

By increasing the debug level i found that the request made using service / doesn't specify any workspace nor env

send: b'GET /api/v3/secrets/raw?workspaceId=&environment=&secretPath=%2F&viewSecretValue=true&expandSecretReferences=true&recursive=true&include_imports=false HTTP/1.1\r\nHost: infisical-upgrade.mydomain.com\r\nUser-Agent: python-requests/2.25.1\r\nAccept-Encoding: gzip, deflate\r\nAccept: application/json\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nAuthorization: Bearer st.abc.def.ghi\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
...
header: access-control-allow-origin: http://infisical-upgrade.mydomain.com
header: access-control-allow-credentials: true
....

But when the same request is done using a scope /** service token, it return a the 400 error above.

Code

#!/usr/bin/env python3

import os
import subprocess
import sys
import tempfile
import json
import requests
import boto3
from botocore.exceptions import ClientError
import logging
import shutil
from infisical_sdk import InfisicalSDKClient

# --- Logging ---
logging.basicConfig(
    filename="/tmp/mount_env.log",
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s] %(message)s",
    filemode="w"
)
logger = logging.getLogger(__name__)
logger.info("Script avviato")

# --- Configurazioni ---
HOST = "https://infisical.myprivate.domain.com"
OUT_PATH = "/path/to/my/app/"

def get_secret():
    """
    Get service token from AWS secret manager
    :return: service_token
    """

def download_all_secrets(service_token: str, secret_path: str = "/") -> dict:
    """
    Scarica i segreti usando l'sdk e il service token
    :param service_token:
    :param secret_path:
    :return: result
    """
    try:
        logger.info("[*] Inizializzazione client Infisical e download segreti...")
        client = InfisicalSDKClient(
            token=service_token,
            cache_ttl=None,
            host=HOST
        )

        response = client.secrets.list_secrets(
            project_id="",
            environment_slug="",
            secret_path=secret_path,
            view_secret_value=True,
            recursive=True,
            include_imports=False,
        )

        result = {}
        for secret in response.secrets:
            full_key = f"{secret.secretPath}{secret.secretKey}"
            result[full_key] = secret.secretValue

        logger.info(f"[+] Scaricati {len(result)} segreti da Infisical.")
        return result

    except Exception as e:
        logger.exception(f"[-] Errore durante il download dei segreti da Infisical {e}")
        raise

def main():
    try:
        logger.info("[+] Avvio download e scrittura .env")
        secrets = download_all_secrets(
            service_token=get_secret(),
            secret_path="/"
        )

        with open(f"{OUT_PATH}.env", "w") as file:
            for full_key, secret_value in secrets.items():
                secret_key = full_key.split("/")[-1]
                if secret_key:
                    file.write(f"{secret_key.upper()}={secret_value}\n")

        logger.info(f"[+] File {OUT_PATH}.env generato con successo.")
        logger.info(f"[+] Totale segreti scritti: {len(secrets)}")

    except Exception as e:
        logger.exception(f"[-] Errore fatale durante l'esecuzione dello script: \n{e}")
        raise

main()

The variables
project_id="",
environment_slug="",
I left them blank on purpurpose, since before we didn't need to specify them before, and the service token has already these info in it, as said in the documentation.

Conclusion

So i don't understand why I need to specify a workspace or/and env, since the service token should already have all the info required to retrive these secrets. Can you tell me if I'm missing something?

PS: I have tried getting the env value using amazon info and even if I specify the env value it still return me the same error :-(.

System information

Machine running the script get_env.py
OS: Amazon Linux 2023.7.20250609 aarch64
Python: v3.9.22
PythonSDK: v1.0.9 (the env is recreated each time the script runs, to avoid a problem with other system packages)

Machine running infisical
OS: Debian GNU/Linux 12 (bookworm) aarch64
Docker: 28.2.2
Infisical: v0.133.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions