Skip to content

MCP Iteration 2: shared principal, API keys and scoped authorization #83

Description

@patoperpetua

Parent: #81
Depends on: #82

Goal

Replace the Iteration 1 PoC credential check with a reusable authentication/authorization layer that works consistently across REST and MCP.

Core model

Introduce a transport-independent principal, for example:

interface Principal {
  id: string;
  tenantId?: string;
  authType: 'api-key' | 'entra';
  scopes: string[];
}

Exact naming should follow repository conventions.

Scope

  • Create a shared authentication package/module used by REST and MCP.
  • Support PostKit-issued API keys for internal/PoC machine access.
  • Store only a secure hash of API keys; never persist the plaintext key after creation.
  • Support revocation and optional expiry.
  • Bind credentials to a tenant where appropriate.
  • Enforce explicit permissions/scopes at the application boundary.
  • Make authorization independent of whether the request came from REST or MCP.

Initial permissions

Use a small semantic permission set such as:

  • templates:read
  • templates:validate
  • templates:preview
  • email:send (defined but not necessarily enabled through MCP yet)

Avoid permissions tied to specific transport routes.

Security rules

  • Tenant ID supplied in tool/API input must never override the authenticated principal's tenant authorization.
  • Reject credentials without the required permission.
  • Never log raw API keys.
  • Provide a clear path to replace/augment API-key authentication with Microsoft Entra ID in Iteration 3.

Acceptance criteria

  • REST and MCP can obtain the same Principal abstraction.
  • MCP tools enforce permissions centrally rather than individually implementing ad-hoc checks.
  • API keys can be created/provisioned, authenticated, expired and revoked.
  • A tenant-bound credential cannot read or preview another tenant's templates.
  • Permission failures return consistent, non-sensitive errors.
  • Tests cover invalid credentials, revoked credentials, missing scopes and tenant boundary violations.

Out of scope

  • Full Microsoft Entra ID OAuth/OIDC integration.
  • Interactive consent flows.
  • Public third-party MCP clients.
  • MCP email sending.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions