Skip to content

Latest commit

 

History

History
192 lines (151 loc) · 7.56 KB

security.adoc

File metadata and controls

192 lines (151 loc) · 7.56 KB

REST Basics - Security

{MUST} secure endpoints

Every API endpoint must be protected and armed with authentication and authorization. As part of the API definition you must specify how you protect your API using either the http typed bearer or oauth2 typed security schemes defined in the OpenAPI Authentication Specification.

The majority of our APIs (especially the company internal APIs) are protected using JWT tokens provided by the platform IAM token service. In these situations you should use the http typed Bearer Authentication security scheme — it is based on OAuth2.0 {RFC-6750}[RFC 6750] defining the standard header Auhorization: Bearer <token>. The following code snippet shows how to define the bearer security scheme.

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

The bearer security schema can then be applied to all API endpoints, e.g. requiring the token to have api-repository.read scope for permission as follows (see also {MUST} define and assign permissions (scopes)):

security:
  - BearerAuth: [ api-repository.read ]

In other, more specific situations e.g. with customer and partner facing APIs you may use other OAuth 2.0 authorization flows as defined by {RFC-6749}[RFC 6749]. Please consult the OpenAPI OAuth 2.0 Authentication section for details on how to define oauth2 typed security schemes correctly.

Note: Do not use OpenAPI oauth2 typed security scheme flows (e.g. implicit) if your service does not fully support it and implements a simple bearer token scheme, because it exposes authentication server address details and may make use of redirection.

{MUST} define and assign permissions (scopes)

APIs must define permissions to protect their resources. Thus, at least one permission must be assigned to each API endpoint.

The naming schema for permissions corresponds to the naming schema for hostnames and event type names. Please refer to {MUST} follow naming convention for permissions (scopes) for designing permission names and see the following examples.

Application ID Resource ID Access Type Example

order-management

sales-order

read

order-management.sales-order.read

order-management

shipment-order

read

order-management.shipment-order.read

fulfillment-order

write

fulfillment-order.write

business-partner-service

read

business-partner-service.read

Note: APIs should stick to component specific permissions without resource extension to avoid the complexity of too many fine grained permissions. For the majority of use cases, restricting access for specific API endpoints using read or write is sufficient.

The defined permissions are than assigned to each API endpoint based on the security schema (see example in previous section) by specifying the security requirement as follows:

paths:
 /business-partners/{partner-id}:
    get:
      summary: Retrieves information about a business partner
      security:
        - BearerAuth: [ business-partner-service.read ]

In some cases a whole API or selected API endpoints may not require specific permissions, e.g. if information is public or protected by object level authorization. To make this explicit you should assign the uid pseudo permission, that is always available as OAuth2 default scope in Zalando.

paths:
  /public-information:
    get:
      summary: Provides public information about ...
               Accessible by any user; no permissions needed.
      security:
        - BearerAuth: [ uid ]

Hint: Following a minimal a minimal API specification approach, the Authorization-header does not need to be defined on each API endpoint, since it is required and so to say implicitly defined via the security section.

{MUST} follow naming convention for permissions (scopes)

As long as the functional naming is not yet supported by our permission registry, permission names in APIs must conform to the following naming pattern:

<permission> ::= <standard-permission> |  -- should be sufficient for majority of use cases
                 <resource-permission> |  -- for special security access differentiation use cases
                 <pseudo-permission>      -- used to explicitly indicate that access is not restricted

<standard-permission> ::= <application-id>.<access-mode>
<resource-permission> ::= <application-id>.<resource-name>.<access-mode>
<pseudo-permission>   ::= uid

<application-id>      ::= [a-z][a-z0-9-]*  -- application identifier
<resource-name>       ::= [a-z][a-z0-9-]*  -- free resource identifier
<access-mode>         ::= read | write    -- might be extended in future

This pattern is compatible with the previous definition.

Note: This naming convention only applies to scopes for service-to-service communication using the Platform IAM tokens. For IAM systems with other naming rules (e.g. Zalando Partner IAM), the naming should be consistent with the existing conventions of those systems.