Forge Event Hooks should be signed

Forge webhooks aren’t signed.

If someone was able to forge a FIT somehow and hit an application endpoint with a malicious body, there’s no way on the application side to reject the forged body.

Proposal:

  1. Atlassian creates a public-private keypair and publishes the public key
  2. Atlassian signs all outgoing hooks with the private key incorporating the body, target URI path, and the FIT
  3. Atlassian adds this signature as X-Atlassian-Signature
  4. Atlassian includes tools to verify this signature in all forge backend SDKs

This way, even if someone somehow manages to compromise the FIT, they would need to compromise the secret private key as well in order to craft malicious application event hooks.

This approach is also backwards-compatible with existing forge apps - they didn’t validate signatures then, and until they update they won’t validate signatures.

The only wrinkle I can think of is how Atlassian rotates keys - it might be worthwhile to set an expiration and a 6-month rollover period for rotation, dropping warnings in the last 3 months and errors in the last month.

I generally agree with this, but I’d like to pose two questions:

FITs are cryptographically signed by Atlassian. So isn’t a stolen or leaked FIT a more likely threat than a forged FIT? I believe that distinction matters, because we as developers can do more to guard against stolen/leaked tokens than forged tokens.

I agree that the payload should be cryptographically bound to the invocation. That would be a meaningful security enhancement. However, I’m curious why this would require a second signature. Couldn’t Atlassian just add more claims to the existing FIT (target path, SHA-256 digest, etc.)?