What is the principle of least privilege?

4 minintermediatesecurityleast-privilegeauthorization

Quick Answer

The principle of least privilege grants every user, service, process, and credential only the minimum permissions needed to do its job — and nothing more. It limits the blast radius of compromised accounts or bugs. Apply it with role/policy-based authorization, scoped tokens, least-privileged database and cloud IAM accounts, and short-lived credentials, reviewing and revoking access regularly.

Detailed Answer

Principle of Least Privilege means granting users, processes, or systems only the minimum permissions necessary to perform their functions.

Implementation in .NET Core:

  1. Role-Based Access Control:
// Define roles in Startup.cs
services.AddAuthorization(options =>
{
    options.AddPolicy("AdminOnly", policy => 
        policy.RequireRole("Administrator"));
    options.AddPolicy("UserOrAdmin", policy => 
        policy.RequireRole("User", "Administrator"));
});

// Use in controllers
[Authorize(Roles = "Administrator")]
public class AdminController : Controller
{
    // Only administrators can access
}

[Authorize(Policy = "AdminOnly")]
public IActionResult DeleteUser(int id)
{
    // Sensitive operation
}
  1. Claims-Based Authorization:
services.AddAuthorization(options =>
{
    options.AddPolicy("CanEditDocuments", policy =>
        policy.RequireClaim("Permission", "Document.Edit"));
    
    options.AddPolicy("SeniorEmployees", policy =>
        policy.RequireAssertion(context =>
            context.User.HasClaim(c => c.Type == "EmployeeLevel" 
                && int.Parse(c.Value) >= 5)));
});

[Authorize(Policy = "CanEditDocuments")]
public IActionResult EditDocument(int id)
{
    // Only users with Document.Edit claim
}
  1. Resource-Based Authorization:
public class DocumentAuthorizationHandler : 
    AuthorizationHandler
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        OperationAuthorizationRequirement requirement,
        Document resource)
    {
        if (resource.OwnerId == context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value)
        {
            context.Succeed(requirement);
        }
        
        return Task.CompletedTask;
    }
}

// Usage in controller
public class DocumentController : Controller
{
    private readonly IAuthorizationService _authorizationService;
    
    public async Task Edit(int id)
    {
        var document = await _repository.GetAsync(id);
        var authResult = await _authorizationService.AuthorizeAsync(
            User, document, "EditPolicy");
            
        if (!authResult.Succeeded)
            return Forbid();
            
        return View(document);
    }
}
  1. Database-Level Permissions:
// Connection string with limited permissions
"Server=myserver;Database=mydb;User Id=app_user;Password=***;"

// User 'app_user' should only have:
// - SELECT, INSERT, UPDATE on specific tables
// - EXECUTE on specific stored procedures
// - NO DROP, ALTER, or admin privileges
  1. API Key Scoping:
public class ApiKeyAuthorizationHandler : AuthorizationHandler
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        ApiKeyRequirement requirement)
    {
        var apiKey = context.User.FindFirst("ApiKey")?.Value;
        var scopes = GetApiKeyScopes(apiKey);
        
        if (scopes.Contains(requirement.RequiredScope))
        {
            context.Succeed(requirement);
        }
        
        return Task.CompletedTask;
    }
}