# Backstage Integration

The Apono Backstage integration allows you to configure Apono as a custom plugin in your Backstage app. This plugin brings Apono's Just-in-Time (JIT) access management to the forefront, making it easily accessible to developers within Backstage. With this integration, you can now effortlessly connect your Backstage app to Apono and manage access directly from the Backstage interface.

Other benefits:

• Backstage Theme Support – The Apono plugin now inherits Backstage’s theme and applies it to the embedded iframe for a consistent look and feel.

• Dynamic Theme Updates – The plugin communicates theme changes to the iframe in real time, ensuring seamless visual consistency.

## Prerequisites

* Generate RSA Private & Public Keys using OpenSSL using the following commands. Be sure to copy both public & private keys encoded as base64 to use later.

<pre class="language-bash"><code class="lang-bash"><strong># Generate RSA Private Key
</strong><strong>openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
</strong>
<strong># Display private_key.pem content encoded as base64
</strong>cat private_key.pem | base64

# Generate RSA Public Key
openssl rsa -pubout -in private_key.pem -out public_key.pem

# Display public_key.pem content encoded as base64
cat public_key.pem | base64
</code></pre>

{% hint style="info" %}
Apono uses OpenSSL keys to ensure secure communication between your Backstage app and the Apono API. By using OpenSSL keys, you can securely interact with the Apono API, ensuring that your data remains protected and your identity is verified.
{% endhint %}

* [Create a Backstage app](https://backstage.io/docs/getting-started/) with an intention to add an existing plugin to it. For more information on Apono plugin for Backstage [frontend](https://github.com/apono-io/backstage-plugin-apono) and [backend](https://github.com/apono-io/backstage-plugin-apono-backend) app.
* Install yarn (`yarn install`) and install any dependencies.

***

## Configuration steps <a href="#configuration-steps" id="configuration-steps"></a>

### In Apono <a href="#in-apono" id="in-apono"></a>

1. On [**Backstage**](https://app.apono.io/catalog/add-integration/backstage) integration page, provide the following information about your Backstage environment:

| Field            | Value                 | Required |
| ---------------- | --------------------- | -------- |
| Integration Name | The integration name. | Yes      |

2. Under **Secret Store**, paste your base64-encoded public key.

<figure><img src="https://1094436629-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6MBfUGvblSdAz31yJXm%2Fuploads%2Fgit-blob-435e9ac89ad904e6dd5f17d8011ff4320382e974%2Fimage%20(1)%20(1)%20(1).png?alt=media" alt=""><figcaption></figcaption></figure>

3. Click **Connect**.

***

### In Backstage

#### Add Apono plugin to Backstage Frontend App

1. To create a new Apono frontend plugin, run the following on your command line from the root of your project.

```bash
yarn --cwd packages/app add @apono-io/backstage-plugin-apono
```

{% hint style="info" %}
The plugin is added to the `app` package, rather than the root **package.json**. Backstage Apps are set up as monorepos with [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). Since CircleCI is a frontend UI plugin, it goes in `app` rather than `backend`.
{% endhint %}

2. Update router for the `AponoPage` inside **packages/app/src/App.tsx**.

```tsx
import { AponoPage } from '@apono-io/backstage-plugin-apono';

// Inside your App component's routes
<Route path="/apono" element={<AponoPage />} />
```

3. In your **app-config.yaml** file, add the Apono client URL to your Content Security Policy to allow the Apono plugin to load its content in an iframe.

```tsx
backend:
  csp:
    frame-src: ["'self'", "https://backstage-client.apono.io"]
```

***

#### Add Apono plugin to Backstage Backend App

To attach and run the Apono plugin, you will make some modifications to your backend.

1. Add Apono plugin to your backend system packages as dependencies. Run the following command.

<pre class="language-bash"><code class="lang-bash"># from the repository root
<strong>yarn --cwd packages/backend add @apono-io/backstage-plugin-apono-backend
</strong></code></pre>

2. Update **packages/backend/src/index.ts**.

```tsx
backend.add(import('@apono-io/backstage-plugin-apono-backend'));
```

3. In **app-config.yaml**, configure Backstage to connect to the Apono API.

{% code overflow="wrap" fullWidth="false" %}

```tsx
apono:
  publicKey: ${APONO_PUBLIC_KEY} # Base64 encoded RSA public key with minimum 2048 bits length
  privateKey: ${APONO_PRIVATE_KEY} # Base64 encoded RSA private key with minimum 2048 bits length
```

{% endcode %}

***

## Backstage Sidebar Update

* (Example) Add Apono plugin to Backstage sidebar. Update the Backstage sidebar in **packages/app/src/components/Root/Root.tsx** with the following code.

```tsx
import { AponoPage } from '@apono-io/backstage-plugin-apono';

export const Root = ({ children }: PropsWithChildren<{}>) => (
  <SidebarPage>
    <Sidebar>
      <SidebarLogo />
      {/* ... */}
      <SidebarGroup label="Menu" icon={<MenuIcon />}>
        {/* ... */}
        <SidebarItem icon={ExtensionIcon} to="/apono" text="Apono" />
        {/* ... */}
        <SidebarDivider />
        {/* ... */}
      </SidebarGroup>
    </Sidebar>
  </SidebarPage>
);
```

<figure><img src="https://1094436629-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6MBfUGvblSdAz31yJXm%2Fuploads%2Fgit-blob-ccf4d1894ede403f7f7910dce86c07087b384752%2Fimage%20(2).png?alt=media" alt=""><figcaption></figcaption></figure>

***

## Troubleshooting

* The following error occurs when you try to enter Apono app on your Backstage app: `Request failed with status code 401 / Failed to load application`

<figure><img src="https://1094436629-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6MBfUGvblSdAz31yJXm%2Fuploads%2Fgit-blob-4a9a072d9a7d0676f4ff3e690027899f14bfa8c2%2Fimage%20(47).png?alt=media" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1094436629-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6MBfUGvblSdAz31yJXm%2Fuploads%2Fgit-blob-582ad96d2e4b1a5b229881a144b89748d460307d%2FScreenshot%202024-10-13%20at%207.15.57%E2%80%AFPM.png?alt=media" alt=""><figcaption></figcaption></figure>

**This issue might occur** when you accidentally delete your Apono Backstage integration.

**To resolve this issue,** recreate the Backstage integration in your Apono account with the Public Key defined in your Backstage app.

To find your public key, go to **app-config.yaml** on your Backstage app repo and look for:

{% code overflow="wrap" %}

```
{...}
apono:
  publicKey: ${APONO_PUBLIC_KEY}
{...}
```

{% endcode %}
