P
PUGUH

Resource Scoping

Understand how resources are scoped in ARSAKA PUGUH.

Scoping Model

PUGUH uses a two-level scoping model:

plaintext
Organization
  └── Application
       ├── Webhooks
       ├── Storage (Files)
       ├── API Keys
       └── Members

Scope Types

Organization-Scoped

Resources shared across all applications in the organization:

  • Users & Roles: Members belong to the organization
  • Billing & Subscriptions: One plan per organization
  • Audit Logs: Organization-wide event history
  • Settings: Organization preferences and policies
typescript
// List all members in the organization
const members = await client.organizations.listMembers(orgId);

// View organization-wide audit trail
const audit = await client.control.listAudit({ page: 1, limit: 50 });

Application-Scoped

Resources isolated within a specific application:

  • Webhooks: Each application has its own webhook endpoints
  • Storage: Files are isolated per application
  • API Keys: Generated per application for integration
  • Members: Users can be assigned to specific applications
typescript
// Create a webhook scoped to an application
const webhook = await client.webhooks.create({
  url: 'https://your-app.com/webhook',
  eventTypes: ['user.registered'],
  applicationId: 'app-uuid',
});

// List webhooks for a specific application
const webhooks = await client.webhooks.list({ applicationId: 'app-uuid' });

Resource Scoping Rules

ResourceScopeNotes
Users Organization Members belong to org, can be assigned to apps
Roles Organization Owner, Admin, Member, Viewer
Applications Organization Created within an organization
Webhooks Application Isolated per application
Storage Application Files isolated per application
API Keys Application One key per application
Audit Logs Both Filterable by application
Billing Organization One subscription per organization

Application Isolation

Applications provide resource isolation within an organization. This is useful for separating environments or teams:

plaintext
Organization: Acme Corp
  ├── Application: production
  │    ├── Webhooks → HTTPS only, strict validation
  │    ├── Storage  → encrypted, access controls
  │    └── API Key  → used in production servers
  ├── Application: staging
  │    ├── Webhooks → test endpoints
  │    ├── Storage  → relaxed limits
  │    └── API Key  → used in CI/CD
  └── Application: development
       ├── Webhooks → localhost allowed
       ├── Storage  → public access
       └── API Key  → used locally

Scope Inheritance

Users & Permissions

  • User permissions are inherited from their organization role
  • An Admin in the organization can manage all applications
  • Application-level member assignments restrict access further
  • Organization Owners have full access to everything

Webhooks

  • Webhooks are always application-scoped
  • Events from one application do not trigger webhooks in another
  • Each webhook has its own secret for signature verification

Audit Trail

  • All actions are logged at the organization level
  • Audit entries include application_id when applicable
  • Filter by application to see application-specific events

Configuration Patterns

Pattern 1: Environment Separation

Use applications to separate deployment environments:

typescript
// Create environment-specific applications
const prod = await client.applications.create({
  name: 'Production',
  slug: 'production',
});

const staging = await client.applications.create({
  name: 'Staging',
  slug: 'staging',
});

// Each gets its own webhooks, storage, and API keys
await client.webhooks.create({
  url: 'https://prod.example.com/webhook',
  applicationId: prod.id,
  eventTypes: ['user.registered', 'billing.payment_succeeded'],
});

Pattern 2: Team Isolation

Use applications to isolate resources between teams:

typescript
// Marketing team application
const marketing = await client.applications.create({
  name: 'Marketing Portal',
  slug: 'marketing',
});

// Engineering team application
const engineering = await client.applications.create({
  name: 'Engineering Tools',
  slug: 'engineering',
});

// Add team members to their respective applications
await client.applications.addMember(marketing.id, { userId: marketerId });
await client.applications.addMember(engineering.id, { userId: engineerId });

Pattern 3: Multi-Product

Use applications for different products under one organization:

typescript
// One organization, multiple products
const mobileApp = await client.applications.create({
  name: 'Mobile App',
  slug: 'mobile',
});

const webApp = await client.applications.create({
  name: 'Web Dashboard',
  slug: 'web',
});

// Each product has its own webhook integrations
await client.webhooks.create({
  url: 'https://mobile-api.example.com/events',
  applicationId: mobileApp.id,
  eventTypes: ['user.registered'],
});

Best Practices

1. Define Clear Scope Boundaries

Document what belongs at organization vs application level:

Resource TypeScopeReason
Team members Organization Company-wide identity
Webhooks Application Environment-specific endpoints
File storage Application Isolated per environment/product
Billing Organization Single subscription covers all apps

2. Use Descriptive Application Names

Name applications clearly so their purpose is obvious:

plaintext
Good: "Production API", "Staging", "Mobile App"
Bad:  "App 1", "Test", "New"

3. Audit Across Scopes

Regularly review activity at both levels:

typescript
// Organization-wide audit
const orgAudit = await client.control.listAudit({
  actions: ['user.role_changed', 'organization.settings_updated'],
});

// Application-specific audit
const appAudit = await client.control.listAudit({
  applicationId: 'app-uuid',
  actions: ['webhook.created', 'webhook.deleted'],
});

4. Manage Access Per Application

Restrict who can access each application:

  • Only add relevant team members to each application
  • Production applications should have fewer members
  • Development applications can be more permissive

Related