Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
- name: UrlShortener
sdkPath: 'src/urlShortener/TypeScript'
specPath: 'spec/Url-Shortener.json'
- name: PowerShellProxy
sdkPath: 'src/powershellProxy/TypeScript'
specPath: 'specs/PowerShell-Proxy.json'
Comment on lines +35 to +37

# Display name of the job
name: Generate NPM Packages
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/Publish-NPM.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ jobs:
- name: UrlShortener
sdkPath: 'src/urlShortener/TypeScript'
specPath: 'spec/Url-Shortener.json'
- name: PowerShellProxy
sdkPath: 'src/powershellProxy/TypeScript'
specPath: 'specs/PowerShell-Proxy.json'
Comment on lines +42 to +44

# Display name of the job
name: Publish - NPM Global Packages
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/Publish-Specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
run: |
DIST_FILE="swagger-ui/dist/swagger-initializer.js"
# Remove the 'url:' property and insert the 'urls:' array
sed -i '/url: /c\ urls: [\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Data-Gateway.json",\n"name": "Data Gateway"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/SHIELD.json",\n"name": "SHIELD"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Url-Shortener.json",\n"name": "SHI - URL Shortener"\n}\n],' "$DIST_FILE"
sed -i '/url: /c\ urls: [\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Data-Gateway.json",\n"name": "Data Gateway"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/SHIELD.json",\n"name": "SHIELD"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Url-Shortener.json",\n"name": "SHI - URL Shortener"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/PowerShell-Proxy.json",\n"name": "SHIELD PowerShell Proxy"\n}\n],' "$DIST_FILE"

# Uploads the built artifact to github pages
- name: Upload Artifact
Expand Down
8 changes: 7 additions & 1 deletion apis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@ apis:
baseUrl: https://api.shilab.com
properties:
- type: x-openapi
url: specs/Data-Gateway.json
url: specs/Data-Gateway.json
- name: SHIELD PowerShell Proxy
description: Authenticated proxy that executes a fixed, server-side allowlisted Security & Compliance (Purview) PowerShell command and returns its structured JSON result.
image: https://www.content.shi.com/SHIcom/images/Global/HeaderFooter/SHI_LOGO_2022_Positive.svg
properties:
- type: x-openapi
url: specs/PowerShell-Proxy.json
407 changes: 407 additions & 0 deletions specs/PowerShell-Proxy.json

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions src/powershellProxy/TypeScript/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Ignore TypeScript source files while allowing library type descriptions
*.ts
!*.d.ts

# Ignore the TypeScript config
tsconfig.json

# Ignore linting config
eslint.config.js

# Ignore the generated SDK source code
/sdk/
2 changes: 2 additions & 0 deletions src/powershellProxy/TypeScript/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Set minimum release age to 1 day
min-release-age=1
21 changes: 21 additions & 0 deletions src/powershellProxy/TypeScript/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 SHI International Corp.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
120 changes: 120 additions & 0 deletions src/powershellProxy/TypeScript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# PowerShell Proxy - TypeScript SDK

This SDK provides a convenient TypeScript client for interacting with the SHIELD PowerShell Proxy service. It is automatically generated from the OpenAPI specification located at [`PowerShell-Proxy.json`](https://github.com/Software-Hardware-Integration-Lab/OpenAPI/blob/main/specs/PowerShell-Proxy.json) using [Kiota](https://github.com/microsoft/kiota).

All typing data is included in the package.

## Installation

Install the SDK using npm:

```bash
npm install @software-hardware-integration-lab/sdk-powershell-proxy
```

## Usage

Here's a basic example of how to use the SDK:

```TypeScript
import { DefaultAzureCredential } from '@azure/identity'
import { powerShellProxyClientFactory, createUntypedString } from '@software-hardware-integration-lab/sdk-powershell-proxy';

/** Authentication session used to authenticate to the PowerShell Proxy. */
const credential = new DefaultAzureCredential();

/** Base URL for your PowerShell Proxy instance. Protocol specifier (`http`/`https`) is required, even for localhost. */
const baseUrl = new URL('https://powershell-proxy.example.com');

/** The third param is the Entra scope for the PowerShell Proxy resource. */
const scopeList = ['api://<powershell-proxy-app-id>/.default'];

/** Configured client for the PowerShell Proxy that can make authenticated web requests against it. */
const powerShellProxyClient = powerShellProxyClientFactory(credential, baseUrl, scopeList);

/**
* Result of executing the allowlisted command. Argument values are generated as `UntypedNode`,
* since the proxy accepts arbitrary JSON-compatible values; use `createUntypedString`/`createUntypedBoolean`
* (both re-exported from this package) to build them.
*/
const results = await powerShellProxyClient.api.proxy.post({
cmdletName: 'Get-DlpCompliancePolicy',
arguments: [
{
name: 'Identity',
value: createUntypedString('Global Policy')
}
]
});

// Check if the command succeeded
if (results?.success === true) {
// Do something with results.result.output/warnings/errors
}
```

### Advanced Usage

You can optionally configure the SDK client with a custom base URL, including support for it being nested deep in a L7 load balancer. `baseUrl` and `scopeList` are both required by the factory:

```TypeScript
/** Custom host and endpoint base to as an example for something behind a layer 7 load balancer, E.g. Azure App Gateway or Azure API Gateway. If in debug mode, run against localhost. */
const customBaseUrl = debugMode ? new URL('http://localhost:7071') : new URL('https://custom-host.example.com/Ballance/Instance1/');

/** Configured instance of the PowerShell Proxy client. */
const customConfiguredClient = powerShellProxyClientFactory(credential, customBaseUrl, scopeList);
```

or with a custom scope (permission) list:

```TypeScript
/**
* `.default` and explicit permissions can't exist in the same custom scope list at the same time, Entra ID doesn't support this.
*
* If not providing the `.default` scope, you can have any number of scopes (permissions) listed in different array indexes.
*/
const customScopes = ['your-custom-scope/something.read.all', 'your-custom-scope/everything.readwrite.all'];

// Initialize the SDK client with custom configuration.
const customConfiguredClient = powerShellProxyClientFactory(credential, baseUrl, customScopes);
```

## Project Structure

- `bin/`: Compiled JavaScript files and type definitions.
- `sdk/`: Source TypeScript files generated by Kiota.
- `api/`: API endpoint definitions.
- `models/`: Data models used by the SDK.

## Development

### Prerequisites

- [Node.js](https://nodejs.org/) - Latest LTS version
- [Kiota](https://github.com/microsoft/kiota)

### Generating the SDK

To regenerate the SDK from the OpenAPI specification, run:

```bash
npm run generate:Sdk
```

### Building the SDK

To build the SDK for production, run:

```bash
npm run build:Prod
```

## License

This SDK is licensed under the [MIT License](./LICENSE).

## Support

For issues or feature requests, please visit the [GitHub Issues page](https://github.com/Software-Hardware-Integration-Lab/OpenAPI/issues).

For more information, visit the [official documentation](https://docs.shilab.com).
7 changes: 7 additions & 0 deletions src/powershellProxy/TypeScript/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig, globalIgnores } from 'eslint/config'
import { eslintConfig } from '@shi-corp/development-utilities/optimized/lint/base.js'

export default defineConfig([
...eslintConfig,
globalIgnores(['sdk/'])
])
42 changes: 42 additions & 0 deletions src/powershellProxy/TypeScript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { assert, assertGuardEquals } from 'typia';
import { AzureIdentityAuthenticationProvider } from '@microsoft/kiota-authentication-azure';
import { FetchRequestAdapter } from '@microsoft/kiota-http-fetchlibrary';
import type { TokenCredential } from '@azure/core-auth';
import { createPowerShellProxyClient } from './sdk/powerShellProxyClient.js';

// Export all of the SDK's types
export type * from './sdk/models/index.js';

export { createUntypedString, createUntypedBoolean } from '@microsoft/kiota-abstractions';

/**
* Function that initializes the PowerShell Proxy SDK.
* @param credential Configured authentication session from Entra ID.
* @param baseUrl Root of the URL that should have endpoints appended to it by the query building system.
* @param scopeList Where each array item is a different Entra ID standard scope to request on token retrieval. E.g. `['api://<powershell-proxy-app-id>/.default']`.
* @returns Configured API client that is able to make requests against the specified PowerShell Proxy instance.
*/
export function powerShellProxyClientFactory(credential: TokenCredential, baseUrl: URL, scopeList: string[]): ReturnType<typeof createPowerShellProxyClient> {
// #region Input Validation
assert(credential);

assertGuardEquals(baseUrl);

assertGuardEquals(scopeList);
// #endregion Input Validation

/** List of hosts that are allowed when making API calls, this is used to prevent token leaks to threat actors. */
const allowedHostList = new Set([baseUrl.host]);

/** Authentication system that will be used to configure the SDK client. */
const authProvider = new AzureIdentityAuthenticationProvider(credential, scopeList, void 0, allowedHostList);

/** Instance of the PowerShell Proxy SDK client initialization configuration. */
const powerShellProxyAdapter = new FetchRequestAdapter(authProvider);

// Set the base URL to be what is provided, since the host name is unique every deployment
powerShellProxyAdapter.baseUrl = baseUrl.href.endsWith('/') ? baseUrl.href.substring(0, baseUrl.href.length - 1) : baseUrl.href;

/** Instance of the API client that can be used for PowerShell Proxy access. */
return createPowerShellProxyClient(powerShellProxyAdapter);
}
Loading
Loading