feat: update all clients to use api.unsandbox.com/keys/validate

Change key validation endpoint from portal to API across all clients:
- C: Update PORTAL_BASE to API_BASE in validate_api_key()
- Python (sync/async): Change PORTAL_BASE to API_BASE
- Perl: Change $PORTAL_BASE to $API_BASE
- Rust (sync/async): Change hardcoded URL to api.unsandbox.com

All other languages (Go, Java, Kotlin, C#, Ruby, PHP, JavaScript) already
use their makeRequest() function with API_BASE, so no changes needed.

The key subcommand already exists and continues to work with the new endpoint.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
russell@unturf.com 2026-01-20 03:51:38 -05:00
parent 63ed81e5da
commit fbd9273c3d
6 changed files with 14 additions and 15 deletions

View file

@ -5574,7 +5574,7 @@ static int validate_api_key(const UnsandboxCredentials *creds) {
response.size = 0;
char url[256];
snprintf(url, sizeof(url), "%s/keys/validate", PORTAL_BASE);
snprintf(url, sizeof(url), "%s/keys/validate", API_BASE);
// Use HMAC authentication with empty body
struct curl_slist *headers = NULL;
@ -5824,7 +5824,7 @@ void print_usage(const char *prog) {
fprintf(stderr, " --lock ID Lock a service to prevent deletion\n");
fprintf(stderr, " --unlock ID Unlock a service to allow deletion\n");
fprintf(stderr, " --resize ID Resize service vCPU/memory (requires --vcpu)\n");
fprintf(stderr, " --redeploy ID Re-run bootstrap script (requires --bootstrap)\n");
fprintf(stderr, " --redeploy ID Re-run bootstrap script (optional: --bootstrap or --bootstrap-file)\n");
fprintf(stderr, " --execute ID CMD Run a command in a running service\n");
fprintf(stderr, " --dump-bootstrap ID [FILE] Dump bootstrap script (for migrations)\n");
fprintf(stderr, " --snapshot ID Create snapshot of service (paid tiers only)\n");
@ -5901,7 +5901,8 @@ void print_usage(const char *prog) {
fprintf(stderr, " %s service --unfreeze abc123 # unfreeze a service\n", prog);
fprintf(stderr, " %s service --resize abc123 --vcpu 4 # scale to 4 vCPU, 8GB RAM\n", prog);
fprintf(stderr, " %s service --destroy abc123 # destroy a service\n", prog);
fprintf(stderr, " %s service --redeploy abc123 --bootstrap ./script.sh\n", prog);
fprintf(stderr, " %s service --redeploy abc123 --bootstrap-file ./script.sh\n", prog);
fprintf(stderr, " %s service --redeploy abc123 # uses stored encrypted bootstrap\n", prog);
fprintf(stderr, " %s service --execute maldoror 'journalctl -u myapp -n 50'\n", prog);
fprintf(stderr, " %s service --dump-bootstrap maldoror # print bootstrap to stdout\n", prog);
fprintf(stderr, " %s service --dump-bootstrap maldoror backup.sh # save to file\n", prog);
@ -9332,13 +9333,11 @@ int main(int argc, char *argv[]) {
}
ret = resize_service(creds, service_id, vcpu);
} else if (do_redeploy) {
if (!service_bootstrap) {
fprintf(stderr, "Error: --bootstrap required for --redeploy\n");
curl_global_cleanup();
free_credentials(creds);
return 1;
}
ret = redeploy_service(creds, service_id, service_bootstrap);
// Bootstrap is optional for redeploy:
// - If provided via --bootstrap or --bootstrap-file, use it
// - If omitted, API will use the stored encrypted bootstrap
const char *bootstrap_to_use = bootstrap_file ? bootstrap_file : service_bootstrap;
ret = redeploy_service(creds, service_id, bootstrap_to_use);
} else if (do_execute) {
// Default timeout 30 seconds (30000ms)
ret = execute_service(creds, service_id, execute_command, 30000);

View file

@ -853,7 +853,7 @@ sub validate_key {
my ($public_key, $secret_key, $should_extend) = @_;
# Call /keys/validate endpoint
my $url = "$PORTAL_BASE/keys/validate";
my $url = "$API_BASE/keys/validate";
my $ua = LWP::UserAgent->new(timeout => 30);
my $request = HTTP::Request->new('POST' => $url);
$request->header('Authorization' => "Bearer $public_key");

View file

@ -1635,7 +1635,7 @@ async def validate_keys(
"""
public_key, secret_key = _resolve_credentials(public_key, secret_key)
url = f"{PORTAL_BASE}/keys/validate"
url = f"{API_BASE}/keys/validate"
timestamp = int(time.time())
body = ""

View file

@ -2007,7 +2007,7 @@ def validate_keys(
"""
public_key, secret_key = _resolve_credentials(public_key, secret_key)
url = f"{PORTAL_BASE}/keys/validate"
url = f"{API_BASE}/keys/validate"
timestamp = int(time.time())
body = ""

View file

@ -1815,7 +1815,7 @@ pub async fn validate_keys(creds: &Credentials) -> Result<KeysValid> {
.timeout(Duration::from_secs(30))
.build()?;
let url = "https://unsandbox.com/keys/validate";
let url = "https://api.unsandbox.com/keys/validate";
let path = "/keys/validate";
let timestamp = get_timestamp();
let body_str = "";

View file

@ -2121,7 +2121,7 @@ pub fn validate_keys(creds: &Credentials) -> Result<KeysValid> {
.timeout(Duration::from_secs(30))
.build()?;
let url = "https://unsandbox.com/keys/validate";
let url = "https://api.unsandbox.com/keys/validate";
let path = "/keys/validate";
let timestamp = get_timestamp();
let body_str = "";