Rebrand to Grace Solutions; add README, about_ help, Gitea CI/CD, track Module bin #1
@@ -0,0 +1,47 @@
|
||||
name: Publish to PowerShell Gallery
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
if: github.event.pull_request.merged == true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
- name: Build and test module
|
||||
shell: pwsh
|
||||
run: |
|
||||
./build.ps1 -RunTests
|
||||
|
||||
- name: Verify PowerShell Gallery API key is configured
|
||||
shell: pwsh
|
||||
env:
|
||||
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
|
||||
run: |
|
||||
if ([string]::IsNullOrWhiteSpace($env:PSGALLERY_API_KEY)) {
|
||||
throw "Repository secret 'PSGALLERY_API_KEY' is not configured."
|
||||
}
|
||||
|
||||
- name: Publish to PowerShell Gallery
|
||||
shell: pwsh
|
||||
env:
|
||||
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
|
||||
run: |
|
||||
$moduleDir = Join-Path $PWD 'Module/PSInfisicalAPI'
|
||||
Write-Host "Publishing module from: $moduleDir"
|
||||
Publish-Module `
|
||||
-Path $moduleDir `
|
||||
-NuGetApiKey $env:PSGALLERY_API_KEY `
|
||||
-Verbose
|
||||
+3
-2
@@ -4,8 +4,9 @@ obj/
|
||||
Artifacts/
|
||||
Releases/
|
||||
|
||||
## Module bin output is generated by build.ps1
|
||||
Module/PSInfisicalAPI/bin/
|
||||
## Module bin output is generated by build.ps1, but tracked so the module is consumable from source
|
||||
!Module/PSInfisicalAPI/bin/
|
||||
!Module/PSInfisicalAPI/bin/**
|
||||
|
||||
## VS / Rider / VSCode
|
||||
.vs/
|
||||
|
||||
+26
-2
@@ -6,11 +6,23 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 2026.06.02.1648
|
||||
|
||||
- Build produced from commit 430e3a00c921.
|
||||
|
||||
## Unreleased (carried forward)
|
||||
|
||||
## 2026.06.02.1638
|
||||
|
||||
- Build produced from commit 3c47d6ff30ec.
|
||||
|
||||
## Unreleased (carried forward)
|
||||
## Unreleased
|
||||
|
||||
## 2026.06.02.1648
|
||||
|
||||
- Build produced from commit 430e3a00c921.
|
||||
|
||||
## Unreleased (carried forward) (carried forward)
|
||||
|
||||
## 2026.06.02.1611
|
||||
|
||||
@@ -18,11 +30,23 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) loos
|
||||
|
||||
## Unreleased
|
||||
|
||||
## 2026.06.02.1648
|
||||
|
||||
- Build produced from commit 430e3a00c921.
|
||||
|
||||
## Unreleased (carried forward)
|
||||
|
||||
## 2026.06.02.1638
|
||||
|
||||
- Build produced from commit 3c47d6ff30ec.
|
||||
|
||||
## Unreleased (carried forward) (carried forward)
|
||||
## Unreleased
|
||||
|
||||
## 2026.06.02.1648
|
||||
|
||||
- Build produced from commit 430e3a00c921.
|
||||
|
||||
## Unreleased (carried forward) (carried forward) (carried forward)
|
||||
|
||||
### Added
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@{
|
||||
RootModule = 'PSInfisicalAPI.psm1'
|
||||
ModuleVersion = '2026.06.02.1638'
|
||||
ModuleVersion = '2026.06.02.1648'
|
||||
GUID = 'b8a2f3d4-7c51-4d2f-9e6a-1f0c8b3d4e51'
|
||||
Author = 'Alphaeus Mote'
|
||||
CompanyName = ''
|
||||
Copyright = '(c) Alphaeus Mote. All rights reserved.'
|
||||
Description = 'PSInfisicalAPI is a C# binary PowerShell module for the Infisical REST API.'
|
||||
Author = 'Grace Solutions'
|
||||
CompanyName = 'Grace Solutions'
|
||||
Copyright = '(c) Grace Solutions. All rights reserved.'
|
||||
Description = 'PSInfisicalAPI is a C# binary PowerShell module for the Infisical REST API, providing cmdlets for authentication, secret retrieval, and export with automatic environment-variable discovery across Process, User, and Machine scopes.'
|
||||
PowerShellVersion = '5.1'
|
||||
CompatiblePSEditions = @('Desktop','Core')
|
||||
FunctionsToExport = @()
|
||||
@@ -23,10 +23,11 @@
|
||||
TypesToProcess = @('PSInfisicalAPI.Types.ps1xml')
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Infisical','Secrets','API','SecureString')
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = ''
|
||||
CommitHash = '3c47d6ff30ec'
|
||||
Tags = @('Infisical','Secrets','API','SecureString','Vault','Authentication')
|
||||
LicenseUri = 'https://www.gnu.org/licenses/agpl-3.0.html'
|
||||
ProjectUri = 'https://prod.git.gracesolution.info/gsadmin/PSInfisicalAPI'
|
||||
ReleaseNotes = 'See CHANGELOG.md in the project repository for release history.'
|
||||
CommitHash = '430e3a00c921'
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
TOPIC
|
||||
about_PSInfisicalAPI
|
||||
|
||||
SHORT DESCRIPTION
|
||||
PSInfisicalAPI is a C# binary PowerShell module that exposes cmdlets for
|
||||
authenticating against and retrieving secrets from the Infisical REST API,
|
||||
with automatic environment-variable discovery for connection parameters.
|
||||
|
||||
LONG DESCRIPTION
|
||||
The module provides the following cmdlets:
|
||||
|
||||
Connect-Infisical Establish a session.
|
||||
Disconnect-Infisical Clear the current session.
|
||||
Get-InfisicalSecrets List secrets at a path.
|
||||
Get-InfisicalSecret Retrieve a single secret by name.
|
||||
ConvertTo-InfisicalSecretDictionary Convert secret objects to a hashtable.
|
||||
Export-InfisicalSecrets Export secrets to JSON, YAML, XML, or .env.
|
||||
|
||||
Use Get-Help <cmdlet> -Full for parameter details.
|
||||
|
||||
AUTHENTICATION
|
||||
Connect-Infisical supports two parameter sets:
|
||||
|
||||
UniversalAuth -ClientId / -ClientSecret (SecureString)
|
||||
Token -AccessToken (SecureString)
|
||||
|
||||
Common parameters apply to both sets:
|
||||
-BaseUri, -OrganizationId, -ProjectId, -Environment,
|
||||
-SecretPath (default '/'), -ApiVersion (default 'v4'), -PassThru.
|
||||
|
||||
ENVIRONMENT VARIABLE DISCOVERY
|
||||
When any of the Connect-Infisical parameters are omitted, null, or contain
|
||||
only whitespace, the cmdlet scans environment variables in three scopes,
|
||||
in order:
|
||||
|
||||
1. Process
|
||||
2. User
|
||||
3. Machine
|
||||
|
||||
The first matching variable with a non-blank value is used. Explicitly
|
||||
supplied parameter values always win.
|
||||
|
||||
Patterns are case-insensitive and match Infisical's CLI defaults plus
|
||||
common variants such as CLOUDINIT_INFISICAL_* and custom-prefixed names
|
||||
(for example "myapp_infisical_client_id").
|
||||
|
||||
Parameter Example variable names
|
||||
---------------- ----------------------------------------------------------
|
||||
BaseUri INFISICAL_API_URL, INFISICAL_BASE_URL, INFISICAL_HOST
|
||||
OrganizationId INFISICAL_ORG_ID, INFISICAL_ORGANIZATION_ID
|
||||
ProjectId INFISICAL_PROJECT_ID, INFISICAL_WORKSPACE_ID
|
||||
Environment INFISICAL_ENVIRONMENT, INFISICAL_ENV, INFISICAL_ENV_SLUG
|
||||
ClientId INFISICAL_CLIENT_ID, INFISICAL_UNIVERSAL_AUTH_CLIENT_ID
|
||||
ClientSecret INFISICAL_CLIENT_SECRET, INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET
|
||||
AccessToken INFISICAL_TOKEN, INFISICAL_ACCESS_TOKEN, INFISICAL_AUTH_TOKEN
|
||||
SecretPath INFISICAL_SECRET_PATH, INFISICAL_DEFAULT_SECRET_PATH
|
||||
ApiVersion INFISICAL_API_VERSION
|
||||
|
||||
Sensitive values (ClientSecret, AccessToken) are read directly into a
|
||||
read-only SecureString. Discovered values are never written to logs;
|
||||
only the variable name and the scope it was found in are recorded.
|
||||
|
||||
Use -Verbose to see the scan announcement and any discovered variable
|
||||
names.
|
||||
|
||||
EXAMPLES
|
||||
Example 1: Zero-configuration connect (all values from environment).
|
||||
|
||||
Connect-Infisical
|
||||
Get-InfisicalSecrets
|
||||
|
||||
Example 2: Explicit parameters override discovery.
|
||||
|
||||
$secret = Read-Host -AsSecureString 'Client Secret'
|
||||
Connect-Infisical -Environment prod -ClientSecret $secret
|
||||
|
||||
Example 3: Token-based authentication.
|
||||
|
||||
$token = Read-Host -AsSecureString 'Access Token'
|
||||
Connect-Infisical -AccessToken $token
|
||||
|
||||
Example 4: Export to a .env file.
|
||||
|
||||
Get-InfisicalSecrets |
|
||||
Export-InfisicalSecrets -Path .\secrets.env -Format Env
|
||||
|
||||
SECURITY NOTES
|
||||
- SecureString is used for ClientSecret, AccessToken, and any secret
|
||||
payloads returned by the API.
|
||||
- Sanitization is applied before any value reaches the logging pipeline.
|
||||
- Sessions are stored in process-local state only and never persisted.
|
||||
|
||||
SEE ALSO
|
||||
Get-Help Connect-Infisical -Full
|
||||
Get-Help Get-InfisicalSecrets -Full
|
||||
Get-Help Export-InfisicalSecrets -Full
|
||||
https://infisical.com/docs/api-reference/overview/introduction
|
||||
@@ -1,2 +1,128 @@
|
||||
# PSInfisicalAPI
|
||||
|
||||
A C# binary PowerShell module for interacting with the [Infisical](https://infisical.com/) REST API. It provides cmdlets for authentication, secret retrieval, structured export, and includes automatic environment-variable discovery so connections can be established with little or no inline configuration.
|
||||
|
||||
- License: AGPL-3.0
|
||||
- Author: Grace Solutions
|
||||
- Target framework: .NET Standard 2.0 (compatible with Windows PowerShell 5.1 and PowerShell 7+)
|
||||
|
||||
## Installation
|
||||
|
||||
### From the PowerShell Gallery
|
||||
|
||||
```powershell
|
||||
Install-Module -Name PSInfisicalAPI -Scope CurrentUser
|
||||
Import-Module -Name PSInfisicalAPI
|
||||
```
|
||||
|
||||
### From source
|
||||
|
||||
```powershell
|
||||
git clone https://prod.git.gracesolution.info/gsadmin/PSInfisicalAPI.git
|
||||
cd PSInfisicalAPI
|
||||
pwsh -NoProfile -ExecutionPolicy Bypass -File .\build.ps1 -RunTests
|
||||
Import-Module -Name .\Module\PSInfisicalAPI
|
||||
```
|
||||
|
||||
## Cmdlets
|
||||
|
||||
| Cmdlet | Purpose |
|
||||
| ------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| `Connect-Infisical` | Establish a session using Universal Auth or a pre-issued access token. |
|
||||
| `Disconnect-Infisical` | Clear the current session. |
|
||||
| `Get-InfisicalSecrets` | List secrets at a given path / environment. |
|
||||
| `Get-InfisicalSecret` | Retrieve a single secret by name. |
|
||||
| `ConvertTo-InfisicalSecretDictionary` | Convert secret objects into a `Hashtable` keyed by `SecretKey`. |
|
||||
| `Export-InfisicalSecrets` | Export secrets to JSON, YAML, XML, or `.env` format. |
|
||||
|
||||
Use `Get-Help <Cmdlet> -Full` for parameter details and `Get-Help about_PSInfisicalAPI` for the module overview.
|
||||
|
||||
## Quick start
|
||||
|
||||
```powershell
|
||||
$secureSecret = Read-Host -AsSecureString 'Client Secret'
|
||||
|
||||
$connection = Connect-Infisical `
|
||||
-BaseUri 'https://app.infisical.com' `
|
||||
-OrganizationId '00000000-0000-0000-0000-000000000000' `
|
||||
-ProjectId '11111111-1111-1111-1111-111111111111' `
|
||||
-Environment 'dev' `
|
||||
-ClientId 'machine-identity-client-id' `
|
||||
-ClientSecret $secureSecret `
|
||||
-PassThru
|
||||
|
||||
Get-InfisicalSecrets -SecretPath '/'
|
||||
Disconnect-Infisical
|
||||
```
|
||||
|
||||
## Automatic environment-variable discovery
|
||||
|
||||
When `Connect-Infisical` is invoked with one or more parameters missing (or set to whitespace/empty), the cmdlet searches environment variables and uses the first value it finds. This makes invocation as simple as `Connect-Infisical` when variables are set up in advance.
|
||||
|
||||
### Scope precedence
|
||||
|
||||
Scopes are searched in order; the first matching variable with a non-blank value wins:
|
||||
|
||||
1. `Process`
|
||||
2. `User`
|
||||
3. `Machine`
|
||||
|
||||
### Patterns
|
||||
|
||||
The resolver matches case-insensitively against patterns aligned with Infisical's CLI defaults plus common variants such as `CLOUDINIT_INFISICAL_*` and custom-prefixed names (e.g., `myapp_infisical_client_id`).
|
||||
|
||||
| Parameter | Example variable names matched |
|
||||
| ----------------- | ------------------------------------------------------------------------------------ |
|
||||
| `BaseUri` | `INFISICAL_API_URL`, `INFISICAL_BASE_URL`, `INFISICAL_HOST` |
|
||||
| `OrganizationId` | `INFISICAL_ORG_ID`, `INFISICAL_ORGANIZATION_ID` |
|
||||
| `ProjectId` | `INFISICAL_PROJECT_ID`, `INFISICAL_WORKSPACE_ID` |
|
||||
| `Environment` | `INFISICAL_ENVIRONMENT`, `INFISICAL_ENV`, `INFISICAL_ENV_SLUG` |
|
||||
| `ClientId` | `INFISICAL_CLIENT_ID`, `INFISICAL_UNIVERSAL_AUTH_CLIENT_ID` |
|
||||
| `ClientSecret` | `INFISICAL_CLIENT_SECRET`, `INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET` |
|
||||
| `AccessToken` | `INFISICAL_TOKEN`, `INFISICAL_ACCESS_TOKEN`, `INFISICAL_AUTH_TOKEN` |
|
||||
| `SecretPath` | `INFISICAL_SECRET_PATH`, `INFISICAL_DEFAULT_SECRET_PATH` |
|
||||
| `ApiVersion` | `INFISICAL_API_VERSION` |
|
||||
|
||||
Sensitive values (`ClientSecret`, `AccessToken`) are read directly into a read-only `SecureString` and never logged.
|
||||
|
||||
### Zero-configuration example
|
||||
|
||||
```powershell
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_API_URL', 'https://app.infisical.com', 'User')
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_ORG_ID', '00000000-0000-0000-0000-000000000000', 'User')
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_PROJECT_ID', '11111111-1111-1111-1111-111111111111', 'User')
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_ENVIRONMENT', 'dev', 'User')
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_CLIENT_ID', 'machine-identity-client-id', 'User')
|
||||
[Environment]::SetEnvironmentVariable('INFISICAL_CLIENT_SECRET', 'super-secret-value', 'User')
|
||||
|
||||
Connect-Infisical
|
||||
Get-InfisicalSecrets
|
||||
```
|
||||
|
||||
### Mixed example (explicit values override discovery)
|
||||
|
||||
Explicit parameters always win over discovered values; blank/whitespace explicit values trigger discovery.
|
||||
|
||||
```powershell
|
||||
Connect-Infisical -Environment 'prod' # everything else discovered from environment
|
||||
```
|
||||
|
||||
### Logging
|
||||
|
||||
The resolver emits a single verbose line announcing the scan and one informational line per discovered variable (variable name and scope; values are never logged). Use `-Verbose` to see the scan announcement.
|
||||
|
||||
## Building
|
||||
|
||||
```powershell
|
||||
pwsh -NoProfile -ExecutionPolicy Bypass -File .\build.ps1 -RunTests
|
||||
```
|
||||
|
||||
The script builds the binary, runs unit tests, publishes binaries into `Module/PSInfisicalAPI/bin/`, regenerates the manifest, and validates that the module imports.
|
||||
|
||||
## Continuous integration
|
||||
|
||||
`.gitea/workflows/publish-psgallery.yml` publishes the module to the PowerShell Gallery whenever a pull request is merged into `main`. The workflow expects a repository secret named `PSGALLERY_API_KEY` containing a valid Gallery API key.
|
||||
|
||||
## License
|
||||
|
||||
Distributed under the GNU Affero General Public License v3.0. See [LICENSE](LICENSE).
|
||||
|
||||
@@ -90,10 +90,10 @@ function Write-Manifest {
|
||||
RootModule = 'PSInfisicalAPI.psm1'
|
||||
ModuleVersion = '$ModuleVersion'
|
||||
GUID = '$ModuleGuid'
|
||||
Author = 'Alphaeus Mote'
|
||||
CompanyName = ''
|
||||
Copyright = '(c) Alphaeus Mote. All rights reserved.'
|
||||
Description = 'PSInfisicalAPI is a C# binary PowerShell module for the Infisical REST API.'
|
||||
Author = 'Grace Solutions'
|
||||
CompanyName = 'Grace Solutions'
|
||||
Copyright = '(c) Grace Solutions. All rights reserved.'
|
||||
Description = 'PSInfisicalAPI is a C# binary PowerShell module for the Infisical REST API, providing cmdlets for authentication, secret retrieval, and export with automatic environment-variable discovery across Process, User, and Machine scopes.'
|
||||
PowerShellVersion = '5.1'
|
||||
CompatiblePSEditions = @('Desktop','Core')
|
||||
FunctionsToExport = @()
|
||||
@@ -111,9 +111,10 @@ function Write-Manifest {
|
||||
TypesToProcess = @('PSInfisicalAPI.Types.ps1xml')
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Infisical','Secrets','API','SecureString')
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = ''
|
||||
Tags = @('Infisical','Secrets','API','SecureString','Vault','Authentication')
|
||||
LicenseUri = 'https://www.gnu.org/licenses/agpl-3.0.html'
|
||||
ProjectUri = 'https://prod.git.gracesolution.info/gsadmin/PSInfisicalAPI'
|
||||
ReleaseNotes = 'See CHANGELOG.md in the project repository for release history.'
|
||||
CommitHash = '$CommitHash'
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -187,7 +187,7 @@ Example shape:
|
||||
RootModule = 'PSInfisicalAPI.psm1'
|
||||
ModuleVersion = 'yyyy.MM.dd.HHmm'
|
||||
GUID = '<stable-guid>'
|
||||
Author = 'Alphaeus Mote'
|
||||
Author = 'Grace Solutions'
|
||||
CompanyName = ''
|
||||
Copyright = ''
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
<AssemblyVersion>$(BuildAssemblyVersion)</AssemblyVersion>
|
||||
<FileVersion>$(BuildAssemblyVersion)</FileVersion>
|
||||
<InformationalVersion>$(BuildVersion)</InformationalVersion>
|
||||
<Company />
|
||||
<Authors>Alphaeus Mote</Authors>
|
||||
<Company>Grace Solutions</Company>
|
||||
<Authors>Grace Solutions</Authors>
|
||||
<Product>PSInfisicalAPI</Product>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
Reference in New Issue
Block a user