From 7c313cdf90bbca1f9a72865289d341320b11a875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hanu=C5=A1?= Date: Thu, 2 Jul 2026 00:42:33 +0200 Subject: [PATCH] feat(auth): treat APIFY_TOKEN env var as authenticated context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When APIFY_TOKEN is exported in the environment, resolveToken() now returns it directly, so any command that calls the API works without a prior `apify login`. This matches the Apify SDK behavior and removes the biggest bootstrap friction for agents and CI: they ship a token via env and would previously hit a "you are not logged in" wall on the first command. Also improves the MissingAuth error message: if APIFY_TOKEN is set but the API rejected it, the hint now says so instead of telling the user to `apify login`. No change for interactive users who ran `apify login` — the on-disk token path is unchanged when APIFY_TOKEN is not set. Co-Authored-By: Claude Opus 4.7 --- src/lib/utils.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b129d369c..3c8aa9729 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -134,20 +134,31 @@ export const getLocalUserInfo = async (): Promise => { }; /** - * Gets instance of ApifyClient for user otherwise throws error + * Gets instance of ApifyClient for user otherwise throws error. + * + * When APIFY_TOKEN is present in the environment and no on-disk auth exists, + * this treats the command as authenticated with the env token — no prior + * `apify login` needed. Primary use case: CI and agent harnesses that ship + * a token via env and would otherwise hit an auth wall on the first command. */ export async function getLoggedClientOrThrow() { const loggedClient = await getLoggedClient(); if (!loggedClient) { process.exitCode = CommandExitCodes.MissingAuth; - throw new Error('You are not logged in with your Apify account. Call "apify login" to fix that.'); + const hint = process.env.APIFY_TOKEN + ? 'APIFY_TOKEN is set in the environment but did not validate against the Apify API. Check that the token is current and has access to this workspace.' + : 'You are not logged in with your Apify account. Call "apify login" to fix that, or export APIFY_TOKEN in your environment (recommended for CI/agent contexts).'; + throw new Error(hint); } return loggedClient; } const resolveToken = async (existingToken?: string): Promise => { if (existingToken) return existingToken; + // Prefer APIFY_TOKEN from env when set — matches Apify SDK behavior and lets + // agents/CI skip `apify login`. Falls through to keyring/auth.json when unset. + if (process.env.APIFY_TOKEN) return process.env.APIFY_TOKEN; await ensureMigrated(); return getToken(); };