Rebrand to Grace Solutions; add README, about_ help, Gitea CI/CD, track Module bin

This commit is contained in:
GraceSolutions
2026-06-02 12:49:39 -04:00
parent 430e3a00c9
commit 5801b4774a
12 changed files with 321 additions and 24 deletions
+47
View File
@@ -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
View File
@@ -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
View File
@@ -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
+10 -9
View File
@@ -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
+126
View File
@@ -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).
+9 -8
View File
@@ -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,10 +111,11 @@ function Write-Manifest {
TypesToProcess = @('PSInfisicalAPI.Types.ps1xml')
PrivateData = @{
PSData = @{
Tags = @('Infisical','Secrets','API','SecureString')
ProjectUri = ''
ReleaseNotes = ''
CommitHash = '$CommitHash'
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
View File
@@ -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'
+2 -2
View File
@@ -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>