simonw / datasette-publish-fly

Datasette plugin for publishing data using Fly
Apache License 2.0
20 stars 7 forks source link

`--plugin-secret` should use Fly secrets #14

Closed simonw closed 2 years ago

simonw commented 2 years ago

In writing the documentation for the new volumes stuff - https://github.com/simonw/datasette-publish-fly/issues/12#issuecomment-1033143443_ (also refs #10) - I realized that if I'm going to show people how to use volumes I need them to deploy writable plugins. But if I show them that, it's not responsible to show them how to do it without authentication. So I should include datasette-auth-passwords - but that requires them to set a password secret using --plugin-secret...

... and I don't want them to have to set the same plugin secret every time they run a deploy to update an existing instance!

So, instead, I'm going to see if I can get --plugin-secret to set a Fly secret, which will persist for the lifetime of the application across multiple deploys.

simonw commented 2 years ago

Current implementation bakes the secrets into the Dockerfile: https://github.com/simonw/datasette-publish-fly/blob/a265963be1abe898b9457db74a41db381f514b55/datasette_publish_fly/__init__.py#L85-L96

Here's info on Fly secrets: https://fly.io/docs/reference/secrets/

Short version:

flyctl secrets set MY_SECRET=value -a name-of-app

You can set multiple secrets in a single call.

simonw commented 2 years ago

Problem: we can persist the environment variable secrets in between deployments, but we don't have a mechanism for persisting the metadata.json we have constructed, which needs to include this bit:

{
    "plugins": {
        "datasette-auth-passwords": {
            "root_password_hash": {
                "$env": "ROOT_PASSWORD_HASH"
            }
        }
    }
}
simonw commented 2 years ago

Once again I find myself wanting a reliable way to introspect the deployed application.

I discussed some options in https://github.com/simonw/datasette-publish-fly/pull/12#issuecomment-1031971831

  • Hit the /-/databases.json JSON API - problem here is that it might be protected by authentication or not yet available if the app hasn't been fully deployed
  • Stash a Fly secret with a list of database names, then read that again next time I deploy. This doesn't work because secret values aren't available to flyctl secrets list - you only get back the digest.
  • Stashing the list of databases in a tag or annotation - but it turns out Fly doesn't provide application or volume tags or annotations

Another option might be the fly ssh command - https://fly.io/docs/flyctl/ssh/ - but that's more designed for issuing SSH credentials and doesn't seem to have a neat equivalent of heroku run ... that could be easily scripted to run a command inside the application.

Two options then:

  1. Tell the user they have to call --plugin-secret on subsequent deploys
  2. Only allow deploys if the application itself can be reached via HTTP, and introspect it that way

I'm going to go with option 1 since it's simpler.