Skip to content

feat: Opt-in API.HTTPAuthSecrets for securing Kubo RPC #10187

@lidel

Description

@lidel

TLDR

We need to provide an HTTP-based solution for #1532 due to the needs from Brave,
which uses Kubo for their embedded IPFS node feature.

For Brave specifically:

  • Short term, they will remove other extension's ability to see Authorization header and modify Origin to work-around CORS.
  • Long term, we want Brave to be able to give limited access to IPFS node in a way that creates scoped IPNS keys / MFS sandbox per app.

cc @autonome @meandavejustice @darobin @cypt4 @vadims fysa
cc brave/brave-browser#34000

Why we need this

  • Brave
    • Currently, access to Kubo RPC is based on CORS safelist defined in API.HTTPHeaders.
    • This is not enough for future features Brave is planning to build on top of IPFS and IPNS, as other webextension could use blocking webRequest API for adjusting Origin header to bypass that.
  • Securing IPFS Desktop (similar reasons)
  • Future: securing docker images and binaries by default, reducing risk related to exposing port 5001 to the internet due to misconfiguration.

Initial design proposal

Add opt-in access control for Kubo RPC port based on HTTP Authorization HTTP header.

  • API.HTTPAuthSecrets (type optionalString or map[string]string)
    • If a value is defined and is other than an empty string, then requests to /api/v0 are rejected with HTTP 403 Forbidden unless they include Authorization HTTP header with the provided value.
    • Value must be an US-ASCII string compatible with rfc9110 with whitespace characters trimmed – we check this during node start, and error if not passing.
    • Secret values should be sanitized the same way we sanitize Identity.PrivKey (it is not sent over wire, not output by ipfs config show etc)

Open questions

  • What should be the UX? There are use-cases beyond Brave, we should support basic auth too. How do we allow use of different authg types?

    • Idea: make values of HTTPAuthSecretsfollow format type:value
      • If the string starts with basic: and has two : then we parse it as basic:user:password, and expect Authorization: Basic <base64("user:password")>
      • If the string starts with bearer:, expect an opaque bearer token sent as Authorization: Bearer <secret-token>
      • If value is something else, ignore it (but we can add other types in the future).
      • The benefit here is the type:value format can be reused in other places, like window.localStorage in webui.
      • The downside is that we may need to have other flags, like "access scope" to decide if app has admin access to all RPCs vs only small subset for onboarding data into CIDs and publishing CID to IPNS. Could be we just need a proper struct herewith Flag and optionalString – something similar to what we do in Gateway.PublicGateways
  • If we plan to have app-scoped data spaces, we may need a map of strings (map[string]string) instead of a single optionalString.

    • This is preferable, as it will enable us to have app names attached to tokens, and then have separate MFS and IPNS keys available only to each app and not others.
  • ipfs --api CLI needs to be extended by adding optional --api-secret that takes the values

  • We need to figure out how webui can load in Brave when the token is set

    • Idea 1: make ipfs-webui check window.localStorage key for auth value, and use it if present
      • Execution A: Brave could make sure the localStorage value is present at https://127.0.0.1:485001 and chrome-extension://companion-id Origins, so things "just work" without user's involvement
      • Execution B: The button at brave://internal-ipfs could have #auth:<auth-type>:<secret-value> attached, and webui could consume it and save it in localstorage to send with all RPC requests

Metadata

Metadata

Assignees

Labels

P1High: Likely tackled by core team if no one steps updif/hardeffort/weeksEstimated to take multiple weeksexp/expertHaving worked on the specific codebase is importantkind/enhancementA net-new feature or improvement to an existing feature

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions