Contentstack LogoContentstack Logo

Build an App using App Permissions

Why App Permissions Matter

Marketplace apps often interact with Contentstack APIs. Apps Permissions ensure apps only have defined access to the resources they need; improving security, trust, and governance.

Benefits for different roles:

  • Developers: Clear APIs, fewer errors, smoother builds.
  • Security/Compliance: Least privilege access, better auditability.
  • PM/Admins: Safer Marketplace apps, well defined access.

Overview

In this guide, we will walk through building an app example for a Quick Info Dashboard App. We will demonstrate how an app can leverage Apps Permissions to securely interact with Contentstack APIs.

This example app highlights a real-world scenario where stack-level statistics (content types, entries, and assets) are displayed in a Dashboard location.

Prerequisites

Quick Info Dashboard App

The Quick Info Dashboard App displays stack-level statistics (for example, Content Types, Entries, and Assets).

Output.png

Create an App

The best place to start a new project is by cloning the Marketplace App Boilerplate. It has all the components you need for rapid dashboard UI Location development.

Clone the Marketplace Boilerplate repository and run the following commands:

npm install
npm run dev

Register the App in Developer Hub

To register an app in Developer Hub, perform the steps given below:

  1. Log in to your Contentstack account.
  2. On the Dashboard page, click the Developer Hub icon.
  3. Click the + New App button.
  4. Contentstack supports two types of Apps based on two categories: Standard and Machine to Machine. Here, we will use the Standard application.

    Additional Resource: Refer to the Creating an App in Developer Hub documentation to know more about Standard and Machine to Machine app categories.

  5. In the Create Standard App modal, select the App Type, and give a suitable app Name (Quick Info Dashboard) and an optional Description as shown below:Creating_App.png
  6. Click Create. You are redirected to the UI Locations landing page.UI_Locations_Tab.png
  7. Navigate back to the UI Locations tab, click the vertical ellipses, then click the + Add UI Location button to add as needed.Add_UI_Location.png
    • Stack Dashboard: Enter a Name, use /stack-dashboardas the Path, and select the Default Width, then click Save to apply and store your configuration. This setup ensures your app appears on the Stack Dashboard.

      Note: The name for each UI Location is optional, and can be used to override the default app name.

      Stack_Dashboard_Location.png

      Note: The Save button becomes active once all required fields are completed.

  8. Navigate to the Hosting tab. You will see Hosting with Launch or Custom Hosting options. Select the Custom Hosting option to enter the hosted URL of your application. Enter the App URL and click Save to apply and confirm your hosting configuration. While running the application locally, select Custom Hosting and use your local app URL (for example, (http://localhost:3000).

    After development, you can host your application using Contentstack Launch.

    Custom_Hosting.png

Configure Permissions

Permissions control which Contentstack APIs your app can access.

For the Quick Info App, configure the following permissions in Developer Hub. To do so, follow the steps below:

  1. Click the UI Locations tab.
  2. Go to the Permissions section. Permissions.png
  3. Select all the permissions you want to add.Selected_Permissions.png
    ModuleAccessEndpoint
    Content Types/v3/content_types
    Entries/v3/content_types/{uid}/entries
    Assets/v3/assets

Security Best Practices:

  • Rotate tokens periodically (do not rely on long-lived tokens).
  • Use .env files and add them to .gitignore (never commit secrets).
  • Log permission errors (403s) for audit tracking.
  • Review permissions regularly, remove unused ones.

Implement API Integration

Run the following command to navigate to the Dashboard Widget folder:

cd src/containers/DashboardWidget

Create a new file named StackMetrics.tsx and add the following code snippet.

This component fetches stack statistics for Content Types, Entries, and Assets using the Contentstack Management SDK and displays them in a widget format.

import { useState, useEffect, useCallback } from "react";
import { useAppSdk } from "../../common/hooks/useAppSdk";
import { useManagementClient } from "../../common/hooks/useManagementClient";

export const StackMetrics = () => {
  const appSdk = useAppSdk();
  const managementClient = useManagementClient();
  const [stats, setStats] = useState({ contentTypes: 0, entries: 0, assets: 0 });

  const fetchStackStats = useCallback(async () => {
    if (!appSdk || !managementClient) return;

    const stack = managementClient.stack({ api_key: appSdk.ids.apiKey });

    const { count: contentTypeCount } = await stack.contentType().query({ include_count: true }).find();
    const { count: assetCount } = await stack.asset().query({ include_count: true }).find();

    // Fetch all content types and count total entries
    const contentTypes = await stack.contentType().query().find();
    const entryCounts = await Promise.all(
      contentTypes.items.map(async (ct) => {
        const res = await stack.contentType(ct.uid).entry().query({ include_count: true }).find();
        return res.count ?? 0;
      })
    );

    setStats({
      contentTypes: contentTypeCount,
      entries: entryCounts.reduce((a, b) => a + b, 0),
      assets: assetCount,
    });
  }, [appSdk, managementClient]);

  useEffect(() => {
    fetchStackStats();
  }, [fetchStackStats]);

  return (
    <div>
      <h3>Stack Metrics</h3>
      <ul>
        <li>Content Types: {stats.contentTypes}</li>
        <li>Entries: {stats.entries}</li>
        <li>Assets: {stats.assets}</li>
      </ul>
    </div>
  );
};

Note: For the complete implementation, refer to the StackMetrics GitHub repo.

Import your component:

Open ./src/containers/DashboardWidget/StackDashboard.tsx and import your component. You need to replace the entire code with the following code snippet:

import "../index.css";
import "./StackDashboard.css";
import { StackMetrics } from "./StackMetrics";
const StackDashboardExtension = () => {
  return (
    <div className="layout-container">
      <StackMetrics />
    </div>
  );
};
export default StackDashboardExtension;

Warning: Without the Content Types: Read permission, this call will fail with a 403 permission denied error.

Install and Test Your App

Local development:

To install and test the app, follow the steps below:

  1. Initiate your development server by running the following commands:
    npm run dev
  2. Now, install the Quick Info Dashboard app using the following steps:
    1. Navigate to Developer Hub in Contentstack.
    2. Go to the app, and click the Install App button. Install_App.png
    3. On the permissions screen, select a Stack and mark the checkbox to accept the Terms of Service and Privacy Policy. Once done, click the Authorize and Install button. Authorize_and_Install.png
  3. You will see the Stack Dashboard UI location configured for the app. Click Open Stack to view the app on the Stack Dashboard. Open_Stack.png
  4. You will see the Quick Info Dashboard app as shown below:
    Output.png

    If you do not use the example app configuration, the Marketplace App Boilerplate shows the following configuration on the Stack Dashboard.

    Dashboard_Boilerplate.png

The app is now available as a Stack Dashboard app that utilizes the Permissions feature in conjunction with Management SDK and the AppSDK Adapter.

Full permissions test:

  • Enable all required permissions in Developer Hub
  • Verify all statistics display correctly
  • Test navigation links to Content Types, Entries, and Assets

Limited permissions test:

  • Disable specific permissions (e.g., Assets)
  • Verify graceful error handling
  • Check that permission error messages are clear and actionable

Troubleshooting

  • UI Location not visible: Check UI Location in Developer Hub.
  • App SDK not initialized: Ensure provider wraps components + installs the app.
  • 403 errors: Verify Permissions in Developer Hub.
  • CORS/network errors: Match hosting URL with Developer Hub configuration.

Resources and Links

Was this article helpful?
^