Skip to content

API Authentication

Every automation request to ZestSSH must be authenticated with an API key. This page covers how keys are generated, used, and managed.

API keys are generated in Settings > Automation > Manage API Keys > Create Key.

  • Length: 48 characters
  • Character set: a-z, A-Z, 0-9 (62 characters)
  • Entropy: ~285 bits (log2(62^48))
  • Generator: Random.secure(), backed by the OS CSPRNG (/dev/urandom on Linux/Android, SecRandomCopyBytes on iOS/macOS, BCryptGenRandom on Windows)

Each key has:

FieldDescription
IDUUID, used internally
LabelHuman-readable name (e.g. “Tasker - Backups”)
KeyThe 48-character secret
Created AtTimestamp of creation
Last Used AtUpdated on each successful use
Expires AtOptional expiration date

Keys can be created with an optional expiration date. After the expiration date:

  • The key is treated as invalid.
  • Requests using it are rejected with an error.
  • Failed attempts with expired keys count toward the rate limit.
  • The key remains in the list (for audit purposes) until you delete it.

Include the key as a key query parameter:

zestssh://execute?connection=MyServer&command=uptime&key=abcDEF123...

Pass the key as an intent extra:

Extra: key → abcDEF123...

The API key is passed locally on the device --- it does not traverse the network. URL schemes and Android intents are inter-process communication (IPC) mechanisms within the same device.

However, be aware that:

  • Other apps on the device could potentially intercept deep links if they register the same URL scheme (Android prevents this with app signing verification).
  • Intent extras are visible to apps with READ_LOGS permission on rooted devices.
  • Tasker profiles that contain API keys store them in Tasker’s configuration files (plaintext on disk if the device is rooted or backed up).

When a request arrives:

  1. Rate limit check: If no key matches and an active lockout is in effect (triggered by repeated consecutive failures, see below), the request is rejected immediately. A request presenting a valid, unexpired key still succeeds even while a lockout from earlier bad attempts is active.
  2. Hash and compare: The submitted key is SHA-256 hashed and compared against stored key hashes using constant-time comparison to prevent timing side-channel attacks.
  3. Expiration check: If the matched key has expired, reject.
  4. Mark used: Update the lastUsedAt timestamp atomically with the validation.

The hash-then-compare approach means the raw key is never compared byte-by-byte, eliminating timing information that could help an attacker narrow down the key value.

Lockout escalates with repeated failures rather than staying fixed:

ConditionEffect
Failed validationIncrement failure counter
5 consecutive failuresLock out all automation for 1 minute
10 consecutive failuresLock out all automation for 5 minutes
15 or more consecutive failuresLock out all automation for 30 minutes (cap)
Successful validationReset failure counter to 0 and clear any active lockout
Lockout timer elapsesRequests are allowed again, but the failure counter itself is only cleared by a successful validation (or by an app restart that occurs after the lockout has already expired)

The failed-attempt counter and lockout timestamp are persisted to secure storage, so they survive app restarts.

To rotate a key without downtime:

  1. Create a new key with a descriptive label (e.g. “Tasker - Backups v2”).
  2. Update all automation tasks (Tasker profiles, Shortcuts, etc.) to use the new key.
  3. Verify the new key works by running a test automation.
  4. Delete the old key.

There is no limit on the number of active keys. Creating a new key does not invalidate existing keys.

To immediately revoke a key:

  1. Go to Settings > Automation > Manage API Keys.
  2. Swipe or tap the delete action on the key.
  3. The key is removed from secure storage. Any future requests using it are rejected.

Revocation is immediate. There is no grace period.

In the API key management UI, keys are displayed in masked format: the first 4 characters, 8 dots, and the last 4 characters (e.g. abcD........EF12). The full key is only visible once at creation time. If you lose a key, create a new one --- there is no way to recover the full key from storage.

  1. Create separate keys for each automation tool or purpose. This limits the blast radius of a compromised key.
  2. Set expiration dates for keys used in temporary or time-limited automation.
  3. Review last-used timestamps periodically. Keys that have not been used in months may be candidates for revocation.
  4. Do not embed keys in shared files. If you export Tasker profiles, remove or placeholder the API keys first.
  5. Enable app lock (biometric or PIN) in ZestSSH to prevent unauthorized key creation on a stolen device.