Skip to content

Platform: Meter ingest Lambda + trust boundary (#13) #80

Description

@I-am-nothing

Summary

Platform-side infrastructure required for the meter package shipped in SDK issue #13. The SDK async-invokes a platform-owned Lambda with usage events; the platform must deploy the Lambda, enforce the trust boundary, and pick a storage backend.

What the SDK expects (from merged PR #78)

Security-critical (hard requirements)

  1. Meter Lambda function — accepts `meter.Event` JSON, reads invoker identity, writes to storage.

  2. IAM scoping — module's Lambda execution role gets `lambda:InvokeFunction` on the exact meter ARN only, never `*`. A rogue module must not be able to enumerate/invoke sibling modules' meter ARNs.

  3. Invoker identity verification — the meter Lambda MUST read `context.FunctionArn` (or `context.InvokedFunctionArn`) from the AWS invocation context and cross-check it against a platform-owned `(invoker_arn → authorized_app_ids)` mapping. The payload's `appIdHint`, `moduleIdHint`, `recordedAtHint` are hints, never trusted for billing attribution.

  4. EventID dedup — persist `eventId` in a short-TTL store (24-72h) to reject Lambda async retries. ReceipientId replay = double billing.

  5. Timestamp authority — replace `recordedAtHint` with server receive time. MUST reject events where `recordedAtHint` is >60 seconds off receive time (backdating would corrupt billing period attribution).

  6. Deploy ordering — `(invoker_arn → app_ids)` mapping MUST be updated and propagated BEFORE the module's new ARN goes live. Reverse ordering drops the first N events silently.

  7. Staging discipline — prod meter ARN MUST NOT be reachable from staging modules. Defense-in-depth: the prod meter Lambda should reject invocations where `context.InvokedFunctionArn`'s account ID is not in an environment-tagged allowlist.

Storage choice (platform decision)

  • Partition/sort key: `(module_id, metric, recorded_at)` where `recorded_at` is server-assigned. `EventID` is dedup-only, NOT primary key (UUID-random → write amplification).
  • Retention split:
    • Dedup window: 24-72h, short-TTL store (Redis / DynamoDB TTL)
    • Billing events: 7 years minimum (tax/audit). Cold tier OK — ClickHouse + S3, Timestream magnetic store, or Parquet in S3 + Athena. Different data store from dedup.
  • Fraud detection: platform-side rate limiting + anomaly bounds on value ranges. Out of SDK scope.

Operational

  • Monitoring: per-module event rate, dedup hit rate, reject rate (stale timestamps, unknown ARNs)
  • DLQ for malformed payloads
  • Developer-visible billing dashboard

Files / systems affected

  • New Lambda function (platform repo)
  • IAM policy templates
  • Platform-owned billing DB schema + ingest code
  • Invoker→app mapping service
  • Platform deployment automation (staging discipline enforcement)

Blocking

  • Billing v1 cannot go live without this. The SDK is ready; the ingest side is not.

Origin

Documented in PR #78 description + `/Users/owo/.claude/plans/functional-waddling-planet.md`; never filed as a trackable platform issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions