Skip to content

Backend portal configuration

Page as Markdown

Configure the backend of the developer portal to select the APIs that you want the portal to serve, their visibility settings, and the usage plans that you want to apply.

With the Portal custom resource, you tie together the backend resources that serve the developer portal. These resources include portal settings, usage plans, API products, and more.

About the backend and frontend portals

As you set up a developer portal, you can think about two main parts to configure:

  • Backend portal: As part of the Gloo Mesh Gateway installation, Gloo set up a portal server. You can configure this backend portal to expose the Gloo Portal OpenAPI as well as the Portal custom resources that describe each developer portal that you create.
  • Frontend portal: The frontend portal is a user-facing application that renders the information about the APIs that the portal server exposes in a developer portal. This way, your users can interact with a graphical user interface to view, authenticate to, and use your API products. For more information, see the Deploy a frontend app guide.

Prepare the backend portal configuration

The Portal custom resource selects the API products and usage plans that you want to expose in the developer portal.

Step 1: Add API products

Decide on the API products that you want your developer portal to serve. To determine the API products that are included in a portal, you specify an API product label selector in your portal resource.

  1. Decide on a label that you want to use to select the API products that you want to include in your developer portal. For example, your label might be portal: dev-portal.

  2. Add the label to the spec.apis section in your portal resource. When you create the portal resource, all API products with this label are retrieved and the corresponding APIs are stitched together in a combined schema.

    apiVersion: apimanagement.gloo.solo.io/v2
    kind: Portal
    metadata:
      name: developer-portal
      namespace: gloo-mesh
    spec:
      visibility:
        public: true
        privateAPILabels:
          portal-visibility: private
      domains:
        - "developer.example.com"
      portalBackendSelectors:
        - selector:
            labels:
              app: gloo-mesh-portal-server
      usagePlans:
         - name: bronze
           displayName: "Bronze Plan"
           description: "A basic usage plan"
         - name: silver
           description: "A better usage plan"
         - name: gold
           description: "The best usage plan!"
      apis:
        - labels:
            portal: dev-portal
  3. Decide on the API products that you want to include in your portal and add the label to the route table that represents each API product. The following example adds the label to the tracks and petstore API products.

    kubectl apply -f - << EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: tracks-rt
      namespace: istio-ingress
      labels:
         portal: dev-portal
         api: tracks
    spec:
      http:
      - name: tracks-api
        labels:
          usagePlans: dev-portal
        matchers:
        - uri:
            prefix: /
        forwardTo:
          pathRewrite: /
          destinations:
          - ref:
              name: tracks-rest-api
              namespace: tracks
            port:
              number: 5000
      portalMetadata:
        apiProductId: "tracks"
        apiProductDisplayName: "Catstronauts Course Tracks"
        apiVersion: "v1"
        title: "Catstronauts REST API"
        description: "REST API for Catstronauts to retrieve data for tracks, authors and modules."
        termsOfService: "You must authenticate to use this API! And other Terms of Service."
        contact: "support@example.com"
        license: "License info, such as MIT"
        lifecycle: "Supported"
        customMetadata:
          compatibility: "None"
    EOF
    kubectl apply -f - << EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: petstore-rt
      namespace: istio-ingress
      labels:
        portal: dev-portal
        api: petstore
    spec:
      http:
      - name: pets-api
        matchers:
        - uri:
            prefix: /pet
        forwardTo:
          destinations:
          - ref:
              name: pets-rest-api
              namespace: pets
            port:
              number: 5000
      - name: users-api
        matchers:
        - uri:
            prefix: /user
        forwardTo:
          destinations:
          - ref:
              name: users-rest-api
              namespace: users
            port:
              number: 5000
      - name: store-api
        matchers:
        - uri:
            prefix: /store
        forwardTo:
          destinations:
          - ref:
              name: store-rest-api
              namespace: store
            port:
              number: 5000
      portalMetadata:
        apiProductId: "petstore"
        apiProductDisplayName: "Pet Store"
        apiId: "petstore-v1"
        apiVersion: "v1"
        title: "Pet Store REST API"
        description: "Totally awesome API for all things pets!"
        termsOfService: "You must authenticate to use this API! And other Terms of Service."
        contact: "support@example.com"
        license: "License info, such as MIT"
        lifecycle: "Supported"
        customMetadata:
          compatibility: "None"
    EOF

Step 2: Set the visibility of API products

For the API products that the developer portal serves, you can decide whether the API product is visible to all users (public APIs) or if the API product is hidden until the user is successfully authenticated and authorized (private APIs).

Click through the following tabs to learn more about the visibility options that are available to you and the resources you need to configure to implement this option.

By default, the portal’s visibility is set to private, which means that all the API products that the portal serves are hidden to the user, until the user is properly authenticated with an OIDC provider and authorized with a portal group.

If you decide to keep all of your API products private, no additional setup in the portal resource or API product is required. However, you must follow the steps to add external authentication with an OIDC provider and authorize users with portal groups.

A public portal does not require authentication for the API products that the portal serves. Any user who accesses the developer portal can view the APIs of the API product. To change the visibility for all API products that the portal serves to public, set the spec.visibility.public value in your portal resource to true as shown in the following example.

kubectl apply -f- <<EOF
apiVersion: apimanagement.gloo.solo.io/v2
kind: Portal
metadata:
  name: developer-portal
  namespace: gloo-mesh
spec:
  visibility:
    public: true
  domains:
    - "developer.example.com"
  portalBackendSelectors:
    - selector:
        labels:
          app: gloo-mesh-portal-server
  usagePlans:
    - name: bronze
      displayName: "Bronze Plan"
      description: "A basic usage plan"
    - name: silver
      description: "A better usage plan"
    - name: gold
      description: "The best usage plan!"
  apis:
    - labels:
        portal: dev-portal
EOF

You can choose to set the visibility for your portal to public and select specific API products that you want to hide until the user is properly authenticated and authorized. With this approach, unauthorized users can see only the APIs of public API products. Private APIs are hidden.

  1. Decide on a label that you want to use to mark an API product private. For example, your label might be portal-visibility: private.

  2. In your portal resource, configure the spec.visibility with both public and private settings. Set the overall visibility to public: true. Then, add the label that you want to use to mark API products as private in the privateAPILabels section.

    kubectl apply -f- <<EOF
    apiVersion: apimanagement.gloo.solo.io/v2
    kind: Portal
    metadata:
      name: developer-portal
      namespace: gloo-mesh
    spec:
      visibility:
        public: true
        privateAPILabels:
          portal-visibility: private
      domains:
        - "developer.example.com"
      portalBackendSelectors:
        - selector:
            labels:
              app: gloo-mesh-portal-server
      usagePlans:
        - name: bronze
          displayName: "Bronze Plan"
          description: "A basic usage plan"
        - name: silver
          description: "A better usage plan"
        - name: gold
          description: "The best usage plan!"
      apis:
        - labels:
            portal: dev-portal
    EOF
  3. Add the label to any API product that you want to mark private. In this example, the portal-visibility: private label is added to the route table that represents the petstore API product.

    kubectl apply -f - << EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: petstore-rt
      namespace: istio-ingress
      labels:
        portal: dev-portal
        api: petstore
        portal-visibility: private
    spec:
      http:
      - name: pets-api
        labels:
          usagePlans: dev-portal
        matchers:
        - uri:
            prefix: /pet
        forwardTo:
          destinations:
          - ref:
              name: pets-rest-api
              namespace: pets
            port:
              number: 5000
      - name: users-api
        labels:
          usagePlans: dev-portal
        matchers:
        - uri:
            prefix: /user
        forwardTo:
          destinations:
          - ref:
              name: users-rest-api
              namespace: users
            port:
              number: 5000
      - name: store-api
        labels:
          usagePlans: dev-portal
        matchers:
        - uri:
            prefix: /store
        forwardTo:
          destinations:
          - ref:
              name: store-rest-api
              namespace: store
            port:
              number: 5000
      portalMetadata:
        apiProductId: "petstore"
        apiProductDisplayName: "Pet Store"
        apiVersion: "v1"
        title: "Pet Store REST API"
        description: "Totally awesome API for all things pets!"
        termsOfService: "You must authenticate to use this API! And other Terms of Service."
        contact: "support@example.com"
        license: "License info, such as MIT"
        lifecycle: "Supported"
        customMetadata:
          compatibility: "None"
    EOF
  4. Follow the steps to add external authentication with an OIDC provider and authorize users with portal groups.

Step 3: Add usage plans

Describe the usage plans that you want to make visible to your users in the developer portal. You might include information such as a display name and a description that you want to show to users that access the developer portal.

  1. Get the usage plans that you set up earlier. The usage plans are set in the rate limit server configuration.

    kubectl get ratelimitserverconfigs usage-plans -n gloo-mesh -o yaml
  2. Select the usage plans that you want to include in your portal. To reference a usage plan in your portal resource, you need to get the simpleDescriptors.value value. In the following example, the usage plan value is bronze.

    ...
    spec:
      destinationServers:
      - port:
          name: grpc
        ref:
          cluster: $CLUSTER_NAME
          name: rate-limiter
          namespace: gloo-mesh
      raw:
        setDescriptors:
        - rateLimit:
            requestsPerUnit: 1
            unit: MINUTE
          simpleDescriptors:
          - key: userId
          - key: usagePlan
            value: bronze

  3. Add the usage plan values to the usagePlans section of your portal resource. Make sure to enter the usage plan value that you retrieved in the previous step in the spec.usagePlans.name field. You can optionally add information, such as the display name or a description for each usage plan that is shown to users that access the developer portal. For example, you might include pricing details, rate limiting, or access instructions in the plan description.

    apiVersion: apimanagement.gloo.solo.io/v2
    kind: Portal
    metadata:
      name: developer-portal
      namespace: gloo-mesh
    spec:
      domains:
        - "developer-portal.example.com"
      portalBackendSelectors:
        - selector:
            labels:
              app: gloo-mesh-portal-server
      usagePlans:
        - name: bronze
          displayName: "Bronze Plan"
          description: "A basic usage plan"
        - name: silver
          description: "A better usage plan"
        - name: gold
          description: "The best usage plan!"
      apis:
        - labels:
            portal: dev-portal

Create a backend portal

Now that you prepared your portal configuration, you can create your developer portal and make it available to your users.

Before you begin

This guide assumes that you want to include the tracks and petstore API products in your developer portal. The tracks API is publicly available, and the petstore API is visible only if you are successfully authenticated and authorized.

  1. Deploy sample REST APIs to create ApiDocs.
  2. Bundle your APIs into API products.
  3. Prepare usage plans, which consist of external auth and rate limit policies.
  4. Prepare your developer portal configuration.

Step 1: Create a backend portal resource

Create a portal resource. The Gloo portal server uses this configuration to create a backend for a developer portal. Later, you can expose the developer portal to end users by creating a frontend app for the portal.

  1. Create a developer portal. The following portal resource creates a developer portal for the developer.example.com host and includes all API products with the portal: dev-portal label. If you followed the examples in Decide on your portal configuration, the tracks and petstore API products are served by this portal resource.

    kubectl apply -f- <<EOF
    apiVersion: apimanagement.gloo.solo.io/v2
    kind: Portal
    metadata:
      name: developer-portal
      namespace: gloo-mesh
    spec:
      visibility:
        public: true
        privateAPILabels:
          portal-visibility: private
      domains:
        - "developer.example.com"
      portalBackendSelectors:
        - selector:
            labels:
              app: gloo-mesh-portal-server
      usagePlans:
        - name: bronze
          displayName: "Bronze Plan"
          description: "A basic usage plan"
        - name: silver
          description: "A better usage plan"
        - name: gold
          description: "The best usage plan!"
      apis:
        - labels:
            portal: dev-portal 
    EOF
  2. Verify that the internal PortalConfig resource is created for your portal.

    kubectl get portalconfigs -n gloo-mesh -o yaml

    Example output: Notice that the stitched schema is used, as well as the portal metadata that you set in the route table.

    apiVersion: v1
    items:
    - apiVersion: internal.gloo.solo.io/v2
      kind: PortalConfig
      metadata:
     creationTimestamp: "2023-04-06T21:30:41Z"
     generation: 1
     labels:
       context.mesh.gloo.solo.io/cluster: cluster-1-portal
       context.mesh.gloo.solo.io/namespace: istio-ingress
       context.mesh.gloo.solo.io/workspace: cluster-1-portal
       gloo.solo.io/parent_cluster: cluster-1-portal
       gloo.solo.io/parent_group: ""
       gloo.solo.io/parent_kind: Namespace
       gloo.solo.io/parent_name: istio-ingress
       gloo.solo.io/parent_namespace: ""
       gloo.solo.io/parent_version: v1
       reconciler.mesh.gloo.solo.io/name: translator
     name: developer-portal-gloo-mesh-cluster-1-portal
     namespace: gloo-mesh
     resourceVersion: "1985686"
     uid: 59fe5508-d839-4720-b6ae-59347664e3bb
      spec:
     apis:
     - apiSchema:
         cluster: cluster-1-portal
         name: tracks-rt-stitched-openapi-cluster-1-portal-istio-ingress-cluster-1-portal
         namespace: gloo-mesh
       contact: support@example.com
       description: REST API for Catstronauts to retrieve data for tracks, authors
      and modules.
       license: license info
       routeTable:
         cluster: cluster-1-portal
         name: tracks-rt
         namespace: istio-ingress
       termsOfService: You must authenticate to use this API! And other Terms of Service.
       title: Catstronauts REST API
     - apiSchema:
         cluster: cluster-1-portal
         name: petstore-rt-stitched-openapi-cluster-1-portal-istio-ingress-cluster-1-portal
         namespace: gloo-mesh
       contact: support@example.com
       description: Totally awesome API for all things pets!
       license: license info
       routeTable:
         cluster: cluster-1-portal
         name: petstore-rt
         namespace: istio-ingress
       termsOfService: You must authenticate to use this API! And other Terms of Service.
       title: Petstore REST API
     domains:
     - developer.example.com
     portalRef:
       cluster: cluster-1-portal
       name: developer-portal
       namespace: gloo-mesh
     public: true
    kind: List
    metadata:
      resourceVersion: ""
      selfLink: ""

Step 2: Set up routing for the backend portal

Set up routing to the portal server. This way, you can access the backend APIs that serve the frontend developer portal, such as listing the APIs in the portal.

  1. Create a virtual gateway that you use to expose the developer portal. The following example selects the default ingress gateway that you deployed during your Gloo Platform installation. For more examples such as HTTPS/TLS, see Configure gateway listeners.

    kubectl apply -f- <<EOF
    apiVersion: networking.gloo.solo.io/v2
    kind: VirtualGateway
    metadata:
      name: istio-ingressgateway-portal
      namespace: istio-ingress
    spec:
      listeners:
        - allowedRouteTables:
            - host: developer.example.com
            - host: portal.example.com
          http: {}
          port:
            number: 80
      workloads:
        - selector:
            cluster: $CLUSTER_NAME
            labels:
              istio: ingressgateway
    EOF
  2. Create a route table for the developer portal. The following route table creates routes for all the portal APIs so that you can interact with your developer portal.

    kubectl apply -f - <<EOF    
    apiVersion: networking.gloo.solo.io/v2
    kind: RouteTable
    metadata:
      name: dev-portal-rt
      namespace: istio-ingress
    spec:
      hosts:
      - developer.example.com
      virtualGateways:
      - name: istio-ingressgateway-portal
        namespace: istio-ingress
      defaultDestination:
        port:
          number: 8080
        ref:
          name: gloo-mesh-portal-server
          namespace: gloo-mesh
          cluster: $CLUSTER_NAME
      http:
        #
        # Portal server routes that require authentication.
        #
        - forwardTo: {}
          name: authn
          labels:
            oauth: "true" # Use this label to apply an OAuth external auth policy
            route: portal-api
          matchers:
            #
            # /v1/me
            - uri:
                prefix: /v1/me
              method: OPTIONS
            - uri:
                prefix: /v1/me
              method: GET
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
            #
            # /v1/apis
            - uri:
                prefix: /v1/apis
              method: GET
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
            #
            # /v1/usage-plans
            - uri:
                prefix: /v1/usage-plans
              method: GET
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
            #
            # /v1/api-keys
            - uri:
                prefix: /v1/api-keys
              method: GET
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
            - uri:
                prefix: /v1/api-keys
              method: POST
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
            - uri:
                prefix: /v1/api-keys
              method: DELETE
              headers:
                - name: Authorization
                  value: "Bearer.*"
                  regex: true
        #
        # Portal server routes that are public and do not require authentication.
        #
        - forwardTo: {}
          name: no-auth
          labels:
            route: portal-api
          matchers:
            - uri:
                prefix: /v1/apis
              method: GET
            - uri:
                prefix: /v1/usage-plans
              method: GET
            - uri:
                prefix: /v1/api-keys
              method: GET
            #
            # Allow OPTION requests without authentication.
            #
            - uri:
                prefix: /v1/api-keys
              method: OPTIONS
            - uri:
                prefix: /v1/usage-plans
              method: OPTIONS
            - uri:
                prefix: /v1/apis
              method: OPTIONS
    EOF

Step 3: Verify the backend portal

Verify that the backend portal is set up by sending a request and reviewing its resources in the Gloo UI.

  1. Send a request to the developer portal to list the APIs that you have access to. Note that because the petstore API is set to private, only the tracks API is returned in your CLI output. To view the private petstore APIs, you must set up authentication and authorization. For more information, see Secure the portal.

    curl -vik --resolve developer.example.com:80:$INGRESS_GW_ADDRESS http://developer.example.com:80/v1/apis

    Example output:

    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < content-type: application/json
    content-type: application/json
    < date: Fri, 14 Apr 2023 13:57:02 GMT
    date: Fri, 14 Apr 2023 13:57:02 GMT
    < content-length: 387
    content-length: 387
    < x-envoy-upstream-service-time: 0
    x-envoy-upstream-service-time: 0
    < server: istio-envoy
    server: istio-envoy
    
    < 
    [{"apiProductDisplayName":"Catstronauts Course Tracks","apiProductId":"tracks","apiVersions":[{"apiId":"tracks-v1","apiVersion":"v1","contact":"support@example.com","customMetadata":{"compatibility":"None"},"description":"REST API for Catstronauts to retrieve data for tracks, authors and modules.","license":"License info, such as MIT","lifecycle":"Supported","termsOfService":"You must authenticate to use this API! And other Terms of Service.","title":"Catstronauts REST API","usagePlans":["bronze","gold","silver"]}]},{"apiProductDisplayName":"Pet Store","apiProductId":"petstore","apiVersions":[{"apiId":"petstore-v1","apiVersion":"v1","contact":"support@example.com","customMetadata":{"compatibility":"None"},"description":"Totally awesome API for all things pets!","license":"License info, such as MIT","lifecycle":"Supported","termsOfService":"You must authenticate to use this API! And other Terms of Service.","title":"Pet Store REST API","usagePlans":["bronze","gold","silver"]}]}]
    * Connection #0 to host developer.example.com left intact
  2. Launch the Gloo UI.

    meshctl dashboard
  3. From the menu, navigate to the APIs > Portals page.

    Figure: Gloo UI view of portals
    Figure: Gloo UI view of portals
    Figure: Gloo UI view of portals
    Figure: Gloo UI view of portals

  4. Click your portal and review the Published APIs and Usage Plans of the portal.

    Figure: Gloo UI detailed view of portals
    Figure: Gloo UI detailed view of portals
    Figure: Gloo UI detailed view of portals
    Figure: Gloo UI detailed view of portals

Next steps

You can continue to use your portal in several ways:

When you are done trying out Portal, you can clean up all of the resources that you created.