usebruno/bruno · error · Error

EdgeGrid: clientSecret is required

Error message

EdgeGrid: clientSecret is required

What it means

Thrown by Bruno's Akamai EdgeGrid signing helper when the `clientSecret` field is missing or blank (isStrPresent returns false). The client secret is the HMAC key material for the signing key, so without it the signature cannot be computed.

Source

Thrown at packages/bruno-requests/src/auth/edgegrid-helper.js:48

 * @param {string} [config.timestamp] - optional timestamp override
 * @param {string} [config.headersToSign] - comma-separated header names to sign
 * @param {string|number} [config.maxBodySize=131072]
 * @param {Object} request - axios request config ({ method, url, headers, data })
 * @returns {Promise<string>} Authorization header value
 */
export async function signEdgeGridRequest(config, request) {
  const { accessToken, clientToken, clientSecret, baseURL, headersToSign } = config;
  const maxBodySize = config.maxBodySize ? parseInt(config.maxBodySize, 10) : MAX_BODY_SIZE_DEFAULT;

  // Validate required fields
  if (!isStrPresent(accessToken)) {
    throw new Error('EdgeGrid: accessToken is required');
  }
  if (!isStrPresent(clientToken)) {
    throw new Error('EdgeGrid: clientToken is required');
  }
  if (!isStrPresent(clientSecret)) {
    throw new Error('EdgeGrid: clientSecret is required');
  }

  // Generate or use provided nonce and timestamp
  const nonce = isStrPresent(config.nonce) ? config.nonce : makeEdgeGridNonce();
  const timestamp = isStrPresent(config.timestamp) ? config.timestamp : makeEdgeGridTimestamp();

  // Determine the URL to sign — use baseURL's host/protocol if provided, otherwise the request URL.
  let urlToSign = request.url;
  if (isStrPresent(baseURL)) {
    const requestUrl = new URL(request.url);
    // A scheme-less baseURL like "localhost:6000" mis-parses ("localhost:" becomes the protocol
    // and the host is empty). If there's no "scheme://", borrow the request URL's scheme.
    const normalizedBaseURL = /^[a-z][a-z0-9+.-]*:\/\//i.test(baseURL.trim())
      ? baseURL.trim()
      : `${requestUrl.protocol}//${baseURL.trim()}`;
    const baseParsed = new URL(normalizedBaseURL);
    urlToSign = `${baseParsed.protocol}//${baseParsed.host}${requestUrl.pathname}${requestUrl.search}`;
  }

View on GitHub (pinned to 9bdd81c7bd)

Solutions

  1. Set config.clientSecret to the Akamai API client secret.
  2. Confirm the Bruno variable providing the secret is defined in the current environment.
  3. Treat all three EdgeGrid fields as required and validate them together before signing.

Example fix

// before
const config = { accessToken: '...', clientToken: '...' }; // clientSecret missing

// after
const config = {
  accessToken: bru.getVar('EDGEGRID_ACCESS_TOKEN'),
  clientToken: bru.getVar('EDGEGRID_CLIENT_TOKEN'),
  clientSecret: bru.getVar('EDGEGRID_CLIENT_SECRET')
};
Defensive patterns

Strategy: validation

Validate before calling

function validateEdgeGrid(cfg) {
  const missing = ['clientSecret'].filter((k) => !cfg[k] || !String(cfg[k]).trim());
  if (missing.length) throw new Error('EdgeGrid missing: ' + missing.join(','));
}

Type guard

const hasClientSecret = (cfg) => typeof cfg?.clientSecret === 'string' && cfg.clientSecret.trim().length > 0;

Try / catch

try { await signEdgeGridRequest(config, request); }
catch (err) {
  if (/clientSecret is required/.test(err.message)) { config.clientSecret = bru.getVar('EDGEGRID_CLIENT_SECRET'); }
  else throw err;
}

Prevention

When it happens

Trigger: Configuring EdgeGrid auth with an empty or unset clientSecret — e.g. the secret was never pasted in, or the Bruno variable holding it is undefined in the active environment.

Common situations: Secret field cleared for security and not re-populated; secret stored under a different variable name; wrong environment active.

Related errors


AI-assisted analysis of usebruno/bruno@9bdd81c7bd (2026-08-13). Data as JSON: /api/errors/2b7490d31090f7f7. Report an issue: GitHub.