Dealer-Specific Access Control

Dealer-Specific Access Control

Overview

AutoElite's API implements dealer-specific access control to ensure that each dealer can only access and modify their own data. This document explains how this feature works and how to implement it in your applications.

How It Works

When an API key is associated with a specific dealer, the AutoElite API automatically enforces access control rules:

  1. Data Filtering: All queries are automatically filtered to only return data belonging to the associated dealer
  2. Access Prevention: Attempts to access data from other dealers are rejected
  3. Automatic Assignment: New data is automatically assigned to the correct dealer
  4. Modification Restrictions: Updates and deletions are restricted to data owned by the dealer

This happens transparently to the client application, requiring no changes to your API calls.

Implementation Details

API Key Association

API keys are associated with dealers through the dealer_api_keys table:

CREATE TABLE dealer_api_keys (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  dealer_id INTEGER NOT NULL,
  api_key_id INTEGER NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (dealer_id) REFERENCES dealers(id) ON DELETE CASCADE,
  FOREIGN KEY (api_key_id) REFERENCES api_keys(id) ON DELETE CASCADE,
  UNIQUE(dealer_id, api_key_id)
);

Middleware Processing

The dealer access control is implemented as middleware that:

  1. Checks if the API key is associated with a dealer
  2. Modifies requests to include dealer filtering
  3. Validates access to specific resources

Endpoint Behavior

GET /api/vehicles

Without Dealer Association:

  • Returns all vehicles in the system
  • No automatic filtering

With Dealer Association:

  • Automatically adds dealer_id filter
  • Only returns vehicles belonging to the associated dealer
  • Example: /api/vehicles becomes /api/vehicles?dealer_id=123

GET /api/vehicles/:id

Without Dealer Association:

  • Can access any vehicle by ID

With Dealer Association:

  • Can only access vehicles belonging to the associated dealer
  • Returns 403 Forbidden if attempting to access a vehicle from another dealer

POST /api/vehicles

Without Dealer Association:

  • Can create vehicles for any dealer
  • Must specify dealer_id in the request body

With Dealer Association:

  • Automatically sets dealer_id to the associated dealer
  • Overrides any dealer_id provided in the request body
  • Ensures all created vehicles belong to the correct dealer

PUT /api/vehicles/:id

Without Dealer Association:

  • Can update any vehicle
  • Can change dealer_id to reassign vehicles

With Dealer Association:

  • Can only update vehicles belonging to the associated dealer
  • Cannot change dealer_id to a different dealer
  • Returns 403 Forbidden if attempting to update a vehicle from another dealer

DELETE /api/vehicles/:id

Without Dealer Association:

  • Can delete any vehicle

With Dealer Association:

  • Can only delete vehicles belonging to the associated dealer
  • Returns 403 Forbidden if attempting to delete a vehicle from another dealer

Client Implementation

The beauty of this system is that client applications don't need to implement any special logic. The same code works regardless of whether the API key is dealer-specific or not.

Example: Fetching Vehicles

// This code works the same for all API keys
const fetchVehicles = async () => {
  const response = await fetch('https://api.autoelite.io/api/vehicles', {
    headers: {
      'X-API-Key': 'your-api-key-here',
      'Content-Type': 'application/json'
    }
  });
  
  return await response.json();
};

If the API key is associated with dealer ID 123:

  • The server automatically filters results to only show vehicles with dealer_id = 123
  • The client receives only the vehicles it should have access to

Example: Creating a Vehicle

// This code works the same for all API keys
const createVehicle = async (vehicleData) => {
  const response = await fetch('https://api.autoelite.io/api/vehicles', {
    method: 'POST',
    headers: {
      'X-API-Key': 'your-api-key-here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(vehicleData)
  });
  
  return await response.json();
};

If the API key is associated with dealer ID 123:

  • The server automatically sets dealer_id = 123 in the vehicle data
  • The vehicle is correctly assigned to the dealer, even if the client doesn't specify a dealer_id

Benefits

Security

  • Prevents unauthorized access to other dealers' data
  • Eliminates the risk of data leakage between dealers
  • Enforces proper data ownership

Simplicity

  • No need to modify client code for different dealers
  • Same application works for all dealers
  • No need to manually filter data by dealer

Maintainability

  • Access control logic is centralized in the API
  • Changes to access control rules only need to be made in one place
  • Consistent enforcement across all endpoints

Testing Dealer-Specific Access

To verify that dealer-specific access control is working correctly:

  1. Create two API keys, each associated with a different dealer

  2. Use each API key to:

    • Fetch all vehicles
    • Attempt to access a vehicle belonging to the other dealer
    • Create a new vehicle
    • Update a vehicle
  3. Verify that:

    • Each API key only sees vehicles from its associated dealer
    • Attempts to access other dealers' vehicles are rejected
    • New vehicles are correctly assigned to the appropriate dealer

Error Responses

When dealer-specific access control prevents an operation, the API returns a 403 Forbidden response with an appropriate error message:

{
  "error": "Access denied: This vehicle does not belong to your dealer"
}

Limitations

  1. Super Admin Override: API keys with no dealer association (super admin keys) bypass dealer-specific access control
  2. Bulk Operations: Some bulk operations may have different behavior - check the specific endpoint documentation
  3. Performance Impact: The additional filtering may have a minor performance impact on some queries

Best Practices

  1. Use Dealer-Specific API Keys: For dealer-facing applications, always use API keys associated with the specific dealer
  2. Test Access Control: Verify that your application correctly handles 403 errors when attempting to access unauthorized resources
  3. Don't Rely on Client-Side Filtering: The API handles all necessary filtering, so don't duplicate this logic in your client
  4. Handle Errors Gracefully: Provide user-friendly error messages when access is denied