getsops/sops · error

failed to get Azure token credential to encrypt data: %w

Error message

failed to get Azure token credential to encrypt data: %w

What it means

EncryptContext encrypts the SOPS data key with the vault key. This error means obtaining the Azure token credential failed at encryption time — same family as the version-retrieval credential error but raised inside the encrypt path.

Source

Thrown at azkv/keysource.go:209

	kdetail, err := c.GetKey(ctx, key.Name, key.Version, nil)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to fetch Azure Key to retrieve key version: %w", err)
	}
	key.Version = kdetail.Key.KID.Version()

	log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Version fetch succeeded")
	return nil
}

// EncryptContext takes a SOPS data key, encrypts it with Azure Key Vault, and stores
// the result in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
	token, err := key.getTokenCredential()
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to get Azure token credential to encrypt data: %w", err)
	}

	c, err := azkeys.NewClient(key.VaultURL, token, key.clientOptions)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to construct Azure Key Vault client to encrypt data: %w", err)
	}

	resp, err := c.Encrypt(ctx, key.Name, key.Version, azkeys.KeyOperationParameters{
		Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
		Value:     dataKey,
	}, nil)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to encrypt sops data key with Azure Key Vault key '%s': %w", key.ToString(), err)
	}

	encodedEncryptedKey := base64.RawURLEncoding.EncodeToString(resp.KeyOperationResult.Result)

View on GitHub (pinned to 13442bb981)

Solutions

  1. Run az login or set AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET before invoking sops -e
  2. Enable/verify managed identity if running inside Azure compute
  3. Rotate the expired client secret or certificate and update the environment
  4. Validate ambient credentials with az account get-access-token --resource https://vault.azure.net

Example fix

// before
sops -e file.yaml  # fails: no Azure credentials in CI
// after
export AZURE_TENANT_ID=... AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=...
sops -e file.yaml
Defensive patterns

Strategy: try-catch

Validate before calling

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
    return fmt.Errorf("run 'az login' or set AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET before encrypting: %w", err)
}
_, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{Scopes: []string{"https://vault.azure.net/.default"}})
if err != nil { return fmt.Errorf("Azure token acquisition failed: %w", err) }

Try / catch

err := sopsEncrypt(...)
if strings.Contains(err.Error(), "failed to get Azure token credential to encrypt data") {
    var cue *azidentity.CredentialUnavailableError
    if errors.As(err, &cue) {
        return fmt.Errorf("no Azure auth source; run 'az login' or configure a service principal: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: EncryptContext calls key.getTokenCredential() before building the client; it errors because no DefaultAzureCredential source (az login, service principal env vars, managed identity) is available or valid.

Common situations: Running sops -e in CI without Azure credentials; expired service principal secret; az login session for the wrong tenant/subscription; container without managed identity.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/c660b4dd8ae1e48a. Report an issue: GitHub.