# @aws/plugin-aws-apps-backend-for-backstage

> # Harmonix on AWS Backend

Latest version **0.4.0** (published 2025-04-18) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @aws/plugin-aws-apps-backend-for-backstage
pnpm add @aws/plugin-aws-apps-backend-for-backstage
yarn add @aws/plugin-aws-apps-backend-for-backstage
bun add @aws/plugin-aws-apps-backend-for-backstage
```

## Health

**Score 45/100 (D)** — status: stable.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 0.4.0 |
| Published | 2025-04-18 |
| First published | 2023-05-09 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 30 |
| Unpacked size | 282 KB |
| Known vulnerabilities | 0 (+2 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 309 |
| Author | Amazon Web Services |
| Maintainers | awsjim, awsacw, z-sourcecode |

## Links

- npm: https://www.npmjs.com/package/@aws/plugin-aws-apps-backend-for-backstage
- Repository: https://github.com/awslabs/harmonix
- Homepage: https://github.com/awslabs/harmonix#readme
- Issues: https://github.com/awslabs/harmonix-backend/issues
- npm.io page: https://npm.io/package/@aws/plugin-aws-apps-backend-for-backstage

## Dependencies (30)

- [yn](https://npm.io/package/yn.md) ^4.0.0
- [yaml](https://npm.io/package/yaml.md) ^2.7.1
- [express](https://npm.io/package/express.md) ^4.17.1
- [octokit](https://npm.io/package/octokit.md) ^3.1.2
- [node-fetch](https://npm.io/package/node-fetch.md) ^2.6.7
- [@octokit/rest](https://npm.io/package/@octokit/rest.md) >=20.0.1
- [@aws-sdk/types](https://npm.io/package/@aws-sdk/types.md) ^3.775.0
- [@backstage/config](https://npm.io/package/@backstage/config.md) ^1.3.2
- [@backstage/errors](https://npm.io/package/@backstage/errors.md) ^1.2.7
- [@aws-sdk/client-s3](https://npm.io/package/@aws-sdk/client-s3.md) ^3.777.0
- [@aws-sdk/client-ecs](https://npm.io/package/@aws-sdk/client-ecs.md) ^3.777.0
- [@aws-sdk/client-eks](https://npm.io/package/@aws-sdk/client-eks.md) ^3.777.0
- [@aws-sdk/client-ssm](https://npm.io/package/@aws-sdk/client-ssm.md) ^3.777.0
- [@aws-sdk/client-sts](https://npm.io/package/@aws-sdk/client-sts.md) ^3.777.0
- [@aws-sdk/client-lambda](https://npm.io/package/@aws-sdk/client-lambda.md) ^3.777.0
- [express-promise-router](https://npm.io/package/express-promise-router.md) ^4.1.0
- [@aws-sdk/client-dynamodb](https://npm.io/package/@aws-sdk/client-dynamodb.md) ^3.777.0
- [@aws-sdk/util-arn-parser](https://npm.io/package/@aws-sdk/util-arn-parser.md) ^3.723.0
- [@backstage/backend-common](https://npm.io/package/@backstage/backend-common.md) ^0.25.0
- [@backstage/catalog-client](https://npm.io/package/@backstage/catalog-client.md) ^1.9.1
- [@backstage/backend-defaults](https://npm.io/package/@backstage/backend-defaults.md) ^0.9.0
- [@backstage/backend-plugin-api](https://npm.io/package/@backstage/backend-plugin-api.md) ^1.3.0
- [octokit-commit-multiple-files](https://npm.io/package/octokit-commit-multiple-files.md) ^5.0.2
- [@aws-sdk/client-cloudformation](https://npm.io/package/@aws-sdk/client-cloudformation.md) ^3.777.0
- [@backstage/plugin-catalog-node](https://npm.io/package/@backstage/plugin-catalog-node.md) ^1.16.3
- [@aws-sdk/client-cloudwatch-logs](https://npm.io/package/@aws-sdk/client-cloudwatch-logs.md) ^3.777.0
- [@aws-sdk/client-resource-groups](https://npm.io/package/@aws-sdk/client-resource-groups.md) ^3.777.0
- [@aws-sdk/client-secrets-manager](https://npm.io/package/@aws-sdk/client-secrets-manager.md) ^3.777.0
- [@aws-sdk/credential-provider-node](https://npm.io/package/@aws-sdk/credential-provider-node.md) ^3.777.0
- [@aws/plugin-aws-apps-common-for-backstage](https://npm.io/package/@aws/plugin-aws-apps-common-for-backstage.md) ^0.4.0

## Recent versions

- 0.4.0 (latest) — 2025-04-18
- 0.3.4 — 2024-08-16
- 0.3.2 — 2024-02-26
- 0.3.1 — 2024-01-25
- 0.3.0 — 2024-01-23
- 0.2.0 — 2023-09-27
- 0.1.2 — 2023-05-10
- 0.1.0 — 2023-05-09

## README

<!-- 
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 
-->
# Harmonix on AWS Backend

This is the backend part of the Harmonix on AWS plugin.  Its key responsibilities:

1. **Catalog contributions** - the plugin provides the AWSEnvironment and AWSEnvironmentProvider entity Kinds, including processing and validation of the entities.
2. **Authentication / Authorization** - the plugin assumes defined roles with permisisons for provisioning infrastructure resources for a target environment account.
3. **Audit** - the plugin provides services to record requested actions, user id and IAM role, timestamps, success/failure results, and additional information for the purpose of capturing audit-level information about the actions performed by the AWS Apps Backstage plugin against AWS.
4. **Proxying AWS requests** - the plugin provides API endpoints for specific AWS service actions.  It receives requests on these endpoints, validates the request, and proxies the request and response between Backstage and a specified AWS account and region.

## Installation

```sh
# From your Backstage root directory
yarn add --cwd packages/backend @aws/plugin-aws-apps-backend-for-backstage@0.2.0
```

## Configuration

Setup for the AWS Apps backend requires a router for Backstage, making the catalog aware of the new entity kinds.

### Configure a router

Create a `awsApps.ts` file in the `packages/backend/src/plugins/`directory.  This file creates a router for the Harmonix on AWS backend.

```ts
// packages/backend/src/plugins/awsApps.ts

import {createRouter} from '@aws/plugin-aws-apps-backend-for-backstage'
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import {DefaultIdentityClient } from '@backstage/plugin-auth-node';

export default async function createPlugin({
  logger,
  discovery,
  config,
  permissions,
}: PluginEnvironment): Promise<Router> {
  return await createRouter({
    logger: logger,
    userIdentity: DefaultIdentityClient.create({
      discovery,
      issuer: await discovery.getExternalBaseUrl('auth'),
    }),
    config,
    permissions,
  });
}
```

You can now add the router to Backstage in the `packages/backend/src/plugins/index.ts` file

```diff
...
+ import awsApps from './plugins/awsApps'

...
// add the environment and router
  const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
  const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
  const authEnv = useHotMemoize(module, () => createEnv('auth'));
  const proxyEnv = useHotMemoize(module, () => createEnv('proxy'));
  const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
  const searchEnv = useHotMemoize(module, () => createEnv('search'));
  const appEnv = useHotMemoize(module, () => createEnv('app'));
+  const awsAppsEnv = useHotMemoize(module, () => createEnv('aws-apps-backend'));

  const apiRouter = Router();
  apiRouter.use('/catalog', await catalog(catalogEnv));
  apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
  apiRouter.use('/auth', await auth(authEnv));
  apiRouter.use('/techdocs', await techdocs(techdocsEnv));
  apiRouter.use('/proxy', await proxy(proxyEnv));
  apiRouter.use('/search', await search(searchEnv));
+ apiRouter.use('/aws-apps-backend', await awsApps(awsAppsEnv));

...
```

### Configure the catalog

Add to the Backstage catalog so that it's aware of the processors for the AWSEnvironment and AWSEnvironmentProvider entity kinds.

```diff
// packages/backend/src/plugins/catalog.ts

import { CatalogBuilder } from '@backstage/plugin-catalog-backend';
import { ScaffolderEntitiesProcessor } from '@backstage/plugin-catalog-backend-module-scaffolder-entity-model';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
+ import { AWSEnvironmentEntitiesProcessor, AWSEnvironmentProviderEntitiesProcessor} from '@aws/plugin-aws-apps-backend-for-backstage';

export default async function createPlugin(
  env: PluginEnvironment,
): Promise<Router> {
  const builder = await CatalogBuilder.create(env);
  
  builder.addProcessor(new ScaffolderEntitiesProcessor());

+ // Custom processors
+ builder.addProcessor(new AWSEnvironmentEntitiesProcessor());
+ builder.addProcessor(new AWSEnvironmentProviderEntitiesProcessor());

  const { processingEngine, router } = await builder.build();

  await processingEngine.start();

  return router;
```

### Permission Framework Policy

The Harmonix on AWS backend plugin leverages the [Backstage permissions framework](https://backstage.io/docs/permissions/overview) to contribute a permission decision for access to audit entries.  If you would like to implement a policy for your Backstage instance to control access to audit entries you will start with the [Permission framework getting started documentation](https://backstage.io/docs/permissions/getting-started) to set up the base framework.  
With the framework in place, you can leverage the `readOpaAppAuditPermission` permission in your policy definition to restrict access to audit entries.

```ts
// Example of policy decision in a policy

import { readOpaAppAuditPermission } from '@aws/plugin-aws-apps-common-for-backstage';
...

export class permissionPolicy implements PermissionPolicy {
  async handle(
    request: PolicyQuery,
    user?: BackstageIdentityResponse
  ): Promise<PolicyDecision> {
    ...
    // restrict access to audit entries if the user is only a member of the Villians group
    const VILLIANS_GROUP = stringifyEntityRef({ kind: 'Group', namespace: DEFAULT_NAMESPACE, name: "villians" });
    const ownershipGroups = user?.identity.ownershipEntityRefs || [];
    if (
      isPermission(request.permission, readOpaAppAuditPermission) && 
      ownershipGroups.length === 1 && 
      ownershipGroups.includes(VILLIANS_GROUP)
    ) {
      return { result: AuthorizationResult.DENY };
    }

    ...
  }
}

```

Additional permission decisions and resources are planned for future releases.

---
_Source: https://npm.io/package/@aws/plugin-aws-apps-backend-for-backstage · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
