Closed dpc closed 3 weeks ago
> error[E0599]: no method named `set_headers` found for struct `WasmClientBuilder` in the current scope
> --> fedimint-api-client/src/api.rs:1350:29
> |
> 1350 | client = client.set_headers(headers);
> | ^^^^^^^^^^^ method not found in `WasmClientBuilder`
Damn it wasm, why?
I think I can workaround it by just modifying the URL, which the underlying browser should translate to the same thing. Will look into it when I can.
ACK concept
(EDIT: I didn't read fully)
I think I can workaround it by just modifying the URL, which the underlying browser should translate to the same thing.
AFAICT this should work, but I don't have a good way to test it RN.
Each
fedimintd
can optionally set one mainapi_secret
, and multipleapi_extra_secrets
Why not just one list of secrets?
Invite codes now carry a new field that contains the secret.
Is that a good idea? I think it's better if the secret has to be communicated out of band, otherwise users might be surprised when it gets rotated. When entering the password apps can warn users of the risk of being locked out if they don't know someone in the inner circle.
Is that a good idea? I think it's better if the secret has to be communicated out of band, otherwise users might be surprised when it gets rotated.
Prevents nothing, UX suffers.
How do we communicate to the user/integrator when auth fails and needs to be renewed?
In case of bad auth the requests return 401 error code. It comes down to error handling and how to structure it to bubble up all the way to end app ux.
But I'd worry about in a follow-up. The whole thing will need some end user app integration (like in Fedi) to figure out all the details and UX.
Rebased.
@elsirion If there is not fundamental dissagrement about the idea, can we land it? This change is merge conflict magnet.
Things to argue about that we can still change:
Things I think need to change anyway:
DEFAULT_API_SECRET...
and FORCE_API_...
env vars. Just like we now do bitcoind rpc. This way it's possible to manage secrets via DB, but still allow (via FORCE) to ignore/overwrite the DB value in tests and setups that don't rely on UI so much. Ping @Kodylow on the opinion. This will probably require UX work and new core APIs, etc. but it can be done down the road.Should probably also migrate admin auth to this scheme. Could use
guardian:<secret>
to distinguish.
Just posted a comment about it in https://github.com/fedimint/fedimint/issues/2420#issuecomment-2128772984 . It's harder to get done, so I think I'll just ignore it for now. @elsirion
Motivation
Running public federation has multiple risk, some of which are related to the sheer amount of usage it might bring.
As mints are perfectly private, there is no way to tell the users apart and control the usage.
However the mint can agree on a shared secret and circulate it among the intended users. Imagine a handful of families or a small community running federation for themselves and their friends.
The users and the guardians semi-know and trust each other, and would like to avoid strangers using their federation, even if just to limit resource usage. They would like to keep thing private between themselves though.
The scheme is as follows: guardians agree on a shared api secret. Api secret is enforced on HTTP level. From the outside perspective, public Federation endpoints appear as just inaccessible HTTP servers, and there's little to no sign that they are running Fedimint.
Guardian share the secret with intended users. Users can share it further if they want - there is no way for guardians to control it. But the expectation is that the users will have an incentive to keep it private.
On top if - guardians at any time (possibly periodically) can rotate the secret. E.g. if they detect unusally high activity, they can generate a new secret, circulate it with intended users again and thus shut-off the access for the non-intended users.
If the abuse persist, they can even rotate the secret and have the users get the secret one by one to reclaim their money, ultimately confiscating funds of people that were not supposed to be used.
Just this possibility alone should scare off strangers using private Federations.
Note: this does not ruin privacy of the intended users.
Technical details
Secret are enforced on HTTP level using Basic http authorization scheme.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization#basic
This makes private mints look mostly like normal http servers. Similiar mechanism can be done using Nginx config, but having it inside
fedimintd
allows better integration with Invite Codes, testing, etc.While working on it it occured to me that I wish it was possible to authenticate guardian APIs on the HTTP level as well, but it seems that currently there's no way to pass any data from jsonrpsee http middleware to the jsonrpc middleware.
Each
fedimintd
can optionally set one mainapi_secret
, and multipleapi_extra_secrets
. The extra secrets are intended for phasing out secrets and allowing users who did not receive the new secret yet, to continue using the existing one.Invite codes now carry a new field that contains the secret.
OOB Notes carry the api secret as well. It's unclear if not doing it would be a better idea. Then sending OOB would not consist being an invitation.
After joining private federation
Client
stores theapi_secret
from the invitation in the database, just like the config. In the future we can add cli and methods to update it, e.g. when receiving newer invitiation. This will allow end-user app integrators to e.g. update secret by re-invitation.The changes are mostly simple, but touch a lot of places, as the
api_secret
needs to be passed from the the cli options all the way to api handlers and clients.Testing
will make everything (both fedimintd and fedimint-cli and other clients) use the api secret.
If you find in the logs api addresses used by one of the peers you can check that public access is not allowed with: