Security

Authorization

APIs are secured using the OAuth 2.0 protocol, which provides account authentication and authorization with the use of a bearer access token. In order to use the APIs, you need a client ID, which can be found in your project in the Builder.

API consumers

To access APIs in your project and build a client that cannot keep the authorization data confidential, use the Implicit Grant flow.

To get an access token, make a GET or POST request to an /authorize endpoint, which is a part of the OAuth2 service. After being redirected to the sign-in page, enter your e-mail address and password. After successful authentication, the service verifies that you are a project member and grants the required scopes for the project. Verified members are redirected back to the redirect_uri provided in the request. The redirect_uri is omitted if the registered client has only one callback URL, in which case the callback URL is used for redirection.

A client reads the following information encoded in the URL fragment:

  • access_token – The value of the access token used in subsequent requests to APIs set in the Authorization: Bearer ACCESS_TOKEN header.
  • id_token(optional) The ID token is present only when setting response_type=id_token token in the request. It is used in subsequent requests for access tokens for the same user as hint (id_token_hint) in the following:
    • POST request as a form parameter
    • GET request as a query parameter
    The user does not need to be redirected to the sign-in page.
  • scope – A list of granted scopes, which is omitted if it is the same as the requested scopes. For more information, see Effective Scopes.
  • state – A parameter that is passed in the request, used to rebuild your client state, and prevent cross-site request forgery.
  • expires_in – The lifetime, in seconds, of the access token.

API providers

YaaS is a multi-tenant platform, and tenant separation is one of the main design principles that affects API security. Access tokens issued by the authorization server are dedicated for that tenant. With the access token issued for one tenant, you cannot get another tenant's data, even if the user that has the access token is invited to both projects and has the proper roles. When developing a service, handle multi-tenancy in both aspects: as a service provider, and as a service consumer.

Get the current tenant for the request

The services published in YaaS are protected by an API proxy component, which is responsible for access token validation. Only requests with valid tokens are passed to your service. The API proxy replaces the authorization header in the incoming request with decoded information about the request context with the following headers:
  • hybris-client – The identifier of the client.
  • hybris-user – Used for an authenticated user with the Implicit Grant or Resource Owner Password Credentials Grant.
  • hybris-scopes – The set of scopes granted for an access token, including the identifier of the project, in the form hybris.tenant=$projectid, or hybris.no_tenant.
    1. hybris.tenant – A tenant to which an access token is issued:
      • If neither the scope nor the hybris.no_tenant header is specified, and the user account is associated with multiple tenants, the authorization server displays an additional page to choose a tenant.
      • If both the scope and the hybris.no_tenant headers are specified, the server responds with a redirection to the redirect_uri or to the registered redirect URL with the error parameter set to invalid_scope and the error details contained in the error_description.
    2. hybris.no_tenant – To omit a tenant choice:
      • If neither the scope nor the hybris.tenant header is specified, and the user account is associated with multiple tenants, the authorization server displays an additional page to choose a tenant.
      • If both the scope and the hybris.tenant headers are specified, the server responds with a redirection to the redirect_uri or to the registered redirect URL with the error parameter set to invalid_scope and the error details contained in the error_description.

Get an access token for a tenant

If your service requires interaction with other services, such as the Document service, acquire an access token for a tenant in the context of the current request. To obtain the access token, use the Client ID and the Client Secret of the client associated with your service in the Builder. Then, request credentials, as described in the Grants document. A basic authorization header is shown in the example:

Authorization: Basic base64(client_id + ':' + client_secret)

In the body, set the hybris-tenant parameter to the value extracted from an incoming hybris-tenant request header. With this token, post content in the Document service, as described in the API Documentation.

Acquire the service's Identifier from the Builder. Go to: Projects > {My Project} > Services > {My service}

Builder modules

A Builder module is a multi-tenant client packaged together with your services. Builder modules use an Implicit Grant flow because the user is required to be signed in. To get an access token for your Builder module, follow the steps above with this additional parameter:

  • hybris_tenant – The tenant taken from the current project selected in the Builder. For more details about how to obtain information about a current project and get notification about changes, see the Builder SDK documentation.

Authorization procedure

After successful authentication, the service performs the authorization grant procedure. This procedure evaluates the effective scopes for the client and the authenticated user. For example, if there is no user in the client credentials grant, only the client scopes are used.

When evaluating the effective scopes, the service determines if the tenant has a current subscription to a package that contains a client with the given identifier. The Granted Scopes are a combination of these scopes:

  • Requested scopes
  • Scopes accepted for the client by the tenant owner during subscription
  • Scopes assigned for the user, as defined in the user roles

After authorization, a response with an access token is generated that includes the scope parameter with the granted scopes.

Changes in client scopes do not immediately affect scopes accepted for the client by the tenant owner during subscription. Changes are applied after re-creation or confirmation of the subscription by the tenant owner.

Authorization Flows in the Builder

The Builder is a client that uses the OAuth 2.0 Implicit Grant flow to obtain an access token. However, a separate token is required for each use case in terms of the user, tenant, or third-party client. Those tokens are valid for a limited time and do not contain refresh tokens. This means that the Builder authorizes itself for each user and tenant independently.

There are different use cases and authorization flows in the Builder for:

  • Builder clients in terms of the user
  • Builder clients in terms of the tenant and user
  • Builder modules (third-party clients) in terms of the tenant and user

Authorize the Builder client in terms of the user

If you log in to the Builder as a user, then a home page, a list of projects, and teams in which you have a membership are displayed. The following diagram shows the authorization flow for this example:

Builder client user flow

In this example:

  1. The user opens the Builder home page.
  2. The Builder does not have a token to act upon in terms of the user, so it sends an authentication request as POST form data to the authorization server. In response to the user request, the Builder sends its client ID, a set of required scopes, and the redirect URI, http://builder.yaas.io, as form data parameters.
  3. The authorization server responds with a sign-in form, which the Builder renders as an iframe on the Builder's sign-in page.
  4. The user provides their YaaS credentials in the form provided by the authorization server.
  5. The user submits the form, which sends the credentials as POST form data to the sign-in endpoint of the authorization server.
  6. The authorization server responds with an HTTP 302 redirection to the address of the Builder client, according to the redirect URI that was sent. The response contains an access token and ID token in the hash part of the URL. The access token gives the Builder the authority to act in terms of the user. The ID token represents the user authentication.
  7. The Builder stores the access token and ID token on the client side and uses the access token to fetch the user's projects and teams from the Account service using the YaaS proxy.
  8. The YaaS proxy verifies the authority of the access token with respect to the requested resources. If access is granted, the call is processed by the target YaaS API, and the Builder receives data about the user's teams and projects. If access is denied, the YaaS proxy responds with an HTTP 401 or HTTP 403 error.

Authorize the Builder client in terms of the tenant and user

The following diagram shows the authorization flow for a user selecting a project in the left navigation tree of the Builder:

Builder tenant switch flow

  1. The user selects a project from the list in the navigation tree.
  2. The Builder checks if it already has a valid access token for the selected tenant in the local cache. If it does, it uses this access token to fetch project details data using the YaaS proxy. If not, it sends an authorization request as POST form data using these parameters:
    • ID token - An ID which satisfies the current user authentication.
    • Redirect URI - A URI that imposes redirection to the Builder's authentication callback, an invisible iframe.
    • Scopes - An authorization scope that the Builder requires to operate in terms of the user and the tenant.
    • hybris.tenant - A special scope to name the tenant for which the Builder needs a token.
  3. The authorization server responds with an HTTP 302 redirection to the address of the Builder's authorization callback address of https://builder.yaas.io/auth/callback.html, with respect to the redirect URI that was sent. The location header of the response contains the access token in the hash part of the URL.
  4. The authentication callback iframe consumes the access token and stores the token on the client side in the token's cache. The access token enables the Builder to act in terms of the user or a requested project.
  5. The Builder uses the access token to fetch project data.
  6. The YaaS proxy verifies the authority of the access token regarding the requested resources. The access token contains encoded information about the user, project, and the user's role in the project (scopes). If access is granted, the call is processed by the target YaaS API, and the Builder receives the project's data back. If access is denied, the YaaS proxy responds with an HTTP 401 or HTTP 403 error.

Authorize the Builder module (third-party client) in terms of the tenant and user

There is another authorization flow for any Builder module that is developed independently from the Builder application. Acting in terms of a project, the user selects a Builder module from the left navigation tree, such as the Wishlist module. In this example, the currently selected project subscribes to a Wishlist package. This package contains a Wishlist service and a Wishlist Builder module. The Builder does not contain details about the Wishlist API, but it can render a third-party UI module that uses the Wishlist API using the YaaS proxy.

The following diagram shows the authorization flow for this example:

Builder app switch flow

  1. The user selects the Wishlist module from the navigation tree.
  2. The Builder creates a container iframe for the Wishlist module.
  3. The Builder issues an authorization request as POST form data in terms of the user, project, and Builder module using these parameters:
    • Client ID - An ID that represents the Builder Wishlist module, not the Builder.
    • ID token - An ID that satisfies the current user authentication.
    • Scopes - The scopes represent what the module requires to operate in terms of the user and the tenant, such as wishlist_read and wishlist_write.
    • Redirect URI - A URI that imposes redirection to the Builder's authentication callback, an invisible iframe.
  4. The authorization server responds with an HTTP 302 redirection to the address of the Builder's authorization callback address of https://builder.yaas.io/auth/callback.html, according to the redirect URI that was sent. The location header of the response contains the access token in the hash part of the URL. The authentication callback iframe consumes the access token.
  5. The token is sent to the Builder module's iframe using a client-side messaging event.
  6. The Builder module then uses the access token to communicate with the YaaS API using the proxy. The token enables the Builder module to act in terms of the user and the project, according to the Builder module's scopes and the user's roles in the project.
  7. The YaaS proxy verifies the authority of the access token regarding the requested resources. The access token contains encoded information about the client, such as the Builder module, user, project, and the user's role in the project (scopes). If access is granted, the call is processed by the target YaaS API, and the Builder module receives the requested data back, such as the wishlist data in this example. If access is denied, the YaaS proxy responds with an HTTP 401 or HTTP 403 error.

Scopes

OAuth 2.0 scopes are permission settings that allow you to govern resources managed by a service, and methods to access them. In YaaS, the limitations can be imposed on a client, or a specific user, or a combination of both.

Ideally, scopes should refer to actions they allow. For example, the scope:

  • hybris.activity_view – This scopes is required to retrieve a list of entities, like activity campaigns.
  • hybris.price_manage – This scope is required to create, update, or delete a price.

Secure your service with scopes and manage access to its functionalities and resources. Find out how in this document. Later, when you include scopes in requests for access tokens, the YaaS authorization service validates the requests and grants the appropriate permissions.

Scopes are service-related. This means that you cannot share scopes between services.

Scopes and HTTP methods

Scopes are not mapped to HTTP methods on a one-to-one basis, but rather, scopes are mapped to a collection of methods that are grouped by typical usage scenarios. For example, map the view scopes to the GET methods, and the manage scopes to the POST, PUT, and DELETE methods. This makes it easier to build user roles. For example, as a product manager role assigned to every single scope, there are fewer scopes to assign using the collections of methods. Of course, there are exceptions to this rule, but follow this standard whenever possible.

Carefully plan the level of granularity for the scopes in your service. Balance the least authority principle with the convenience of the user.

Find out how to create user roles in this document.

For more information about scopes, see the OAuth 2.0 Specification.

Secure a Service

Secure your service by assigning scopes for different operations, without having to write any code.

Declare scopes in the Builder


Add scopes to your service definition in the Builder:
  1. Click Projects > {My project} > Development > Services > {My service} and select MANAGE SCOPES.
  2. Click + SCOPE and add the name and the description of the new scope.
    • When naming the scopes for your service, follow this convention:
      • <organization_basepath>.<service_identifier>_<action>
      The basepath of your organization is the part of YaaS URL that you defined when you created the organization.
      For example, the basepath of https://api.eu.yaas.io/fictionops is fictionops.

      The following example shows a name for a scope that allows to manage resources, defined within the Hybris organization and the Price service:
      • hybris.price_manage
      The maximum length for scope names in YaaS is 128 characters. Scope names are case-sensitive.
    • When naming the scopes for your service, follow this convention:
      • Scope Description - Use this scope to to create, update, or delete a price.
  3. Save your changes.

Authorization rules

The authorization rules protect specific paths that you define. Enter the path to secure, select the HTTP methods affected by the rule, and specify which scopes access these methods. Use additional options, such as Skip Subscription Check, to fine-tune your rule. The API proxy created for your service verifies the rules.

The order of the authorization rules is important. Only the first matching rule applies to the resource, so put the most fine-grained rules on the top of the list, and the most general rules on the bottom.

To create a new authorization rule in the Builder:

  1. Click Projects > {My Project} > Development > Services > {My service} > Authorization Rules.
  2. Click +Authorization Rules to add a new authorization rule. This screen displays:

    Add Authorization Rules.

    Set these parameters to create your authorization rule:
    • Path – This is a required field. It specifies the path you want to secure with the authorization rule. Use path expressions and wildcard characters. For example, /resource/* secures everything below the /resource path.
    • Methods – This field defines which of the standard HTTP methods, such as GET or POST, the rule secures. You can also use the * wildcard character to secure all methods.
    • Scopes – This is a required field. It specifies the scopes that are required to access the resource.
    • Require all scopes for authorization – If you enable this option, the caller will need all of the scopes specified in the Scopes field in order to access the resource. Use this option if you selected two or more scopes for this rule.
    • Optional Authorization - Use this security setting to enable your service to return both anonymous and non-public (restricted) data, from a single endpoint.
      If you enable this option, the API Proxy checks the call for the authorization header. If the call includes the header, the API Proxy validates the access token and adds the Hybris-headers to the request.
      If the call does not include the authorization header, the API Proxy passes the request to the target service without setting the Hybris-specific headers.
    • Skip Subscription Check - If you select this option, the API Proxy does not check the access token for active subscription to the service.
    • Skip Authorization – If you enable this option, the API proxy does not verify the caller's access token. The Hybris-specific headers are not sent in the request to the service, and all original headers sent to the API Proxy are forwarded to the service.
      Skip Authorization option overrides any other options in the given rule!
  3. Click SAVE to save your authorization rule.

Sample authorization rules


  1. Optional authorization - Enables your service to return two different sets of resources. A good use case for this rule is a service that manages blog posts.
    • Path: /myservice/v1/blogposts/
    • Methods: GET
    • Scopes: myservice.post_manage, myservice.post_create
    • Enabled options: Require all scopes for authorization, Optional Authorization
    This rule secures the GET method on the specified path. The API Proxy checks the call for a valid access token. If the user calls the service without an access token, the service returns public resources, such as all of the published blog posts. If the call includes a valid token with both of the specified scopes, the service returns a restricted set of resources, such as the unpublished posts saved by the given user.
  2. Skip subscription check - Enables all users to call your service, no matter if they subscribe to it or not.

    • Path: /hybrisservice/v1/resource/
    • Methods: GET, POST, PUT
    • Scopes: hybris.account_view, hybris.org_view
    • Enabled options: Skip Subscription Check
    This rule secures the GET, POST, and PUT methods on the specified path. The API Proxy checks the call for a valid access token. The system requires either of the two specified scopes, but the API Proxy does not check if the user subscribes to the service. For everyone to have access to your service without the need to subscribe, use this rule.
  3. Skip Authorization - Override other authorization rules set for the given path and allow unrestricted access to your resources.

    • Path: /fictionops/v1/*
    • Methods: GET, POST, PUT, DELETE
    • Scopes: hybris.account_view, hybris.org_view
    • Enabled options: Skip Authorization
    This authorization rule has the Skip Authorization option enabled. This means that the system does not verify the access token when performing the GET, POST, or PUT operations on the specified path. Remember that Skip Authorization overrides any other options/rules set for the specified path.
  4. You can use various URL patterns in your rules. For example, the path /tutorial/media/* is more granular than /tutorial/media*. The optional values /tutorial/media(/*) will secure the defined methods for the path /tutorial/media and /tutorial/media/*.

    Default authorization rules

    If the proxy cannot find any matching entries in the list of the defined rules for a service, it always uses the default settings:
    • For the "single-slash" path, or when no path is provided, the Skip Authorization parameter is set to true for all methods and the API Console.
    • For any other path and method, the Skip Authorization parameter is set to false, and the value in the Scopes field is not passed. However, a valid access token is required.
    • The Optional Authorization parameter is set to false.

    Evaluate the hybris-scopes header directly in your service

    If you do not want to set authorization rules in the Builder, you can implement advanced authorization directly in your service. This requires evaluating the hybris-scopes header in your service logic.

    Last-mile security

    Make sure that only the API Proxy can access your service directly. The API Proxy shields your services within the YaaS ecosystem, but an attacker who gains access to the internal network can bypass this shield. Mitigate the risk with last-mile security, based on the HTTP basic access authentication method.

    Enable basic authentication in the Builder

    To enable basic authentication in the Builder, click Projects > {My Project} > Development > Services > {My service}.
    Find the Basic Authentication toggle in the API Proxy settings section. Click it to enable basic authentication. When you enable basic authentication, define these credentials:

    • Authorization Username - The username must be between 8 and 33 characters long (inclusive).
    • Password - The password must be between 8 and 33 characters long (inclusive) and include at least one lowercase character, at least one uppercase character, and at least one digit.

    The API proxy uses the HTTP basic access authentication method. You cannot enable service credentials for services that are defined with an insecure protocol (HTTP). Likewise, if there are credentials defined, you cannot update the service definition URL with an insecure protocol URL.

    Store these credentials in a safe place. There is no way to retrieve them from the service details.

User Roles and Effective Scopes

User roles

In YaaS, developers can define unique scopes in a service, and the projects can use many services from various providers. Managing the allowed scopes for each user is a difficult task, unless you define User Roles, which group several scopes into one.
For example, create a shop_manager role that contains the following scopes:

  • hybris.category_read_unpublished
  • hybris.product_create
  • hybris.price_manage
  • Users in a project are automatically assigned the scopes that are bound with their roles.
    Each user can have different user roles. This means that a single user can be invited to many projects and have different user roles assigned in each one of them.

    Effective scopes

    In the authorization process, the client sends a request to an OAuth 2.0 endpoint to get an access token with the proper scopes. In the response, for different grant flows, the access token includes the encoded effective scopes that are intersections of the following:

    1. Client Credentials Grant
      • Requested scopes
      • Scopes granted to the client by the tenant
    2. Implicit Grant and Resource Owner Password Credentials Grant
      • Requested scopes
      • Scopes granted to the client by the tenant
      • User scopes defined by roles assigned to user

    Example

    In this example, the <YaaS_URL> is removed from the scope names for better readability.

    Developer A develops Builder Module A that requires the following scopes from the Product Content package:

    • product_create
    • price_manage

    User B, and the owner of Project B, subscribes to the Package A that contains this builder module.

    User B then invites his fellow, User C, to the Project B and assigns him a user role of Product Manager that contains the product_create and product_update scopes. When User C uses Builder Module A in the context of Tenant B (Project B), the request for the access token to the OAuth2 authorize endpoint is made with the following items:

    • Client ID of Builder Module A
    • Requested scopes: product_create, product_publish, hybris.tenant=projectb

    The user is then prompted to sign in. If the authentication completes successfully, the access token is issued WITHOUT the scope product_publish. This is the only scope of those sent in the request, which is not assigned to the user, nor granted to the Builder module in the context of the tenant.

    For more information about the hybris.tenant and hybris.no_tenant scopes, see Authorization.

    Storefront Security

    The storefront is a retail shop web application with products for purchase as a working demonstration of the YaaS APIs. Storefront security plays a substantial role in ensuring secure transactions. The following items are the key security features in storefront:

    Cross-site scripting (XSS)

    Helmet is a code module loaded from the Node Package Manager (NPM). It includes these security settings which can be added to your site:

    • frameguard – Denies a malicious attacker the ability to put site information into an iframe that could contain extra execution logic.
    • xssFilter – Adds an X-XSS-Protection HTTP header to protect against cross-site scripting (XSS).

    A custom wrapper with regular expression validators is also provided to ensure that certain input types have limited character sets in a directive called y-input. Those input types are URL, email, ID, name, password, description, date, and keys.

    Angular security

    Angular version 1.2 has Strict Contextual Escaping (SCE) enabled by default to help defeat XSS. SCE ensures that no HTML is executed as JavaScript. Therefore, use Angular version 1.2 or greater.

    Angular also provides a mechanism to combat cross-site request forgery (CSRF or XSRF). For more information, see the AngularJS website.

    Headers

    The x-powered-by header is disabled to hide the stack implementation details, which limits the exploitation of known vulnerabilities. For more information, see the NPM website.

    Clickjacking

    Configure your deployment HTTP server to send the X-FRAME-OPTIONS header to restrict others from hosting your site inside an iframe. For more information, see OWASP Clickjacking.

    This is an example of a header that disallows the ability to inject the storefront into an iframe:

    X-Frame-Options: DENY
    

    This is an example of the header that blocks injection into inputs:

    X-XSS-Protection:1; mode=block
    

    HTTPS and SSL certificates

    YaaS APIs use HTTPS to encrypt HTTP transactions. Therefore, configure your domain to allow HTTP to be encrypted into a HTTPS session. Also, a forced redirect is applied for any HTTP request to be converted to a Secure Socket Layer (SSL) HTTPS session. To gain the chain of trust that is required for a browser to verify your website identity, purchase a certificate from an online certificate authority.

    • Send feedback

      If you find any information that is unclear or incorrect, please let us know so that we can improve the Dev Portal content.

    • Get Help

      Use our private help channel. Receive updates over email and contact our specialists directly.

    • hybris Experts

      If you need more information about this topic, visit hybris Experts to post your own question and interact with our community and experts.