Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide self-hosting swagger UI/Redoc support #530

Closed
johnthagen opened this issue Sep 19, 2021 · 10 comments
Closed

Provide self-hosting swagger UI/Redoc support #530

johnthagen opened this issue Sep 19, 2021 · 10 comments
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending

Comments

@johnthagen
Copy link
Contributor

One of the convenient features that drf-yasg provided was self hosting swagger-ui and redoc automatically in the wheel. For deployments on networks that do not have internet access, this made it a non-issue to make the swagger UI work out of the box regardless of the client's network.

Could similar support by added to drf-spectacular? Perhaps as a separate PyPI package if it's not deemed appropriate for the main package?

It could be an extras in the install_requires, installed something like: pip install drf-spectacular[swagger-ui].

For prior art, a similar package in the FastAPI ecosystem is fastapi-offline.

@tfranzel
Copy link
Owner

tfranzel commented Sep 23, 2021

Hi @johnthagen,

so I did some research to weigh the options. I certainly do not want to ingest binary upstream builds into this repository, which I believe is bad form. For yasg, this is an manual process, which is why their builds are significantly outdated. Until now I was hesitant to open that can of worms and run into similar issues regarding staleness and maintenance overhead.

We had a similar ask in #389, but saying CDNs are not trustworthy is not really a valid argument imho. If someone is that mistrustful, then reviewing, building and self-hosting an approved version would be the only choice anyway (which we easily allow via settings). Given that fastapi-offline fetches from CDN, this would not provide anything more with respect to "security" anyway. However, we also had valid point in #457 where the redirect html needs to come from same origin due to CORS. At the time, it was not reason enough for me, since it was still possible to host that single file in the project's static folder.

I experienced myself that corporate requirements are real and internet access is not a given for every environment. Sure, you could again dump those js builds into the project's static folder but that does not scale very well. So to sum this up:

  • pypi does not support multiple builds, except for different platform wheels, which limits the available options
  • I don't want to have upstream binary builds in this repo
  • I'd prefer not having those builds in the main pypi package.

I currently envision a separate repo as an optional sidecar to this repo, very similar to how fastapi-offline is built. Ideally with a github action that updates the sidecar package. I will give this a try.

@johnthagen
Copy link
Contributor Author

@tfranzel Thank you for your thoughtful consideration. I agree with all of your sentiments about the trade-offs about bundling binaries into the wheel.

I currently envision a separate repo as an optional sidecar to this repo, very similar to how fastapi-offline is built. Ideally with a github action that updates the sidecar package. I will give this a try.

I think this would be an excellent addition to the drf-spectacular ecosystem if it works out. Thank you for your time trying it out.

@tfranzel
Copy link
Owner

the sidecar is here: https://github.com/tfranzel/drf-spectacular-sidecar

convenience methods and doc added with aeda969

@tfranzel tfranzel added enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending labels Sep 24, 2021
@johnthagen
Copy link
Contributor Author

@tfranzel This looks great! One small idea is that the drf-yasg porting section could link to this feature since users coming from that package might be expecting self hosting.

@valentijnscholten
Copy link

Although it's great to have the option to self-host the swaggerui and redoc, I'm not sure the sidecar really helps a lot with regards to security / CDN trust. The main reason I see corporates don't want external javascript from CDN is because CDNs can get hacked and serve modified/malicous javascript. The sidecar still takes the js code from the CDN without any checks. So it could result in the same problem. Chances are maybe smaller because users / downstream have to update the sidecard packages first. A point at which they "could" inspect the javascript code. I am wondering if the proper fix would be to use SRI to check the integrity of SwaggerUI? Or just bundle the javascript with the main builds which would be sourcing them from npm probably.

@johnthagen
Copy link
Contributor Author

@valentijnscholten As the reporter of this issue originally, I wanted to say for my particular use case it was not about security concerns of what is pulled from the CDN. It was strictly about the issue of running a drf-spectacular application on a network that has no internet connection.

So for me, the sidecar solution was sufficient. I think security concerns about the integrity of what is downloaded for sidecar should be opened on that repo.

@tfranzel
Copy link
Owner

tfranzel commented Oct 4, 2021

@johnthagen thanks for chiming in. I agree with you that this thing serves a particular use-case.

@valentijnscholten I'm by no means a security expert, but here are my 2 cents on the topic.

  • the SRI usually comes from the CDN's page, so at the end of the day you again solely trust them. This would only protect you from in-transit attacks. If the payload is already tainted, you gain very little like that. It only gives you more security if that SRI would be provided independently to you (by the project homepage or something).
  • drf-spectacular-sidecar does check the SRI (sha256 of the build) which it gets from the jsdelivr metadata endpoints.
  • CDNs implemented this as a one-way street. They pull packages from npm, build them and then publish, with "no" way of changing the build afterwards.
  • jsdelivr serves billions of requests per month, so it's safe to say a lot of people trust their judgement.

The same point was raised in #389. I believe if you are really serious about your security, you likely want to build from npm (or even github), validate/check/analyze and then also serve those builds yourself. I don't see why you would put more trust in me than in jsdelivr for handling that process correctly. I'm honored though 😄. Please correct me if i'm wrong, but I do not see any security benefits for you, by me personally doing npm build.

If you build yourself, you are free to use those assets with drf-spectacular. All you have to do is point SWAGGER_UI_DIST to your static location.

I do agree that adding SRI to our templates is an improvement, even if it is only a minor one. Beyond that, I do not know how we can factually improve security (without considerable time efforts on my part). Imho the npm/CDN argument is a matter of "perceived" security which does not really translate to measurable improvements.

I'm all ears if someone can make a concrete suggestion backed by research/evidence.

@valentijnscholten
Copy link

I am not debating whether or not to trust jsdelivr or any other CDN. The idea with SRI is that you either calculate the hash yourself after obtaining the artifacts from a trusted source and then upload it to a CDN. Or obtain the SRI from a trusted source as well. The onway street model helps a bit, bit strictly speaking that can also be hacked. But npm registry can also be hacked :-) and someone can commit malicious code to swaggerui. Probably compliance teams don't understand all these details and just demand self-hosting or "a" SRI :-)

Anyway, foy my usecase we are already packaging lots of npm dependencies with the project, so I can just add SwaggerUI to it and use the SWAGGER_UI_DIST setting.

@tfranzel
Copy link
Owner

tfranzel commented Oct 5, 2021

@valentijnscholten completely agree with you there. glad the self-hosting option works for you. I'll look into the SRI thing, but it has to work for the sidecar too.

@johnthagen
Copy link
Contributor Author

@tfranzel I wanted to report that we tried out drf-spectacular-sidecar in our production application (DRF + NGINX + Docker) in an offline environment and the Swagger UI and Redoc views worked perfectly! Everything was picked up automatically by Django collectstatic and served properly. No extra config needed.

🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fix confirmation pending issue has been fixed and confirmation from issue reporter is pending
Projects
None yet
Development

No branches or pull requests

3 participants