Hardcoding secrets (API keys, tokens, connection strings) directly inside SharePoint Framework (SPFx) code is dangerous and violates security best practices. The reasons are,

This article explains how to securely store secrets, with real code examples and safe patterns.

Safe Options to Protect Secrets

You have four valid approaches:

  1. Azure Key Vault

  2. Azure Function proxy

  3. SharePoint API Permissions + AadHttpClient

  4. Environment variables + pipeline secrets

1. Use Azure Key Vault (Recommended for sensitive secrets)

Azure Key Vault stores your secret and SPFx gets it indirectly, through a secure backend (Azure Function or API).

Note: SPFx cannot call Key Vault directly (needs Azure AD app & server identity). So you must use Azure Function or API Management in between.

SPFx  →  Azure Function (Managed Identity)  →  Key Vault  →  Backend API

Example (Azure Function to fetch secret)

Function code:

[Function("GetApiSecret")]
public async Task<HttpResponseData> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req)
{
    var client = new SecretClient(
        new Uri(Environment.GetEnvironmentVariable("KeyVaultUrl")),
        new DefaultAzureCredential());

    var secret = (await client.GetSecretAsync("MyApiKey")).Value.Value;

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteString(secret);
    return response;
}

SPFx calls the Function:

const response = await this.context.httpClient.get(
  "https://myfunction.azurewebsites.net/api/GetApiSecret",
  HttpClient.configurations.v1
);

const secret = await response.text();
console.log(secret); // SPFx gets secret only temporarily (still safer)

Use secret temporarily, not store it.

2. Use Azure Function as a Secure Proxy (Most Common)

This is the safest & simplest scalable method.

SPFx → Azure Function → External API

The Azure Function:

Example:

[Function("GetData")]
public async Task<HttpResponseData> Run(
    [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
    var apiKey = Environment.GetEnvironmentVariable("MyApiKey");

    var http = new HttpClient();
    http.DefaultRequestHeaders.Add("x-api-key", apiKey);

    var apiResponse = await http.GetStringAsync("https://myapi.com/data");

    var response = req.CreateResponse(HttpStatusCode.OK);
    response.WriteString(apiResponse);
    return response;
}

SPFx calls:

const result = await this.context.httpClient.post(
  "https://myfunction.azurewebsites.net/api/GetData",
  HttpClient.configurations.v1,
  { headers: { "Content-Type": "application/json" } }
);

const data = await result.json();

3. Use AadHttpClient + API Permissions (Safe & SPFx-native)

If your backend API is Azure AD protected:

SPFx → Azure AD → Protected API

Configure in package-solution.json

"webApiPermissionRequests": [
  {
    "resource": "MyApi",
    "scope": "user_impersonation"
  }
]

Call with AadHttpClient:

const client = await this.context.aadHttpClientFactory.getClient("api://your-app-id");

const response = await client.get(`${apiUrl}/data`, AadHttpClient.configurations.v1);
const data = await response.json();

This is very secure because:

4. Use Environment Variables + CI/CD (Not secure alone, but useful)

Don't store secrets locally.
Instead, use Azure DevOps / GitHub Actions pipelines.

Example

variables:
  API_KEY: $(MySecretApiKey)

Then inject into write-manifest.json or .env file:

Note:

Conclusion

Protecting secrets in SPFx is not optional—it is critical.
Because SPFx runs on the client side, any secret placed inside your web part code is automatically visible to the end user.

The correct strategy is:

With these patterns, your SPFx solutions remain secure, enterprise-ready, and compliant.