Identity & Auth

Happen provides the minimal, essential tools that enable developers to build their own identity models. Here's what that looks like:

1. Node Identity

Every node in Happen possesses a unique identity established at creation:

const orderNode = createNode('order-service');

This creates a node with a cryptographic identity that:

  • Is established automatically at node creation

  • Is used to verify the origin of events

  • Remains consistent throughout the node's lifecycle

  • Can be referenced by other nodes

Node identity is foundational to Happen's event flow, enabling verifiable communication between components without requiring elaborate identity infrastructure.

2. Origin Context

Events in Happen carry origin information in their context, providing a clear record of where events came from:

{
  type: "order-created",
  payload: {
    // Domain-specific data
    orderId: "order-123",
    items: [/* items data */]
  },
  context: {
    causal: {
      id: "evt-789",
      sender: "checkout-node",
      causationId: "evt-456",
      correlationId: "txn-123"
    },
    origin: {
      nodeId: "checkout-node",      // The immediate sender node (added automatically)
      sourceId: "user-456",         // Original source (optional, application-provided)
      sourceType: "user"            // Type of source (optional)
    }
  }
}

The origin context provides:

  • nodeId: The node that immediately sent the event (added automatically)

  • sourceId: The original source identity (e.g., user ID, service ID)

  • sourceType: The type of source (e.g., "user", "system", "service")

This minimal but powerful primitive allows events to carry essential identity information without prescribing how that information should be structured or used.

3. Acceptance Controls

Nodes can specify which origins they're willing to accept events from:

const paymentNode = createNode("payment-service", {
  acceptFrom: [
    "checkout-node",     // Accept from specific node
    "user:admin",        // Accept from specific user type/role
    "order-*"            // Accept from nodes matching pattern
  ]
});

This declarative approach provides a simple way to control event flow based on origin, without requiring complex configuration or policy engines.

How Happen Enables Identity Models

By providing these blocks rather than a complete identity system, Happen enables developers to:

Build Custom Identity Models

// Example: Multi-tenant identity model
function createTenantNode(tenantId, nodeId) {
  return createNode(nodeId, {
    // Only accept events from the same tenant
    acceptFrom: [`tenant:${tenantId}:*`]
  });
}

// When sending events, include tenant context
sourceNode.send(targetNode, {
  type: "process-data",
  payload: {/* data */},
  context: {
    origin: {
      sourceId: `tenant:${tenantId}:user-123`,
      sourceType: "user"
    }
  }
});

Create Domain-Specific Authorization

// Custom authorization using the Event Continuum
orderNode.on("update-order", (event, context) => {
  // Extract origin information
  const { sourceId, sourceType } = event.context.origin;
  
  // Get the order
  const order = getOrder(event.payload.orderId);
  
  // Check if the source has permission to update this order
  if (sourceType === "user" && order.customerId !== sourceId) {
    return {
      success: false,
      reason: "unauthorized",
      message: "Users can only update their own orders"
    };
  }
  
  // Continue with authorized flow
  return processOrderUpdate;
});

Implement Delegation Patterns

// Forward events while preserving original source
apiNode.on("create-order", (event, context) => {
  // Preserve the original source when forwarding
  return apiNode.send(orderNode, {
    type: "process-order",
    payload: event.payload,
    context: {
      origin: {
        // Keep original source information
        sourceId: event.context.origin.sourceId,
        sourceType: event.context.origin.sourceType
      }
    }
  });
});

Embracing Causality

The identity system in Happen is designed to work seamlessly with its causal model:

  • Each event naturally references its sender node

  • The causal chain provides a complete history of who did what

  • Origin information flows through event chains

  • The combination creates a natural audit trail

This integration means that identity becomes an inherent property of the event flow rather than a separate concern requiring special handling.

The Power of Minimalism

By providing just the essential identity apparatus, Happen enables:

  1. Simple Identity Tracking: Basic origin tracking with zero configuration

  2. Powerful Custom Models: Build sophisticated identity systems when needed

  3. Domain-Specific Authorization: Implement authorization that matches your domain

  4. Clean Mental Model: Identity as a natural property of events

Last updated