zenstackhq / zenstack

Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
https://zenstack.dev
MIT License
2.07k stars 88 forks source link

OpenAPI security #321

Closed Azzerty23 closed 1 year ago

Azzerty23 commented 1 year ago

Is your feature request related to a problem? Please describe. As I'm transitioning from FastAPI to Zenstack, I'm used to have the generated Swagger UI with authentication built-in. For endpoints requiring auth, there is a padlock to identify them. I would love to have the same within Zenstack.

Describe the solution you'd like Ideally, I would like an automatic addition of an empty security field in the generated schema when the model/operation (endpoint) doesn't require any authentication (e.g. for a model with the @@allow('create', true) attribute).

Describe alternatives you've considered Add manually a security field in @@openapi.meta attribute. E.g:

    @@openapi.meta({
        description: 'A user of the pet store',
        create: {
            description: 'I would like to disable Swagger UI authentication for this operation',
            security: []   <--- here
        },
    })

Additional context

  1. When I add this in the generated specification :

    Capture d’écran 2023-03-31 à 15 12 12
  2. It removes the authentication check : Capture d’écran 2023-03-31 à 15 12 28

Working example : https://github.com/Azzerty23/petstore-openapi-zenstack

ymc9 commented 1 year ago

Thanks for the proposal @Azzerty23 !

Yes, security settings are missing right now. Following the specification, I believe we need to add three things:

  1. A way to express security scheme Maybe just extend the plugin options:

    plugin openapi {
        ...
        securityScheme = [
            { myBearer: { type: 'http', scheme: 'bearer' } },
            { myApiKey: { type: 'apiKey', in: 'header', name: 'X-API-KEY' } }
        ]
    }

    These can just be dumped into the 'components' section in the spec as is.

  2. Generate spec using the scheme By default, if "securityScheme" is configured, a root-level "security" setting will be added to the spec, including all schemes,

    security:
        - myBearer: []
        - myApiKey: []

    On the route level, as you suggested, we can statically analyze if an operation is fully open, and if so, generate an override with security: [].

  3. Explicitly customize route-level security As you suggested, we can allow further customization of security for a route using @@openapi.meta, either setting it to empty or some specific scheme.

Does this generally look good to you?

Azzerty23 commented 1 year ago

Yes, that's the perfect solution !

Azzerty23 commented 1 year ago

I updated the exemple for reference if that helps: https://github.com/Azzerty23/petstore-openapi-zenstack

And while I'm at it, it would have been nice to be able to customize the tags description: [ModelName] operations by default. Maybe like this:

@@openapi.meta({
        description: 'A user of the pet store',  // to replace User operations
        create: {
            ...
        },
    })

Capture d’écran 2023-04-01 à 11 20 44

ymc9 commented 1 year ago

Got it. We'll try to incorporate these in the next release.

Azzerty23 commented 1 year ago

Again, sorry for that, it would be nice to be able to deprecate an endpoint.

Capture d’écran 2023-04-01 à 11 57 31 Capture d’écran 2023-04-01 à 11 58 21 Capture d’écran 2023-04-01 à 11 55 36
ymc9 commented 1 year ago

Yes, we can use this issue to keep collecting missing features around openapi.

ymc9 commented 1 year ago

Fixed by #340 and #342