Authentication overview

Shields.io is a service designed to generate informational SVG badges, primarily for public display in project READMEs or websites. The fundamental operational model of Shields.io involves constructing a URL that specifies the badge's content, style, and data source. For most common use cases, such as displaying the version of a public package or the status of an open-source build, Shields.io operates without requiring direct authentication from the user to Shields.io itself. The service fetches publicly accessible data and renders the badge as described in the Shields.io documentation.

However, when a dynamic badge needs to retrieve information from a private source—such as a private GitHub repository, a proprietary build system, or an internal API—authentication becomes a critical concern. In such scenarios, Shields.io does not act as an authentication broker. Instead, the responsibility for authentication lies with the upstream service that provides the data. Users must configure the authentication details for these private data sources. This typically involves embedding credentials (like API keys or tokens) directly into the dynamic badge URL, or more securely, using a server-side proxy to mediate access and protect sensitive information.

The design philosophy of Shields.io emphasizes simplicity and statelessness. It avoids storing user credentials, which means any authentication details required for accessing private data must be provided with each badge request or managed externally by the user's infrastructure. This approach offloads credential management and security responsibilities to the user and the upstream data provider, aligning with the stateless nature of web services as defined by HTTP standards.

Supported authentication methods

As Shields.io itself does not directly handle authentication for private data sources, the "supported authentication methods" refer to how users can provide credentials to the upstream services that Shields.io queries for dynamic badges. The choice of method largely depends on the upstream API's requirements and the user's security posture. Direct URL-based authentication is common for convenience but carries significant security risks if not managed carefully.

Here's a breakdown of common approaches to facilitate authenticated data retrieval for dynamic Shields.io badges:

Method When to Use Security Level Shields.io Integration
Public/Unauthenticated Access Data is publicly available (e.g., open-source package versions, public GitHub repo stats). N/A (no authentication needed) Direct URL to public API endpoint or pre-defined Shields.io integrations.
URL-encoded API Keys/Tokens Accessing private APIs with simple token-based auth. Suitable for quickly testing or low-security non-sensitive data. Low to Medium (Discouraged for sensitive data due to URL exposure in logs, browser history, and referers.) Embed API key or token directly in the url parameter of a dynamic badge. Example: https://img.shields.io/badge/dynamic/json?url=https://api.example.com/data?key=YOUR_API_KEY&query=$.status
HTTP Basic Authentication (via Proxy) Upstream API requires Basic Auth (username/password). Medium (when proxied correctly) A custom proxy server handles Basic Auth and exposes an unauthenticated endpoint to Shields.io. The proxy stores credentials securely.
OAuth 2.0 (via Proxy) Upstream API uses OAuth 2.0 for authorization (e.g., GitHub, GitLab private repos). High (when proxied correctly) A custom proxy server obtains and refreshes OAuth tokens, then serves the data to Shields.io. This is the recommended secure approach for OAuth-protected resources. OAuth documentation can be found on resources like OAuth.net.
Custom Server-Side Endpoint For maximum control over data transformation, caching, and security. High Create a backend service that fetches data from the private API (using any required authentication method), processes it, and serves it as JSON to a dynamic Shields.io badge. This endpoint can be unauthenticated for Shields.io, as the heavy lifting of security is handled server-side.

Getting your credentials

Since Shields.io doesn't directly manage credentials, the process of "getting your credentials" refers to obtaining them from the specific external service whose data you wish to display on a badge. This typically involves steps like:

  1. Identify the Upstream Service: Determine which API or service holds the data you need (e.g., GitHub, GitLab, a custom build server, a monitoring tool).
  2. Consult Service Documentation: Navigate to the official developer documentation of that service to understand its authentication mechanisms. For instance, AWS provides comprehensive documentation on managing security credentials, and GitHub explains how to generate personal access tokens.
  3. Generate API Keys or Tokens: If the service uses API keys or personal access tokens, follow their instructions to generate one. Ensure it has only the necessary permissions (least privilege principle) to access the specific data required for your badge.
  4. Configure OAuth 2.0 Applications: If the service uses OAuth 2.0 (common for accessing user-specific or private repository data), you might need to register an OAuth application with the service. This process yields a Client ID and Client Secret, which are then used by your proxy server to obtain access tokens.
  5. Set Up Basic Authentication: For services requiring username and password, these credentials will be provided by the service administrator or obtained through the service's user management interface. Again, these should be handled by a secure proxy.

Important: Always treat your credentials as sensitive information. Never hardcode them directly into publicly accessible code or commit them to version control. For server-side solutions, use environment variables, secret management services, or secure configuration files.

Authenticated request example

A direct "authenticated request example" for Shields.io typically involves a dynamic badge URL that includes an API key or token as a query parameter. While convenient, this method is generally discouraged for sensitive data due to the risks of exposing credentials in URLs, server logs, and browser histories. The following example illustrates how it could be done for a fictional service, but always consider the security implications.

Example using URL-encoded API Key (for demonstration only, use with caution)

https://img.shields.io/badge/dynamic/json?label=Project%20Status&url=https://api.example.com/v1/status?apiKey=YOUR_SUPER_SECRET_API_KEY&query=$.data.status&color=blue

In this hypothetical example:

  • https://api.example.com/v1/status is the private API endpoint.
  • apiKey=YOUR_SUPER_SECRET_API_KEY is the credential embedded directly in the API URL.
  • query=$.data.status specifies the JSON path to extract the status value.
  • label and color define the badge's appearance.

Recommended secure approach: Using a custom server-side proxy

For sensitive data, the recommended approach is to create a simple backend service that authenticates with your private API and then exposes an unauthenticated, public-facing endpoint that Shields.io can consume. This keeps your credentials secure on your server.

// Example Node.js proxy service (simplified)
const express = require('express');
const axios = require('axios');
const app = express();
const PORT = process.env.PORT || 3000;

// Load sensitive API key from environment variables
const PRIVATE_API_KEY = process.env.PRIVATE_API_KEY;
const PRIVATE_API_URL = 'https://api.example.com/v1/status';

app.get('/badge-data', async (req, res) => {
  try {
    const response = await axios.get(PRIVATE_API_URL, {
      headers: {
        'Authorization': `Bearer ${PRIVATE_API_KEY}` // Securely use API key
      }
    });
    const status = response.data.data.status;
    res.json({
      schemaVersion: 1,
      label: 'Project Status',
      message: status,
      color: status === 'active' ? 'green' : 'red'
    });
  } catch (error) {
    console.error('Error fetching data:', error.message);
    res.status(500).json({ error: 'Failed to fetch data' });
  }
});

app.listen(PORT, () => {
  console.log(`Proxy server listening on port ${PORT}`);
});

Then, your Shields.io dynamic badge URL would point to your proxy:

https://img.shields.io/badge/dynamic/json?url=https://your-proxy.example.com/badge-data&query=$.message&label=Project%20Status&color=$.color

This method prevents direct exposure of your PRIVATE_API_KEY.

Security best practices

When using Shields.io with private data sources, adhering to security best practices is crucial to prevent credential exposure and unauthorized access:

  1. Avoid URL-Encoded Credentials for Sensitive Data: Directly embedding API keys or sensitive tokens in a URL parameter is highly discouraged for production environments, especially for critical systems. URLs can be:

    • Logged by web servers, proxies, and load balancers.
    • Stored in browser history, bookmarks, and referrer headers.
    • Visible in developer tools and network inspector.

    If you must use this method for non-sensitive data or temporary testing, regenerate the key frequently and restrict its permissions.

  2. Use a Server-Side Proxy: The most secure and recommended approach for dynamic badges requiring authentication is to implement an intermediate server-side proxy. This proxy service would:

    • Store and manage sensitive credentials securely (e.g., in environment variables, secret managers like AWS Secrets Manager, or Google Secret Manager).
    • Handle the actual authentication with the upstream private API (e.g., obtaining OAuth tokens, adding API key headers).
    • Fetch the required data, format it as needed (often as JSON), and expose a simple, unauthenticated endpoint that Shields.io can query.
    • Implement caching to reduce load on the upstream API and improve badge response times.

    This way, Shields.io only interacts with your trusted proxy, and your sensitive credentials never leave your controlled environment. Many cloud providers offer services for deploying simple functions or microservices that can act as such proxies, like Google Cloud Functions or AWS Lambda.

  3. Implement Least Privilege: When generating API keys or tokens for upstream services, grant them only the minimum necessary permissions required to retrieve the specific data for your badge. Avoid giving broad administrative access.

  4. Regularly Rotate Credentials: Periodically rotate any API keys, tokens, or passwords used by your proxy service to access private APIs. This limits the window of exposure if a credential is ever compromised.

  5. Use HTTPS Everywhere: Ensure all communication, from Shields.io to your proxy, and from your proxy to the upstream API, occurs over HTTPS to encrypt data in transit and prevent eavesdropping. Shields.io itself serves badges over HTTPS as indicated on its homepage.

  6. Monitor Access Logs: If you operate a proxy, regularly review its access logs for unusual activity, failed authentication attempts, or excessive requests that might indicate an attack or misconfiguration.