Unverified Commit 5bf5a53c authored by Hong Minhee's avatar Hong Minhee
Browse files

Instrument `verifyRequest()`

parent 84ec4c36
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@
    "hongminhee",
    "hono",
    "httpsig",
    "httpsignatures",
    "hugoalh",
    "icojs",
    "instanceof",
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ To be released.
     -  Added `LookupWebFingerOptions.tracerProvider` option.
     -  Added `LookupObjectOptions.tracerProvider` option.
     -  Added `GetActorHandleOptions.tracerProvider` option.
     -  Added `VerifyRequestOptions.tracerProvider` option.

 -  Added `@fedify/fedify/x/sveltekit` module for integrating with [SvelteKit]
    hook.  [[#171], [#183] by Jiyu Park]
+35 −27
Original line number Diff line number Diff line
@@ -117,27 +117,30 @@ Instrumented spans
Fedify automatically instruments the following operations with OpenTelemetry
spans:

| Operation            | Span type | Description                           |
|----------------------|-----------|---------------------------------------|
| Operation            | [Span kind] | Description                           |
|----------------------|-------------|---------------------------------------|
| `Federation.fetch()` | Server      | Serves the incoming HTTP request.     |
| `lookupObject()`     | Client      | Looks up the Activity Streams object. |
| `getActorHandle()`   | Client      | Resolves the actor handle.            |
| `lookupWebFinger()`  | Client      | Looks up the WebFinger resource.      |
| `handleWebFinger()`  | Server      | Handles the WebFinger request.        |
| `verifyRequest()`    | Internal    | Verifies the HTTP request signature.  |

More operations will be instrumented in the future releases.

[Span kind]: https://opentelemetry.io/docs/specs/otel/trace/api/#spankind

Semantic attributes for ActivityPub
-----------------------------------

Semantic [attributes] for ActivityPub
-------------------------------------

The [OpenTelemetry Semantic Conventions] currently do not have a specification
for ActivityPub as of November 2024.  However, Fedify provides a set of semantic
attributes for ActivityPub.  The following table shows the semantic attributes
[attributes] for ActivityPub.  The following table shows the semantic attributes
for ActivityPub:

| Attribute                           | Type     | Description                                                                              | Example                                                              |
|----------------------------------|----------|---------------------------------------------------------------------------------|----------------------------------------------------|
|-------------------------------------|----------|------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| `activitypub.activity.id`           | string   | The URI of the activity object.                                                          | `"https://example.com/activity/1"`                                   |
| `activitypub.activity.type`         | string[] | The qualified URI(s) of the activity type(s).                                            | `["https://www.w3.org/ns/activitystreams#Create"]`                   |
| `activitypub.activity.to`           | string[] | The URI(s) of the recipient collections/actors of the activity.                          | `["https://example.com/1/followers/2"]`                              |
@@ -150,7 +153,12 @@ for ActivityPub:
| `activitypub.object.in_reply_to`    | string[] | The URI(s) of the original object to which the object reply.                             | `["https://example.com/object/1"]`                                   |
| `activitypub.inboxes`               | int      | The number of inboxes the activity is sent to.                                           | `12`                                                                 |
| `activitypub.shared_inbox`          | boolean  | Whether the activity is sent to the shared inbox.                                        | `true`                                                               |
| `httpsignatures.signature`          | string   | The signature of the HTTP request in hexadecimal.                                        | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` |
| `httpsignatures.algorithm`          | string   | The algorithm of the HTTP request signature.                                             | `"rsa-sha256"`                                                       |
| `httpsignatures.key_id`             | string   | The public key ID of the HTTP request signature.                                         | `"https://example.com/actor/1#main-key"`                             |
| `httpsignatures.digest.{algorithm}` | string   | The digest of the HTTP request body in hexadecimal.  The `{algorithm}` is the digest algorithm (e.g., `sha`, `sha-256`). | `"d41d8cd98f00b204e9800998ecf8427e"` |
| `webfinger.resource`                | string   | The queried resource URI.                                                                | `"acct:fedify@hollo.social"`                                         |
| `webfinger.resource.scheme`         | string   | The scheme of the queried resource URI.                                                  | `"acct"`                                                             |

[attributes]: https://opentelemetry.io/docs/specs/otel/common/#attribute
[OpenTelemetry Semantic Conventions]: https://opentelemetry.io/docs/specs/semconv/
+4 −0
Original line number Diff line number Diff line
import { getLogger } from "@logtape/logtape";
import type { TracerProvider } from "@opentelemetry/api";
import { accepts } from "@std/http/negotiation";
import type { DocumentLoader } from "../runtime/docloader.ts";
import { verifyRequest } from "../sig/http.ts";
@@ -359,6 +360,7 @@ export interface InboxHandlerParameters<TContextData> {
  onNotFound(request: Request): Response | Promise<Response>;
  signatureTimeWindow: Temporal.Duration | Temporal.DurationLike | false;
  skipSignatureVerification: boolean;
  tracerProvider?: TracerProvider;
}

export async function handleInbox<TContextData>(
@@ -376,6 +378,7 @@ export async function handleInbox<TContextData>(
    onNotFound,
    signatureTimeWindow,
    skipSignatureVerification,
    tracerProvider,
  }: InboxHandlerParameters<TContextData>,
): Promise<Response> {
  const logger = getLogger(["fedify", "federation", "inbox"]);
@@ -513,6 +516,7 @@ export async function handleInbox<TContextData>(
        documentLoader: context.documentLoader,
        timeWindow: signatureTimeWindow,
        keyCache,
        tracerProvider,
      });
      if (key == null) {
        logger.error(
+2 −0
Original line number Diff line number Diff line
@@ -2075,6 +2075,7 @@ export class FederationImpl<TContextData> implements Federation<TContextData> {
          onNotFound,
          signatureTimeWindow: this.signatureTimeWindow,
          skipSignatureVerification: this.skipSignatureVerification,
          tracerProvider: this.tracerProvider,
        });
      case "following":
        return await handleCollection(request, {
@@ -2892,6 +2893,7 @@ class RequestContextImpl<TContextData> extends ContextImpl<TContextData>
    return this.#signedKey = await verifyRequest(this.request, {
      ...this,
      timeWindow: this.federation.signatureTimeWindow,
      tracerProvider: this.federation.tracerProvider,
    });
  }

Loading