sondahub / Infisical sandbox
An Infisical API mock with Universal Auth
Infisical’s API, answered by sondahub: a machine identity that logs in with Universal Auth, projects with dev, staging and prod, folders, secrets through the raw v3 and the v4 API — single and batch — with references expanded, imports, tags, versions, comments and personal overrides. Point the SDK’s host or the CLI’s API URL here.
An independent imitation for testing. Not affiliated with, or endorsed by, Infisical.
Connect
- Instead of
- https://app.infisical.com
- Site URL
- https://api.sondahub.com
- Client id
- 9e3779b1-ccd0-8520-64cf-8f988c2ee30a
- Client secret
- sondahub-infisical-sandbox-client-secret
- Project
- 9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b (Backend)
- Also at
- https://api.sondahub.com/sandbox/infisical
- OpenAPI 3
- https://api.sondahub.com/sandbox/infisical/openapi.json
Python (infisicalsdk)
from infisical_sdk import InfisicalSDKClient
client = InfisicalSDKClient(host='https://api.sondahub.com')
client.auth.universal_auth.login(client_id='9e3779b1-ccd0-8520-64cf-8f988c2ee30a', client_secret='sondahub-infisical-sandbox-client-secret')
# carry the sandbox session from each answer to the next request
http = client.api.session
def keep(response, *args, **kwargs):
token = response.headers.get('X-Sondahub-Session')
if token:
http.headers['X-Sondahub-Session'] = token
http.hooks['response'].append(keep)
secrets = client.secrets.list_secrets(project_id='9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b', environment_slug='dev', secret_path='/',
expand_secret_references=True)
print({s.secretKey: s.secretValue for s in secrets.secrets})
Infisical CLI
export INFISICAL_API_URL=https://api.sondahub.com/api export INFISICAL_TOKEN=$(infisical login --method=universal-auth \ --client-id=9e3779b1-ccd0-8520-64cf-8f988c2ee30a --client-secret=sondahub-infisical-sandbox-client-secret --silent --plain) infisical export --projectId=9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b --env=prod --format=dotenv
Import it. In Sonda: Import → From a URL, paste the OpenAPI address. You get a folder per resource and a request per operation, with example bodies and names from the seed, so most requests work as they are. Then set the auth: Bearer: the accessToken from the login request (any token works). Any client that imports OpenAPI 3 takes the same address.
Try it here
curl -X POST "https://api.sondahub.com/api/v1/auth/universal-auth/login" \
-H "Content-Type: application/json" \
-d '{"clientId":"9e3779b1-ccd0-8520-64cf-8f988c2ee30a","clientSecret":"sondahub-infisical-sandbox-client-secret"}'
curl "https://api.sondahub.com/api/v3/secrets/raw?workspaceId=9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b&environment=dev&secretPath=%2F&expandSecretReferences=true" \ -H "Authorization: Bearer <accessToken from the login>"
curl "https://api.sondahub.com/api/v3/secrets/raw/DB_HOST?workspaceId=9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b&environment=prod&secretPath=%2Fdatabase" \ -H "Authorization: Bearer <accessToken from the login>"
curl "https://api.sondahub.com/api/v3/secrets/raw?workspaceId=9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b&environment=prod&secretPath=%2F&include_imports=true" \ -H "Authorization: Bearer <accessToken from the login>"
curl -X POST "https://api.sondahub.com/api/v3/secrets/raw/QUEUE_URL" \
-H "Authorization: Bearer <accessToken from the login>" \
-H "Content-Type: application/json" \
-d '{"workspaceId":"9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b","environment":"dev","secretPath":"/","secretValue":"redis://localhost:6379/1","secretComment":"The job queue","type":"shared"}'
curl -X PATCH "https://api.sondahub.com/api/v3/secrets/raw/QUEUE_URL" \
-H "Authorization: Bearer <accessToken from the login>" \
-H "Content-Type: application/json" \
-d '{"workspaceId":"9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b","environment":"dev","secretPath":"/","secretValue":"redis://cache:6379/1"}'
curl "https://api.sondahub.com/api/v2/folders?projectId=9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b&environment=prod&path=%2F" \ -H "Authorization: Bearer <accessToken from the login>"
From the shell, keep the token yourself: curl -i shows X-Sondahub-Session; send it back with -H "X-Sondahub-Session: …". How sessions work.
The seed organization
| Project | Environments and folders with secrets |
|---|---|
Backend9e3779b1-8889-ed6a-7bdb-82e5f94b1a0b | dev /, dev /database, staging /, staging /database, prod /, prod /database, prod /payments |
Web3c6ef362-da47-3389-64e5-54bb903d3dc1 | dev /, staging /, prod / |
Each project has dev, staging and prod. DATABASE_URL in each environment is built from references to its /database folder; prod’s root imports /payments; LOG_LEVEL in dev has your personal override. Tags (database, payments, public) filter lists with tagSlugs.
Every value in the seed is fake and made up when the site is built. What you write is kept in your own session token and nowhere else — but this is a public playground: never send it a real secret. Not affiliated with, or endorsed by, Infisical.
What it answers
Errors are Infisical’s: {"reqId", "statusCode", "message", "error"}.
Questions
Is this Infisical?
No — an independent imitation of Infisical’s API for testing, not affiliated with or endorsed by Infisical. No organization or account is involved and nothing is encrypted.
Will the Infisical SDK and CLI work against it?
The Python set-up on this page was run against the sandbox with Infisical’s Python SDK: the Universal Auth login, listing with references expanded and imports, getting by name, creating, updating, deleting, folders, and a refused login. The CLI lines use its documented API URL variable and Universal Auth login. The site URL is https://api.sondahub.com itself — the sandbox answers Infisical’s /api paths at the root.
Which credentials work?
The published machine identity — client id 9e3779b1-ccd0-8520-64cf-8f988c2ee30a, client secret sondahub-infisical-sandbox-client-secret — has its secret checked; any other UUID as a client id logs in with any secret. The access token lasts two hours and renews at /api/v1/auth/token/renew. The API then takes the token as a bearer — and any other bearer, so a request can be tried without logging in.
How are references expanded?
With expandSecretReferences=true, as Infisical does: ${KEY} from the same folder, ${env.KEY} from an environment’s root, ${env.folder.sub.KEY} from a folder. A secret import puts another folder’s secrets in imports when include_imports=true, and a get by name looks there too. A personal override replaces the shared value for you.
What is not modelled?
The other auth methods (AWS, GCP, Azure, Kubernetes, OIDC, LDAP), dynamic secrets, rotation, the KMS API, approvals, point-in-time recovery, secret sharing and the end-to-end-encrypted (non-raw) secret endpoints. A secret keeps its last 10 values.