19 Commits
Author SHA1 Message Date
shadowdaoandClaude Sonnet 5.5 0d10004ab7 Merge ci/postgres-tests: Postgres-backed DB test job
ci / db-tests (push) Failing after 5m35s
ci / check (push) Successful in 7m22s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:13:13 -07:00
shadowdaoandClaude Sonnet 5.5 954fda6325 CI: exclude container-spawning test packages from db-tests
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 14:13:11 -07:00
shadowdaoandClaude Sonnet 5.5 6ab93be603 CI: add Postgres-backed db-tests job
Builds the pre-migrated test image from testing/dbtest/docker, runs the root
module's DB-backed tests on push/nightly/manual. Skips estimate tests that
also fail on untouched upstream.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 11:44:10 -07:00
shadowdaoandClaude Sonnet 5.5 764bb27d54 Merge upgrade-compat: seamless in-place upgrade from Boundary
ci / check (push) Successful in 21m11s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 11:14:31 -07:00
shadowdaoandClaude Sonnet 5.5 d07030a10b Make in-place upgrade from HashiCorp Boundary seamless
Linux packages: migrate /etc/boundary.d to /etc/threshold.d without
clobbering, reuse the boundary service user, carry over service
enablement with a boundary.service alias, provide a boundary command.
Docker: accept /boundary/config.hcl, boundary command, /boundary symlink.
CLI: deprecation notice when invoked as boundary (stderr only).
Dev mode: also create *.threshold.dev aliases.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 11:12:29 -07:00
shadowdaoandClaude Sonnet 5.5 80ece9c4fc Bump moby/sys/user to v0.4.1; document accepted test-only docker/docker findings
ci / check (push) Successful in 7m13s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:49:41 -07:00
shadowdaoandClaude Sonnet 5.5 de2ee74928 CI: don't run on tag pushes
ci / check (push) Failing after 18m6s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:37:57 -07:00
shadowdaoandClaude Sonnet 5.5 f4b9a16788 Merge plugins/threshold-forks: repoint plugin mains at Threshold forks
ci / check (push) Failing after 17m43s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:37:42 -07:00
shadowdaoandClaude Sonnet 5.5 5fdfc8c2cc Repoint plugin mains at Threshold forks and renamed sdk
- boundary host/storage plugin mains use repo.anhonesthost.net/CyberCoveLLC/threshold-plugin-{aws,azure,gcp,minio}
- all mains import threshold/sdk (no more duplicate proto registrations)
- main module paths renamed under repo.anhonesthost.net/CyberCoveLLC/threshold

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:37:42 -07:00
shadowdaoandClaude Sonnet 5.5 44fd64f588 api: depend on published sdk v0.1.0 (drop local replace)
ci / check (push) Failing after 5m49s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:35:07 -07:00
shadowdaoandClaude Sonnet 5.5 a5ba9460e5 Merge rebrand/phase-b: rename Go module path to repo.anhonesthost.net/CyberCoveLLC/threshold
ci / check (push) Failing after 19m6s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:34:24 -07:00
shadowdaoandClaude Sonnet 5.5 962d708fdd Rename Go module paths to repo.anhonesthost.net/CyberCoveLLC/threshold
Rename root, api and sdk module paths (imports, go.mod, go_package,
ldflags, build scripts, buf configs) and regenerate protobuf/gateway
code with the project's pinned toolchain. Wire identifiers unchanged.
api gets a local replace for sdk; root/api/sdk require v0.1.0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:33:41 -07:00
shadowdaoandClaude Sonnet 5.5 443e483a16 Merge rebrand/phase-a: Threshold CLI/binary, packaging, docs, legacy fallbacks
ci / check (push) Failing after 12m27s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:23:51 -07:00
shadowdaoandClaude Sonnet 5.5 613415624e Merge security/go-1.26.9: Go 1.26.9, x/net, AWS SDK bumps, Gitea CI
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:23:50 -07:00
shadowdaoandClaude Sonnet 5.5 b30dead452 Bump golang.org/x/net to v0.60.0 (GO-2026-6603/6610/6611/6612/6617) and gofmt
Go fuzz test / Fuzz grants.Parse (push) Successful in 4m29s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:21:04 -07:00
shadowdaoandClaude Sonnet 5.5 ab4ed3c9e5 Rebrand user-visible CLI text; add legacy fallbacks for keyring, cache dir and version prefix
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:20:06 -07:00
shadowdaoandClaude Sonnet 5.5 4cb3bda43a Add fork notice, NOTICE file, README/CONTRIBUTING rewrite; drop HashiCorp logo assets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 09:53:17 -07:00
shadowdaoandClaude Sonnet 5.5 5f5d35b9ff Rename binary to threshold and update build/release packaging
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 09:53:13 -07:00
shadowdaoandClaude Sonnet 5.5 306960d24b Add THRESHOLD_* env var support with BOUNDARY_* fallback
Introduce api.Getenv/api.LookupEnv which prefer THRESHOLD_X and fall back to legacy BOUNDARY_X; use them for user-facing env var reads.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 09:45:44 -07:00
1938 changed files with 10521 additions and 9194 deletions

No files matched your search

+61
View File
@@ -3,6 +3,7 @@ name: ci
on:
push:
branches: [main]
tags-ignore: ["**"]
pull_request:
workflow_dispatch:
schedule:
@@ -48,3 +49,63 @@ jobs:
fi
- name: osv-scanner
run: osv-scanner scan source -r .
# DB-backed Go tests need Postgres 16 with a pre-migrated template database.
# The image is built from testing/dbtest/docker (not HashiCorp's Docker Hub
# image) and published on 127.0.0.1:55432 because the tests hardcode loopback.
# Skipped on pull requests to spare the shared runner pool.
db-tests:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 120
env:
TEST_DB_PORT: "55432"
PG_CONTAINER: threshold-sql-tests-${{ github.run_id }}
steps:
- name: require docker
run: |
if ! docker info >/dev/null 2>&1; then
echo "::error::this runner has no usable docker; db-tests need it"; exit 1
fi
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: .go-version
cache: false
- name: start postgres (pre-migrated template)
shell: bash
run: |
set -euo pipefail
docker build -q -t threshold-test-pg:16 -f testing/dbtest/docker/Dockerfile.16-alpine testing/dbtest/docker
mkdir -p "$RUNNER_TEMP/benchmark_dumps"
docker run -d --name "$PG_CONTAINER" -p "$TEST_DB_PORT:5432" \
-e POSTGRES_PASSWORD=boundary -e POSTGRES_USER=boundary -e POSTGRES_DB=boundary \
-e PGDATA=/pgdata --mount type=tmpfs,destination=/pgdata \
-v "$PWD/internal/db/schema/migrations:/migrations" \
-v "$RUNNER_TEMP/benchmark_dumps:/benchmark_dumps" \
threshold-test-pg:16 -c config_file=/etc/postgresql/postgresql.conf
# init scripts run on a temporary server first; wait for the real one
for i in $(seq 1 120); do
if docker logs "$PG_CONTAINER" 2>&1 | grep -q "init process complete" \
&& docker exec "$PG_CONTAINER" pg_isready -U boundary -d boundary >/dev/null 2>&1; then
echo "postgres ready"; exit 0
fi
sleep 3
done
docker logs "$PG_CONTAINER" | tail -30; echo "::error::postgres did not become ready"; exit 1
- name: go test (root module, DB-backed)
shell: bash
run: |
# Excluded: tests that start their own dev-DB/Vault containers via
# dockertest and then dial the mapped host port, which is unreachable
# from inside this job's container (internal/cmd/commands/server also
# fails the same way on untouched upstream).
pkgs=$(go list ./... | grep -v -E '/testing/internal/e2e|/enos/|/internal/tests/(cli|api)|/internal/cmd/commands/server$|/internal/credential/vault$|/internal/daemon/controller$|/internal/daemon/controller/handlers/credentialstores$')
# *Estimated*Count / ListDeletedStoreIds depend on pg planner stats and
# also fail on untouched upstream Boundary (verified); skipped here.
go test $pkgs -count=1 -p 2 -timeout 90m \
-skip 'EstimatedCount|EstimatedCredentialCount|EstimatedLibraryCount|ListDeletedStoreIds'
- name: stop postgres
if: always()
run: docker rm -f -v "$PG_CONTAINER" || true
+1
View File
@@ -282,6 +282,7 @@ jobs:
rpm_depends: "openssl"
config_dir: ".release/linux/package/"
preinstall: ".release/linux/preinst"
postinstall: ".release/linux/postinst"
postremove: ".release/linux/postrm"
- name: Add Linux Package names to env
run: |
+1 -1
View File
@@ -7,7 +7,7 @@ if [[ $remote_url == *"boundary-enterprise"* ]]; then
exit 0
fi
if [ -f cmd/boundary/package_registration_ent.go ]; then
if [ -f cmd/threshold/package_registration_ent.go ]; then
echo "Found enterprise file while pushing to oss remote"
exit 1
fi
-44
View File
@@ -1,44 +0,0 @@
# Copyright IBM Corp. 2020, 2026
# SPDX-License-Identifier: BUSL-1.1
schema = 1
artifacts {
zip = [
"boundary_${version}_darwin_amd64.zip",
"boundary_${version}_darwin_arm64.zip",
"boundary_${version}_freebsd_386.zip",
"boundary_${version}_freebsd_amd64.zip",
"boundary_${version}_freebsd_arm.zip",
"boundary_${version}_linux_386.zip",
"boundary_${version}_linux_amd64.zip",
"boundary_${version}_linux_arm.zip",
"boundary_${version}_linux_arm64.zip",
"boundary_${version}_netbsd_386.zip",
"boundary_${version}_netbsd_amd64.zip",
"boundary_${version}_netbsd_arm.zip",
"boundary_${version}_openbsd_386.zip",
"boundary_${version}_openbsd_amd64.zip",
"boundary_${version}_openbsd_arm.zip",
"boundary_${version}_solaris_amd64.zip",
"boundary_${version}_windows_386.zip",
"boundary_${version}_windows_amd64.zip",
]
rpm = [
"boundary-${version_linux}-1.aarch64.rpm",
"boundary-${version_linux}-1.armv7hl.rpm",
"boundary-${version_linux}-1.i386.rpm",
"boundary-${version_linux}-1.x86_64.rpm",
]
deb = [
"boundary_${version_linux}-1_amd64.deb",
"boundary_${version_linux}-1_arm64.deb",
"boundary_${version_linux}-1_armhf.deb",
"boundary_${version_linux}-1_i386.deb",
]
container = [
"boundary_default_linux_386_${version}_${commit_sha}.docker.tar",
"boundary_default_linux_amd64_${version}_${commit_sha}.docker.tar",
"boundary_default_linux_arm64_${version}_${commit_sha}.docker.tar",
"boundary_default_linux_arm_${version}_${commit_sha}.docker.tar",
]
}
+8 -9
View File
@@ -1,16 +1,15 @@
# Boundary Docker Image
# Threshold Docker Image
The root of this repository contains the officially supported HashiCorp Dockerfile to build the hashicorp/boundary docker image.
The dev docker image should be built for local dev and testing,
while the production docker image is built in CI and makes use of CI-built binaries.
The official docker image is built using the official binaries from releases.hashicorp.com.
The root of this repository contains the Dockerfile used to build the Threshold
docker image. Threshold is a community fork of HashiCorp Boundary Community
Edition and is not affiliated with or endorsed by HashiCorp or IBM.
The dev docker image is built from a locally built binary (`./bin/threshold`),
while the production docker image makes use of CI-built binaries.
## Build
See the Makefile targets in the root of this repository
for building Boundary images in either development or release modes:
See the Makefile targets in the root of this repository for building images:
- `make docker-build-dev`
- `make docker-multiarch-build`
- `make docker-build`
- `make docker`
+39 -29
View File
@@ -1,46 +1,56 @@
<!---
This is used for the Overview tab for the boundary docker image on hub.docker.com
https://hub.docker.com/r/hashicorp/boundary
This is used for the Overview tab for the threshold docker image on hub.docker.com
https://repo.anhonesthost.net/CyberCoveLLC/threshold
--->
# Boundary
# Threshold
## Usage
See the latest updates to the Dockerfile for this image in our
[GitHub repository](https://github.com/hashicorp/boundary).
[repository](https://repo.anhonesthost.net/CyberCoveLLC/threshold).
### Dev Mode
Due to the limitations of `boundary dev` running and maintaining a postgres docker container,
Due to the limitations of `threshold dev` running and maintaining a postgres docker container,
it's not recommended to run `dev` mode inside docker.
To do so will require knowledge of running [docker-in-docker](https://hub.docker.com/_/docker),
and the caveats associated with it.
### Default Configuration
The default behavior of the Boundary docker image is to run `boundary server -config /boundary/config.hcl`.
The default behavior of the Threshold docker image is to run `threshold server -config /threshold/config.hcl`.
The included `config.hcl` file is meant to serve as an example,
and is not suitable for actual deployment.
Please see the comments within the file for more information;
full configuration details can be found on Boundary's documentation site.
full configuration details can be found on Threshold's documentation site.
#### Upgrading from the HashiCorp Boundary image
The configuration directory moved from `/boundary` to `/threshold`. For
compatibility, `/boundary` is a symlink to `/threshold` inside the image, a
`-config /boundary/config.hcl` argument (or a config mounted at
`/boundary/config.hcl`) is still honored with a deprecation warning, `boundary`
is accepted as a command name, and `BOUNDARY_*` environment variables are
mirrored to `THRESHOLD_*`. Please migrate your mounts and arguments to the
`/threshold` and `THRESHOLD_*` names.
### Postgres
The usage instructions in this README assume you have an external postgres database (version 12 or greater) to run boundary server with.
The usage instructions in this README assume you have an external postgres database (version 12 or greater) to run threshold server with.
If you want to get started quickly, you can start a local postgres in docker:
```bash
docker run -it -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres postgres
```
The postgres URL setting is defined with `env://BOUNDARY_POSTGRES_URL` so it can be easily set with `-e` during docker run:
The postgres URL setting is defined with `env://THRESHOLD_POSTGRES_URL` so it can be easily set with `-e` during docker run:
```bash
docker run \
--network host \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
hashicorp/boundary
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
repo.anhonesthost.net/cybercovellc/threshold
```
### Database Init
@@ -52,8 +62,8 @@ initialize the database using the default `config.hcl`:
```bash
docker run \
--network host \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
hashicorp/boundary database init -config /boundary/config.hcl
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
repo.anhonesthost.net/cybercovellc/threshold database init -config /threshold/config.hcl
```
If you want to run this with your own `config.hcl` (assuming `config.hcl` is located at `$(pwd)/config.hcl`):
@@ -61,22 +71,22 @@ If you want to run this with your own `config.hcl` (assuming `config.hcl` is loc
```bash
docker run \
--network host \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
-v "$(pwd)":/boundary/ \
hashicorp/boundary database init -config /boundary/config.hcl
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
-v "$(pwd)":/threshold/ \
repo.anhonesthost.net/cybercovellc/threshold database init -config /threshold/config.hcl
```
### Database Migration
If you are updating to a newer version of boundary with a database instance
If you are updating to a newer version of threshold with a database instance
that was initialized with an older version,
you will need to apply the database migrations:
```bash
docker run \
--network host \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
hashicorp/boundary database migrate -config /boundary/config.hcl
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
repo.anhonesthost.net/cybercovellc/threshold database migrate -config /threshold/config.hcl
```
If you want to run this with your own `config.hcl` (assuming `config.hcl` is located at `$(pwd)/config.hcl`):
@@ -84,14 +94,14 @@ If you want to run this with your own `config.hcl` (assuming `config.hcl` is loc
```bash
docker run \
--network host \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
-v "$(pwd)":/boundary/ \
hashicorp/boundary database migrate -config /boundary/config.hcl
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
-v "$(pwd)":/threshold/ \
repo.anhonesthost.net/cybercovellc/threshold database migrate -config /threshold/config.hcl
```
### Server
Start a Boundary server using the default `config.hcl`:
Start a Threshold server using the default `config.hcl`:
```bash
docker run \
@@ -99,11 +109,11 @@ docker run \
-p 9200:9200 \
-p 9201:9201 \
-p 9202:9202 \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
hashicorp/boundary
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
repo.anhonesthost.net/cybercovellc/threshold
```
Start a Boundary server using your own `config.hcl`, assuming it's located at `$(pwd)/config.hcl`:
Start a Threshold server using your own `config.hcl`, assuming it's located at `$(pwd)/config.hcl`:
```bash
docker run \
@@ -111,7 +121,7 @@ docker run \
-p 9200:9200 \
-p 9201:9201 \
-p 9202:9202 \
-v "$(pwd)":/boundary/ \
-e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
hashicorp/boundary
-v "$(pwd)":/threshold/ \
-e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@0.0.0.0:5432/postgres?sslmode=disable' \
repo.anhonesthost.net/cybercovellc/threshold
```
+5 -5
View File
@@ -14,12 +14,12 @@ controller {
database {
# This configuration setting requires the user to execute the container with the URL as an env var
# to connect to the Boundary postgres DB. An example of how this can be done assuming the postgres
# to connect to the Threshold postgres DB. An example of how this can be done assuming the postgres
# database is running as a container and you're using Docker for Mac (replace host.docker.internal with
# localhost if you're on Linux):
#
# $ docker run -e 'BOUNDARY_POSTGRES_URL=postgresql://postgres:postgres@host.docker.internal:5432/postgres?sslmode=disable' [other options] boundary:[version]
url = "env://BOUNDARY_POSTGRES_URL"
# $ docker run -e 'THRESHOLD_POSTGRES_URL=postgresql://postgres:postgres@host.docker.internal:5432/postgres?sslmode=disable' [other options] threshold:[version]
url = "env://THRESHOLD_POSTGRES_URL"
}
public_cluster_addr = "env://HOSTNAME"
@@ -48,7 +48,7 @@ listener "tcp" {
tls_disable = true
}
# Root KMS configuration block: this is the root key for Boundary
# Root KMS configuration block: this is the root key for Threshold
# Use a production KMS such as AWS KMS in production installs
kms "aead" {
purpose = "root"
@@ -67,7 +67,7 @@ kms "aead" {
key_id = "global_worker-auth"
}
# Recovery KMS block: configures the recovery key for Boundary
# Recovery KMS block: configures the recovery key for Threshold
# Use a production KMS such as AWS KMS for production installs
kms "aead" {
purpose = "recovery"
+100 -18
View File
@@ -12,24 +12,102 @@ set -e
# Prevent core dumps
ulimit -c 0
# If the user is trying to run Boundary directly with some arguments, then
# pass them to Boundary.
# Backwards compatibility: honor legacy BOUNDARY_* environment variables by
# mirroring them to their THRESHOLD_* equivalents when the latter are unset.
# (The Threshold CLI itself also falls back to BOUNDARY_* for CLI variables.)
for legacy_name in $(env | sed -n 's/^\(BOUNDARY_[A-Za-z0-9_]*\)=.*/\1/p'); do
new_name="THRESHOLD_${legacy_name#BOUNDARY_}"
if [ -z "$(printenv "$new_name")" ]; then
export "$new_name=$(printenv "$legacy_name")"
fi
done
# Backwards compatibility: the legacy HashiCorp Boundary image kept its config
# in /boundary/config.hcl and ran the "boundary" binary. Accept both.
# (The *_TEST_* overrides exist only for .release/docker/test-entrypoint.sh.)
NEW_CONFIG_PATH=${THRESHOLD_ENTRYPOINT_TEST_NEW:-/threshold/config.hcl}
LEGACY_CONFIG_PATH=${THRESHOLD_ENTRYPOINT_TEST_LEGACY:-/boundary/config.hcl}
STOCK_CONFIG_COPY=${THRESHOLD_ENTRYPOINT_TEST_STOCK:-/usr/share/threshold/config.hcl.default}
legacy_warn() {
>&2 echo "WARNING: $1 (deprecated Boundary-era path); please move to /threshold/config.hcl"
}
# Prints the config path that should actually be used for a requested -config
# path. Prefers /threshold/config.hcl, falling back to /boundary/config.hcl.
resolve_config_path() {
case "$1" in
"$NEW_CONFIG_PATH")
# The image ships a stock demo config at /threshold/config.hcl. If it is
# still the stock one and the user supplied their own legacy config
# (for example by mounting it at /boundary/config.hcl on an image
# where /boundary is a real directory), use theirs.
if [ -f "$LEGACY_CONFIG_PATH" ] && ! [ "$LEGACY_CONFIG_PATH" -ef "$NEW_CONFIG_PATH" ] \
&& [ -f "$STOCK_CONFIG_COPY" ] && cmp -s "$NEW_CONFIG_PATH" "$STOCK_CONFIG_COPY"; then
legacy_warn "using $LEGACY_CONFIG_PATH"
echo "$LEGACY_CONFIG_PATH"
return
fi
;;
"$LEGACY_CONFIG_PATH")
if [ -f "$LEGACY_CONFIG_PATH" ]; then
legacy_warn "using $LEGACY_CONFIG_PATH"
elif [ -f "$NEW_CONFIG_PATH" ]; then
legacy_warn "$LEGACY_CONFIG_PATH not found, falling back to $NEW_CONFIG_PATH"
echo "$NEW_CONFIG_PATH"
return
fi
;;
esac
echo "$1"
}
# Accept the legacy command name: "docker run <image> boundary ..." (or an
# entrypoint/command override that invokes boundary) runs threshold.
if [ "$1" = 'boundary' ]; then
>&2 echo "WARNING: the 'boundary' command is deprecated; use 'threshold' (running threshold)"
shift
set -- threshold "$@"
fi
# If the user is trying to run Threshold directly with some arguments, then
# pass them to Threshold.
if [ "${1:0:1}" = '-' ]; then
set -- boundary "$@"
set -- threshold "$@"
fi
if [ "$1" = 'server' ]; then
shift
set -- boundary server \
set -- threshold server \
"$@"
elif boundary --help "$1" 2>&1 | grep -q "boundary $1"; then
elif threshold --help "$1" 2>&1 | grep -q "threshold $1"; then
# We can't use the return code to check for the existence of a subcommand, so
# we have to use grep to look for a pattern in the help output.
set -- boundary "$@"
set -- threshold "$@"
fi
# If we are running Boundary, make sure it executes as the proper user.
if [ "$1" = 'boundary' ]; then
# Rewrite -config arguments (see resolve_config_path).
if [ "$1" = 'threshold' ]; then
_n=$#
_prev=""
while [ "$_n" -gt 0 ]; do
_a=$1
shift
_n=$((_n - 1))
case "$_prev" in
-config | --config) _new=$(resolve_config_path "$_a") ;;
*) _new=$_a ;;
esac
case "$_a" in
-config=* | --config=*) _new="${_a%%=*}=$(resolve_config_path "${_a#*=}")" ;;
esac
_prev=$_a
set -- "$@" "$_new"
done
fi
# If we are running Threshold, make sure it executes as the proper user.
if [ "$1" = 'threshold' ]; then
is_root=0
if [ "$(id -u)" = '0' ]; then
is_root=1
@@ -38,23 +116,27 @@ if [ "$1" = 'boundary' ]; then
if [ -z "$SKIP_CHOWN" ]; then
if [ "$is_root" = '1' ]; then
# If the config dir is bind mounted then chown it
if [ "$(stat -c %u /boundary)" != "$(id -u boundary)" ]; then
chown -R boundary:boundary /boundary || echo "Could not chown /boundary (may not have appropriate permissions)"
if [ "$(stat -c %u /threshold)" != "$(id -u threshold)" ]; then
chown -R threshold:threshold /threshold || echo "Could not chown /threshold (may not have appropriate permissions)"
fi
# Legacy config dir, when it is a real directory (not the symlink to /threshold)
if [ -d /boundary ] && [ ! -L /boundary ] && [ "$(stat -c %u /boundary)" != "$(id -u threshold)" ]; then
chown -R threshold:threshold /boundary || echo "Could not chown /boundary (may not have appropriate permissions)"
fi
else
>&2 echo "SKIP_CHOWN not set but running non-root; skipping chown /boundary"
>&2 echo "SKIP_CHOWN not set but running non-root; skipping chown /threshold"
fi
fi
if [ -z "$SKIP_SETCAP" ]; then
if [ "$is_root" = '1' ]; then
# Allow mlock to avoid swapping Boundary memory to disk
setcap cap_ipc_lock=+ep $(readlink -f $(which boundary))
# Allow mlock to avoid swapping Threshold memory to disk
setcap cap_ipc_lock=+ep $(readlink -f $(which threshold))
# In the case Boundary has been started in a container without IPC_LOCK privileges
if ! boundary -version 1>/dev/null 2>/dev/null; then
>&2 echo "Couldn't start Boundary with IPC_LOCK. Disabling IPC_LOCK, please use --privileged or --cap-add IPC_LOCK"
setcap cap_ipc_lock=-ep $(readlink -f $(which boundary))
# In the case Threshold has been started in a container without IPC_LOCK privileges
if ! threshold -version 1>/dev/null 2>/dev/null; then
>&2 echo "Couldn't start Threshold with IPC_LOCK. Disabling IPC_LOCK, please use --privileged or --cap-add IPC_LOCK"
setcap cap_ipc_lock=-ep $(readlink -f $(which threshold))
fi
else
>&2 echo "SKIP_SETCAP not set but running non-root; skipping setcap"
@@ -62,7 +144,7 @@ if [ "$1" = 'boundary' ]; then
fi
if [ "$is_root" = '1' ]; then
set -- su-exec boundary "$@"
set -- su-exec threshold "$@"
fi
fi
+107
View File
@@ -0,0 +1,107 @@
#!/bin/bash
# Self-contained test for the legacy-path handling in docker-entrypoint.sh.
#
# Runs the real entrypoint with a fake "threshold" binary and temporary
# config paths (via the THRESHOLD_ENTRYPOINT_TEST_* overrides). No Docker or
# root needed. The entrypoint is written for busybox/ash; bash is used here
# because it accepts the same ${var:off:len} syntax.
#
# Usage: .release/docker/test-entrypoint.sh
set -u
HERE=$(cd "$(dirname "$0")" && pwd)
ENTRY="$HERE/docker-entrypoint.sh"
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
FAILS=0
PASSES=0
check() { # check DESC EXPECTED ACTUAL
if [ "$2" = "$3" ]; then
PASSES=$((PASSES + 1))
else
FAILS=$((FAILS + 1))
echo "FAIL: $1" >&2
echo " expected: $2" >&2
echo " actual: $3" >&2
fi
}
mkdir -p "$WORK/bin" "$WORK/new" "$WORK/legacy"
# Fake threshold: print the argument vector on one line, "|"-separated.
cat >"$WORK/bin/threshold" <<'EOF'
#!/bin/sh
case "$1" in --help) [ "$2" = threshold ] || echo "threshold $2"; exit 0 ;; esac
IFS='|'
echo "ARGS:$*"
EOF
cat >"$WORK/bin/su-exec" <<'EOF'
#!/bin/sh
shift
exec "$@"
EOF
chmod 755 "$WORK/bin/threshold" "$WORK/bin/su-exec"
NEWCFG="$WORK/new/config.hcl"
LEGCFG="$WORK/legacy/config.hcl"
STOCK="$WORK/stock.hcl"
run() { # run ARGS... ; prints "<stdout-args> || <stderr>"
PATH="$WORK/bin:$PATH" SKIP_CHOWN=1 SKIP_SETCAP=1 \
THRESHOLD_ENTRYPOINT_TEST_NEW="$NEWCFG" \
THRESHOLD_ENTRYPOINT_TEST_LEGACY="$LEGCFG" \
THRESHOLD_ENTRYPOINT_TEST_STOCK="$STOCK" \
bash "$ENTRY" "$@" 2>"$WORK/err" | grep '^ARGS:'
}
stderr() { cat "$WORK/err"; }
echo "stock demo config" >"$STOCK"
cp "$STOCK" "$NEWCFG"
# 1. default invocation, stock config, no legacy file -> unchanged, no warning
out=$(run server -config "$NEWCFG")
check "default path kept" "ARGS:server|-config|$NEWCFG" "$out"
check "no warning by default" "" "$(stderr | grep -c deprecated | grep -v '^0$')"
# 2. user's own /threshold config (differs from stock) wins over a legacy file
echo "user threshold config" >"$NEWCFG"
echo "user legacy config" >"$LEGCFG"
out=$(run server -config "$NEWCFG")
check "custom threshold config preferred" "ARGS:server|-config|$NEWCFG" "$out"
# 3. stock /threshold config + user legacy config -> legacy used with warning
cp "$STOCK" "$NEWCFG"
out=$(run server -config "$NEWCFG")
check "legacy config used when threshold is stock" "ARGS:server|-config|$LEGCFG" "$out"
check "deprecation warning printed" "1" "$(stderr | grep -c 'WARNING.*Boundary-era')"
# 4. explicit legacy path that exists -> used with warning
out=$(run server -config "$LEGCFG")
check "explicit legacy path kept" "ARGS:server|-config|$LEGCFG" "$out"
check "explicit legacy warns" "1" "$(stderr | grep -c 'WARNING')"
# 5. explicit legacy path that does not exist -> fall back to threshold path
rm -f "$LEGCFG"
out=$(run server -config "$LEGCFG")
check "missing legacy falls back to threshold" "ARGS:server|-config|$NEWCFG" "$out"
# 6. -config=PATH form
echo "user legacy config" >"$LEGCFG"
out=$(run server -config="$LEGCFG")
check "-config=path form" "ARGS:server|-config=$LEGCFG" "$out"
rm -f "$LEGCFG"
out=$(run server -config="$LEGCFG")
check "-config=path fallback" "ARGS:server|-config=$NEWCFG" "$out"
# 7. legacy command name
out=$(run boundary version)
check "boundary command accepted" "ARGS:version" "$out"
check "boundary command warns" "1" "$(stderr | grep -c "'boundary' command is deprecated")"
# 8. unrelated args untouched
out=$(run database init -config "$NEWCFG" -skip-auth-method-creation)
check "other args preserved" "ARGS:database|init|-config|$NEWCFG|-skip-auth-method-creation" "$out"
echo "passed: $PASSES, failed: $FAILS"
[ "$FAILS" -eq 0 ]
@@ -15,7 +15,7 @@
# # supply the url, or "env://" to name an environment variable
# # that contains the URL.
# database {
# url = "postgresql://boundary:boundarydemo@postgres.yourdomain.com:5432/boundary"
# url = "postgresql://threshold:thresholddemo@postgres.yourdomain.com:5432/threshold"
# }
# }
@@ -42,7 +42,7 @@
# purpose = "cluster"
# }
# # Root KMS configuration block: this is the root key for Boundary
# # Root KMS configuration block: this is the root key for Threshold
# # Use a production KMS such as AWS KMS in production installs
# kms "aead" {
# purpose = "root"
@@ -61,7 +61,7 @@
# key_id = "global_worker-auth"
# }
# # Recovery KMS block: configures the recovery key for Boundary
# # Recovery KMS block: configures the recovery key for Threshold
# # Use a production KMS such as AWS KMS for production installs
# kms "aead" {
# purpose = "recovery"
@@ -1,23 +0,0 @@
[Unit]
Description="HashiCorp Boundary - Identity-based access management for dynamic infrastructure"
Documentation=https://www.boundaryproject.io/docs
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
EnvironmentFile=-/etc/boundary.d/boundary.env
User=boundary
Group=boundary
ProtectSystem=full
ProtectHome=read-only
ExecStart=/usr/bin/boundary server -config=/etc/boundary.d/boundary.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitMEMLOCK=infinity
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,26 @@
[Unit]
Description="Threshold (fork of HashiCorp Boundary CE) - Identity-based access management for dynamic infrastructure"
Documentation=https://repo.anhonesthost.net/CyberCoveLLC/threshold
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
# Legacy HashiCorp Boundary environment file (BOUNDARY_* variables are still
# honored). Read first so that threshold.env takes precedence.
EnvironmentFile=-/etc/boundary.d/boundary.env
EnvironmentFile=-/etc/threshold.d/threshold.env
User=threshold
Group=threshold
ProtectSystem=full
ProtectHome=read-only
ExecStart=/usr/bin/threshold server -config=/etc/threshold.d/threshold.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitMEMLOCK=infinity
[Install]
WantedBy=multi-user.target
+163
View File
@@ -0,0 +1,163 @@
#!/bin/sh
# Threshold package post-install script (deb "postinst" / rpm "%post").
#
# Completes an in-place upgrade from a HashiCorp Boundary install. Safe to run
# repeatedly; never deletes user configuration or data:
#
# 1. If the legacy "boundary" user exists and there is no "threshold" user,
# run the service as "boundary" through a systemd drop-in, so existing
# data/log directory ownership keeps working.
# 2. Provide a "boundary" command: /usr/bin/boundary -> threshold, only if
# /usr/bin/boundary does not exist.
# 3. If the legacy boundary.service is enabled/active: stop it, carry its
# enablement over to threshold.service, and start threshold.service if the
# old service was running (rolling back to boundary.service if that fails).
# 4. Make "systemctl <verb> boundary" address threshold.service by adding a
# boundary.service alias symlink, unless something already exists there.
#
# THRESHOLD_PKG_ROOT exists only so the logic can be exercised by
# .release/linux/test/test-package-scripts.sh without root; it is empty in
# normal use.
set -eu
ROOT="${THRESHOLD_PKG_ROOT:-}"
NEW_USER="threshold"
LEGACY_USER="boundary"
UNIT="threshold.service"
LEGACY_UNIT="boundary.service"
SYSTEMD_ETC="$ROOT/etc/systemd/system"
DROPIN_DIR="$SYSTEMD_ETC/threshold.service.d"
DROPIN="$DROPIN_DIR/10-legacy-boundary-user.conf"
DROPIN_MARK="# Managed by the Threshold package (legacy boundary user reuse)"
say() {
echo "threshold postinst: $*" >&2
}
user_exists() {
id -u "$1" >/dev/null 2>&1
}
have_systemd() {
command -v systemctl >/dev/null 2>&1 && [ -d "$ROOT/run/systemd/system" ]
}
# Print the Id= systemd resolves a unit name to (follows aliases).
unit_id() {
systemctl show -p Id "$1" 2>/dev/null | sed -n 's/^Id=//p'
}
unit_load_state() {
systemctl show -p LoadState "$1" 2>/dev/null | sed -n 's/^LoadState=//p'
}
# Where the packaged threshold.service lives (merged-usr or not).
packaged_unit_path() {
for _p in "$ROOT/usr/lib/systemd/system/$UNIT" "$ROOT/lib/systemd/system/$UNIT"; do
if [ -f "$_p" ]; then
echo "${_p#"$ROOT"}"
return 0
fi
done
return 1
}
# --- 1. legacy service user -------------------------------------------------
if user_exists "$LEGACY_USER" && ! user_exists "$NEW_USER"; then
_group=$(id -gn "$LEGACY_USER" 2>/dev/null || echo "$LEGACY_USER")
_content="$DROPIN_MARK
[Service]
User=$LEGACY_USER
Group=$_group"
if [ -e "$DROPIN" ] && ! grep -qF "$DROPIN_MARK" "$DROPIN"; then
say "leaving existing $DROPIN untouched (not managed by this package)"
else
mkdir -p "$DROPIN_DIR"
_tmp="$DROPIN.tmp.$$"
printf '%s\n' "$_content" >"$_tmp"
mv -f "$_tmp" "$DROPIN"
say "service will run as existing user '$LEGACY_USER' ($DROPIN)"
fi
fi
# --- 2. "boundary" command ----------------------------------------------------
_bin="$ROOT/usr/bin/boundary"
if [ ! -e "$_bin" ] && [ ! -L "$_bin" ]; then
if [ -e "$ROOT/usr/bin/threshold" ]; then
ln -s threshold "$_bin"
fi
elif [ ! -L "$_bin" ]; then
say "/usr/bin/boundary is still the HashiCorp Boundary binary (old package installed); leaving it"
say "after removing the old package run: ln -s threshold /usr/bin/boundary"
fi
# --- 3 + 4. legacy systemd service ----------------------------------------------
if have_systemd; then
_alias="$SYSTEMD_ETC/$LEGACY_UNIT"
if [ -L "$_alias" ]; then
# Already aliased (previous run): nothing to migrate.
:
elif [ -e "$_alias" ]; then
say "$_alias is a custom unit; not touching the legacy service."
say "move it away and re-run the package configuration to migrate."
else
_id=$(unit_id "$LEGACY_UNIT")
_load=$(unit_load_state "$LEGACY_UNIT")
_legacy_present=0
_was_enabled=0
_was_active=0
if [ "$_id" = "$LEGACY_UNIT" ] && [ "$_load" = "loaded" ]; then
_legacy_present=1
if systemctl is-enabled --quiet "$LEGACY_UNIT" 2>/dev/null; then
_was_enabled=1
fi
if systemctl is-active --quiet "$LEGACY_UNIT" 2>/dev/null; then
_was_active=1
fi
fi
# Only act on upgrades: a legacy unit or legacy config is present.
if [ "$_legacy_present" = 1 ] || [ -d "$ROOT/etc/boundary.d" ]; then
if [ "$_was_active" = 1 ]; then
say "stopping $LEGACY_UNIT"
systemctl stop "$LEGACY_UNIT" || say "could not stop $LEGACY_UNIT"
fi
if [ "$_was_enabled" = 1 ]; then
systemctl disable "$LEGACY_UNIT" >/dev/null 2>&1 || say "could not disable $LEGACY_UNIT"
fi
# Alias symlink so `systemctl restart boundary` reaches threshold.service.
if _unit_path=$(packaged_unit_path); then
mkdir -p "$SYSTEMD_ETC"
ln -s "$_unit_path" "$_alias"
fi
systemctl daemon-reload || true
if [ "$_was_enabled" = 1 ]; then
systemctl enable "$UNIT" >/dev/null 2>&1 || say "could not enable $UNIT"
fi
if [ "$_was_active" = 1 ]; then
if systemctl start "$UNIT"; then
say "$LEGACY_UNIT migrated to $UNIT (config: /etc/threshold.d)"
else
say "FAILED to start $UNIT; rolling back to $LEGACY_UNIT"
systemctl disable "$UNIT" >/dev/null 2>&1 || true
rm -f "$_alias"
systemctl daemon-reload || true
if [ "$_was_enabled" = 1 ]; then
systemctl enable "$LEGACY_UNIT" >/dev/null 2>&1 || true
fi
systemctl start "$LEGACY_UNIT" || say "could not restart $LEGACY_UNIT"
fi
elif [ "$_was_enabled" = 1 ]; then
say "$LEGACY_UNIT enablement carried over to $UNIT (not started: it was stopped)"
fi
fi
fi
# Pick up a new/changed user drop-in even when no migration was needed.
systemctl daemon-reload || true
fi
exit 0
Regular → Executable
+52 -5
View File
@@ -1,8 +1,55 @@
#!/bin/bash
#!/bin/sh
# Threshold package post-remove script (deb "postrm" / rpm "%postun").
#
# deb: $1 is remove|purge|upgrade|... rpm: $1 is 0 (erase) or 1+ (upgrade)
#
# On final removal this removes only what the Threshold package scripts
# themselves created: the managed systemd drop-in, the /usr/bin/boundary and
# /etc/systemd/system/boundary.service symlinks (only if they point at
# Threshold), and on purge the "threshold" user. User configuration, data and
# the legacy "boundary" user are never touched.
#
# THRESHOLD_PKG_ROOT exists only so the logic can be exercised by
# .release/linux/test/test-package-scripts.sh without root; it is empty in
# normal use.
if [ "$1" = "purge" ]
then
userdel boundary
set -eu
ROOT="${THRESHOLD_PKG_ROOT:-}"
SYSTEMD_ETC="$ROOT/etc/systemd/system"
DROPIN_DIR="$SYSTEMD_ETC/threshold.service.d"
DROPIN="$DROPIN_DIR/10-legacy-boundary-user.conf"
DROPIN_MARK="# Managed by the Threshold package (legacy boundary user reuse)"
# rm a symlink only if its target's basename matches $2.
rm_link_if() {
if [ -L "$1" ]; then
_t=$(readlink "$1" || true)
case "${_t##*/}" in
"$2") rm -f "$1" ;;
esac
fi
}
case "${1:-}" in
remove | purge | 0)
rm_link_if "$ROOT/usr/bin/boundary" threshold
rm_link_if "$SYSTEMD_ETC/boundary.service" threshold.service
rm_link_if "$SYSTEMD_ETC/multi-user.target.wants/threshold.service" threshold.service
if [ -f "$DROPIN" ] && grep -qF "$DROPIN_MARK" "$DROPIN"; then
rm -f "$DROPIN"
rmdir "$DROPIN_DIR" 2>/dev/null || true
fi
if command -v systemctl >/dev/null 2>&1 && [ -d "$ROOT/run/systemd/system" ]; then
systemctl daemon-reload >/dev/null 2>&1 || true
fi
;;
esac
if [ "${1:-}" = "purge" ]; then
if id -u threshold >/dev/null 2>&1; then
userdel threshold || true
fi
fi
exit 0
exit 0
Regular → Executable
+94 -9
View File
@@ -1,13 +1,98 @@
#!/bin/bash
#!/bin/sh
# Threshold package pre-install script (deb "preinst" / rpm "%pre").
#
# Runs before the package files are unpacked. It is safe to run repeatedly and
# never deletes or overwrites anything:
#
# * Service user: if a HashiCorp Boundary "boundary" user already exists and
# there is no "threshold" user yet, no new user is created. The postinst
# script makes the service run as the existing "boundary" user so that its
# data/log directory ownership keeps working.
# * Configuration: files from /etc/boundary.d are COPIED to /etc/threshold.d
# (boundary.hcl -> threshold.hcl, boundary.env -> threshold.env, everything
# else keeps its name). An existing file in /etc/threshold.d is never
# replaced, and the originals in /etc/boundary.d are left untouched.
#
# THRESHOLD_PKG_ROOT exists only so the logic can be exercised by
# .release/linux/test/test-package-scripts.sh without root; it is empty in
# normal use.
set -eu
USER="boundary"
ROOT="${THRESHOLD_PKG_ROOT:-}"
NEW_USER="threshold"
LEGACY_USER="boundary"
LEGACY_DIR="$ROOT/etc/boundary.d"
NEW_DIR="$ROOT/etc/threshold.d"
if ! id -u $USER > /dev/null 2>&1; then
useradd \
--system \
--user-group \
--shell /bin/false \
$USER
fi
say() {
echo "threshold preinst: $*" >&2
}
user_exists() {
id -u "$1" >/dev/null 2>&1
}
# Map a top-level legacy file name to its Threshold name.
map_name() {
case "$1" in
boundary.hcl) echo "threshold.hcl" ;;
boundary.env) echo "threshold.env" ;;
*) echo "$1" ;;
esac
}
# copy_tree SRC_DIR DST_DIR TOPLEVEL(0/1)
# Copies entries that do not exist yet in DST_DIR; never overwrites.
copy_tree() {
_src=$1
_dst=$2
_top=$3
for _f in "$_src"/* "$_src"/.[!.]*; do
if [ ! -e "$_f" ] && [ ! -L "$_f" ]; then
continue
fi
_name=${_f##*/}
if [ "$_top" = 1 ]; then
_name=$(map_name "$_name")
fi
_target="$_dst/$_name"
if [ -d "$_f" ] && [ ! -L "$_f" ]; then
if [ -d "$_target" ]; then
copy_tree "$_f" "$_target" 0
elif [ -e "$_target" ] || [ -L "$_target" ]; then
say "not replacing existing $_target"
else
cp -pR "$_f" "$_target"
say "copied $_f -> $_target"
fi
elif [ -e "$_target" ] || [ -L "$_target" ]; then
# Already present (user's own file, or a previous run): keep it.
:
else
cp -pP "$_f" "$_target"
say "copied $_f -> $_target"
fi
done
}
# --- service user -----------------------------------------------------------
if ! user_exists "$NEW_USER"; then
if user_exists "$LEGACY_USER"; then
say "existing '$LEGACY_USER' user found; reusing it instead of creating '$NEW_USER'"
else
useradd \
--system \
--user-group \
--shell /bin/false \
"$NEW_USER"
fi
fi
# --- configuration migration ------------------------------------------------
if [ -d "$LEGACY_DIR" ]; then
mkdir -p "$NEW_DIR"
copy_tree "$LEGACY_DIR" "$NEW_DIR" 1
fi
exit 0
+267
View File
@@ -0,0 +1,267 @@
#!/bin/sh
# Self-contained test for the Linux package scripts (preinst/postinst/postrm).
#
# Simulates an old HashiCorp Boundary layout in a temporary directory (fake
# /etc/boundary.d, a "boundary" user, a running boundary.service) using the
# THRESHOLD_PKG_ROOT prefix and fake id/useradd/userdel/systemctl commands.
# Needs neither root nor systemd.
#
# Usage: .release/linux/test/test-package-scripts.sh
set -eu
HERE=$(cd "$(dirname "$0")" && pwd)
PKG_DIR=$(cd "$HERE/.." && pwd)
PREINST="$PKG_DIR/preinst"
POSTINST="$PKG_DIR/postinst"
POSTRM="$PKG_DIR/postrm"
SH=${TEST_SH:-sh}
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT INT TERM
FAILS=0
PASSES=0
pass() { PASSES=$((PASSES + 1)); }
fail() {
FAILS=$((FAILS + 1))
echo "FAIL: $*" >&2
}
assert() { # assert DESC cmd...
_d=$1
shift
if "$@"; then pass; else fail "$_d"; fi
}
refute() { # refute DESC cmd...
_d=$1
shift
if "$@"; then fail "$_d"; else pass; fi
}
file_has() { grep -qF -- "$2" "$1"; }
file_eq() { [ "$(cat "$1")" = "$2" ]; }
# --- fake commands ------------------------------------------------------------
BIN="$WORK/bin"
mkdir -p "$BIN"
cat >"$BIN/id" <<'EOF'
#!/bin/sh
# fake id: id -u NAME | id -gn NAME ; users in $FAKE/users as name:group
mode=$1
name=$2
line=$(grep "^$name:" "$FAKE/users" 2>/dev/null) || exit 1
case "$mode" in
-u) echo 1000 ;;
-gn) echo "${line#*:}" ;;
esac
EOF
cat >"$BIN/useradd" <<'EOF'
#!/bin/sh
for a in "$@"; do name=$a; done
echo "$name:$name" >>"$FAKE/users"
echo "useradd $name" >>"$FAKE/calls"
EOF
cat >"$BIN/userdel" <<'EOF'
#!/bin/sh
grep -v "^$1:" "$FAKE/users" >"$FAKE/users.new" || true
mv "$FAKE/users.new" "$FAKE/users"
echo "userdel $1" >>"$FAKE/calls"
EOF
cat >"$BIN/systemctl" <<'EOF'
#!/bin/sh
# fake systemctl backed by files in $FAKE (state) and $THRESHOLD_PKG_ROOT
resolve() {
if [ -L "$THRESHOLD_PKG_ROOT/etc/systemd/system/$1" ]; then
_t=$(readlink "$THRESHOLD_PKG_ROOT/etc/systemd/system/$1")
echo "${_t##*/}"
else
echo "$1"
fi
}
echo "systemctl $*" >>"$FAKE/calls"
case "$1" in
show)
u=$(resolve "$4")
case "$3" in
Id) echo "Id=$u" ;;
LoadState)
if [ -f "$THRESHOLD_PKG_ROOT/usr/lib/systemd/system/$u" ]; then
echo "LoadState=loaded"
else
echo "LoadState=not-found"
fi
;;
esac
;;
is-enabled) u=$(resolve "$3"); [ -e "$FAKE/enabled/$u" ] ;;
is-active) u=$(resolve "$3"); [ -e "$FAKE/active/$u" ] ;;
enable) u=$(resolve "$2"); : >"$FAKE/enabled/$u" ;;
disable) u=$(resolve "$2"); rm -f "$FAKE/enabled/$u" ;;
start)
u=$(resolve "$2")
[ -e "$FAKE/fail_start/$u" ] && exit 1
: >"$FAKE/active/$u"
;;
stop) u=$(resolve "$2"); rm -f "$FAKE/active/$u" ;;
daemon-reload) : ;;
esac
exit $?
EOF
chmod 755 "$BIN"/*
# --- scenario helpers -----------------------------------------------------------
new_root() { # new_root NAME -> sets ROOT and FAKE, creates skeleton
ROOT="$WORK/$1/root"
FAKE="$WORK/$1/fake"
mkdir -p "$ROOT/etc" "$ROOT/usr/bin" "$ROOT/usr/lib/systemd/system" \
"$ROOT/etc/systemd/system" "$ROOT/run/systemd/system" \
"$FAKE/enabled" "$FAKE/active" "$FAKE/fail_start"
: >"$FAKE/users"
: >"$FAKE/calls"
# What the package itself would have unpacked.
: >"$ROOT/usr/bin/threshold"
echo "[Service]" >"$ROOT/usr/lib/systemd/system/threshold.service"
export THRESHOLD_PKG_ROOT="$ROOT" FAKE
}
run_script() { # run_script SCRIPT [ARGS...]
_s=$1
shift
PATH="$BIN:$PATH" "$SH" "$_s" "$@" >"$WORK/out.log" 2>&1
}
add_legacy_layout() {
mkdir -p "$ROOT/etc/boundary.d/tls"
echo 'controller { name = "mine" }' >"$ROOT/etc/boundary.d/boundary.hcl"
echo 'BOUNDARY_POSTGRES_URL=secret' >"$ROOT/etc/boundary.d/boundary.env"
echo 'worker { name = "w" }' >"$ROOT/etc/boundary.d/worker.hcl"
echo 'KEY' >"$ROOT/etc/boundary.d/tls/server.key"
chmod 600 "$ROOT/etc/boundary.d/tls/server.key"
echo "boundary:boundary" >>"$FAKE/users"
echo "[Service]" >"$ROOT/usr/lib/systemd/system/boundary.service"
}
# ==============================================================================
echo "== scenario 1: upgrade from Boundary (running + enabled), existing threshold.hcl"
new_root s1
add_legacy_layout
: >"$FAKE/enabled/boundary.service"
: >"$FAKE/active/boundary.service"
mkdir -p "$ROOT/etc/threshold.d"
echo 'USER-OWNED' >"$ROOT/etc/threshold.d/threshold.hcl"
assert "preinst succeeds" run_script "$PREINST" install
assert "threshold.hcl NOT clobbered" file_eq "$ROOT/etc/threshold.d/threshold.hcl" "USER-OWNED"
assert "boundary.env migrated to threshold.env" file_has "$ROOT/etc/threshold.d/threshold.env" "BOUNDARY_POSTGRES_URL=secret"
assert "worker.hcl copied under same name" file_has "$ROOT/etc/threshold.d/worker.hcl" 'name = "w"'
assert "subdirectory copied" file_has "$ROOT/etc/threshold.d/tls/server.key" "KEY"
assert "originals kept: boundary.hcl" test -f "$ROOT/etc/boundary.d/boundary.hcl"
assert "originals kept: boundary.env" test -f "$ROOT/etc/boundary.d/boundary.env"
refute "no duplicate threshold user created" grep -q '^useradd' "$FAKE/calls"
refute "no boundary.hcl name left in threshold.d" test -e "$ROOT/etc/threshold.d/boundary.hcl"
assert "postinst succeeds" run_script "$POSTINST" configure
assert "drop-in written" file_has "$ROOT/etc/systemd/system/threshold.service.d/10-legacy-boundary-user.conf" "User=boundary"
assert "drop-in group" file_has "$ROOT/etc/systemd/system/threshold.service.d/10-legacy-boundary-user.conf" "Group=boundary"
assert "boundary command symlink" test -L "$ROOT/usr/bin/boundary"
assert "boundary symlink target is threshold" test "$(readlink "$ROOT/usr/bin/boundary")" = "threshold"
assert "boundary.service alias symlink" test -L "$ROOT/etc/systemd/system/boundary.service"
assert "legacy service stopped" test ! -e "$FAKE/active/boundary.service"
assert "threshold enabled" test -e "$FAKE/enabled/threshold.service"
assert "threshold started" test -e "$FAKE/active/threshold.service"
refute "legacy unit not left enabled as itself" grep -q 'enable boundary.service' "$FAKE/calls"
: >"$FAKE/calls"
assert "postinst idempotent (2nd run)" run_script "$POSTINST" configure
refute "2nd run does not stop/start anything" grep -qE 'systemctl (stop|start|enable|disable)' "$FAKE/calls"
assert "preinst idempotent (2nd run)" run_script "$PREINST" upgrade
assert "threshold.hcl still not clobbered" file_eq "$ROOT/etc/threshold.d/threshold.hcl" "USER-OWNED"
echo "== scenario 1b: postrm remove/purge cleans only generated pieces"
assert "postrm remove" run_script "$POSTRM" remove
refute "boundary command symlink removed" test -L "$ROOT/usr/bin/boundary"
refute "alias symlink removed" test -L "$ROOT/etc/systemd/system/boundary.service"
refute "drop-in removed" test -e "$ROOT/etc/systemd/system/threshold.service.d/10-legacy-boundary-user.conf"
assert "user config untouched after remove" test -f "$ROOT/etc/boundary.d/boundary.hcl"
assert "migrated config untouched after remove" test -f "$ROOT/etc/threshold.d/threshold.env"
assert "postrm purge (no threshold user: no userdel)" run_script "$POSTRM" purge
refute "boundary user never deleted" grep -q 'userdel boundary' "$FAKE/calls"
# ==============================================================================
echo "== scenario 2: fresh install, no Boundary"
new_root s2
assert "preinst succeeds" run_script "$PREINST" install
assert "threshold user created" grep -q '^useradd threshold' "$FAKE/calls"
refute "no /etc/threshold.d created by migration" test -e "$ROOT/etc/threshold.d"
assert "postinst succeeds" run_script "$POSTINST" configure
refute "no drop-in" test -e "$ROOT/etc/systemd/system/threshold.service.d"
refute "no boundary.service alias on fresh install" test -L "$ROOT/etc/systemd/system/boundary.service"
assert "boundary command symlink still provided" test -L "$ROOT/usr/bin/boundary"
refute "threshold not auto-enabled on fresh install" test -e "$FAKE/enabled/threshold.service"
assert "postrm purge deletes threshold user" run_script "$POSTRM" purge
assert "userdel threshold called" grep -q '^userdel threshold' "$FAKE/calls"
# ==============================================================================
echo "== scenario 3: boundary service enabled but threshold start fails -> rollback"
new_root s3
add_legacy_layout
: >"$FAKE/enabled/boundary.service"
: >"$FAKE/active/boundary.service"
: >"$FAKE/fail_start/threshold.service"
assert "preinst succeeds" run_script "$PREINST" install
assert "postinst still exits 0" run_script "$POSTINST" configure
assert "legacy service running again" test -e "$FAKE/active/boundary.service"
assert "legacy service enabled again" test -e "$FAKE/enabled/boundary.service"
refute "threshold left disabled" test -e "$FAKE/enabled/threshold.service"
refute "alias removed on rollback" test -L "$ROOT/etc/systemd/system/boundary.service"
assert "rollback explained" file_has "$WORK/out.log" "rolling back"
# ==============================================================================
echo "== scenario 4: enabled but stopped boundary service is only carried over"
new_root s4
add_legacy_layout
: >"$FAKE/enabled/boundary.service"
assert "preinst" run_script "$PREINST" install
assert "postinst" run_script "$POSTINST" configure
assert "threshold enabled" test -e "$FAKE/enabled/threshold.service"
refute "threshold not started" test -e "$FAKE/active/threshold.service"
# ==============================================================================
echo "== scenario 5: custom regular-file /etc/systemd/system/boundary.service is left alone"
new_root s5
add_legacy_layout
: >"$FAKE/enabled/boundary.service"
: >"$FAKE/active/boundary.service"
echo "CUSTOM" >"$ROOT/etc/systemd/system/boundary.service"
assert "preinst" run_script "$PREINST" install
assert "postinst" run_script "$POSTINST" configure
assert "custom unit untouched" file_eq "$ROOT/etc/systemd/system/boundary.service" "CUSTOM"
assert "legacy service still running" test -e "$FAKE/active/boundary.service"
refute "threshold not started" test -e "$FAKE/active/threshold.service"
# ==============================================================================
echo "== scenario 6: old boundary package binary present is not replaced"
new_root s6
add_legacy_layout
echo "OLDBIN" >"$ROOT/usr/bin/boundary"
assert "preinst" run_script "$PREINST" install
assert "postinst" run_script "$POSTINST" configure
refute "boundary binary not turned into symlink" test -L "$ROOT/usr/bin/boundary"
assert "boundary binary content kept" file_eq "$ROOT/usr/bin/boundary" "OLDBIN"
assert "postrm remove does not delete the old binary" run_script "$POSTRM" remove
assert "old binary still there" test -f "$ROOT/usr/bin/boundary"
# ==============================================================================
echo "== scenario 7: threshold user already exists alongside boundary -> no drop-in"
new_root s7
add_legacy_layout
echo "threshold:threshold" >>"$FAKE/users"
assert "preinst" run_script "$PREINST" install
assert "postinst" run_script "$POSTINST" configure
refute "no drop-in when threshold user exists" test -e "$ROOT/etc/systemd/system/threshold.service.d"
# ==============================================================================
echo
echo "passed: $PASSES, failed: $FAILS"
[ "$FAILS" -eq 0 ]
+4 -6
View File
@@ -1,9 +1,7 @@
# Copyright IBM Corp. 2020, 2026
# SPDX-License-Identifier: BUSL-1.1
url_docker_registry_dockerhub = "https://hub.docker.com/r/hashicorp/boundary"
url_docker_registry_ecr = "https://gallery.ecr.aws/hashicorp/boundary"
url_license = "https://github.com/hashicorp/boundary/blob/main/LICENSE"
url_project_website = "https://www.boundaryproject.io"
url_release_notes = "https://www.boundaryproject.io/docs/releases/release-notes"
url_source_repository = "https://github.com/hashicorp/boundary"
url_license = "https://repo.anhonesthost.net/CyberCoveLLC/threshold/src/branch/main/LICENSE"
url_project_website = "https://repo.anhonesthost.net/CyberCoveLLC/threshold"
url_release_notes = "https://repo.anhonesthost.net/CyberCoveLLC/threshold/src/branch/main/CHANGELOG.md"
url_source_repository = "https://repo.anhonesthost.net/CyberCoveLLC/threshold"
+44
View File
@@ -0,0 +1,44 @@
# Copyright IBM Corp. 2020, 2026
# SPDX-License-Identifier: BUSL-1.1
schema = 1
artifacts {
zip = [
"threshold_${version}_darwin_amd64.zip",
"threshold_${version}_darwin_arm64.zip",
"threshold_${version}_freebsd_386.zip",
"threshold_${version}_freebsd_amd64.zip",
"threshold_${version}_freebsd_arm.zip",
"threshold_${version}_linux_386.zip",
"threshold_${version}_linux_amd64.zip",
"threshold_${version}_linux_arm.zip",
"threshold_${version}_linux_arm64.zip",
"threshold_${version}_netbsd_386.zip",
"threshold_${version}_netbsd_amd64.zip",
"threshold_${version}_netbsd_arm.zip",
"threshold_${version}_openbsd_386.zip",
"threshold_${version}_openbsd_amd64.zip",
"threshold_${version}_openbsd_arm.zip",
"threshold_${version}_solaris_amd64.zip",
"threshold_${version}_windows_386.zip",
"threshold_${version}_windows_amd64.zip",
]
rpm = [
"threshold-${version_linux}-1.aarch64.rpm",
"threshold-${version_linux}-1.armv7hl.rpm",
"threshold-${version_linux}-1.i386.rpm",
"threshold-${version_linux}-1.x86_64.rpm",
]
deb = [
"threshold_${version_linux}-1_amd64.deb",
"threshold_${version_linux}-1_arm64.deb",
"threshold_${version_linux}-1_armhf.deb",
"threshold_${version_linux}-1_i386.deb",
]
container = [
"threshold_default_linux_386_${version}_${commit_sha}.docker.tar",
"threshold_default_linux_amd64_${version}_${commit_sha}.docker.tar",
"threshold_default_linux_arm64_${version}_${commit_sha}.docker.tar",
"threshold_default_linux_arm_${version}_${commit_sha}.docker.tar",
]
}
+14
View File
@@ -1,3 +1,17 @@
# Threshold CHANGELOG
> **Note:** Threshold is a community fork of HashiCorp Boundary Community Edition (CE), which was archived upstream on
> 2026-10-09. Entries below this note are the upstream Boundary changelog and are kept unchanged for history.
> Threshold-specific changes are listed under the "Threshold" heading, newest first.
## Threshold
### Unreleased
* Renamed the CLI binary to `threshold` and rebranded user-visible text. `THRESHOLD_*` environment variables are now
preferred, with `BOUNDARY_*` honored as a fallback. The client cache directory is `~/.threshold` (falling back to an
existing `~/.boundary`), and stored tokens are written under new keyring names while old entries are still read.
# Boundary CHANGELOG
Canonical reference for changes, improvements, and bugfixes for Boundary.
+20 -27
View File
@@ -1,53 +1,46 @@
# Contributing to Boundary
# Contributing to Threshold
Thank you for contributing to Boundary! Here you can find common questions around reporting issues and opening
pull requests to our project.
Thank you for contributing to Threshold! Threshold is a community fork of HashiCorp Boundary Community Edition (CE).
It is not affiliated with or endorsed by HashiCorp or IBM. Here you can find common questions around reporting issues
and opening pull requests to the project. The repository lives at
<https://repo.anhonesthost.net/CyberCoveLLC/threshold>.
When contributing in any way to the Boundary project (new issue, PR, etc), please be aware that our team identifies with many gender pronouns. Please remember to use nonbinary pronouns (they/them) and gender neutral language ("Hello folks") when addressing our team. For more reading on our code of conduct, please see the [HashiCorp community guidelines](https://www.hashicorp.com/community-guidelines).
Please be respectful and inclusive when contributing in any way (new issue, PR, etc).
## Issue Reporting
### Reporting Security Related Vulnerabilities
We take Boundary's security and our users' trust very seriously. If you believe you have found a security issue
in Boundary, please responsibly disclose by contacting us at security@hashicorp.com. Do not open an issue on
our GitHub issue tracker if you believe you've found a security related issue, thank you!
If you believe you have found a security issue in Threshold, please disclose it responsibly by contacting the
maintainers privately rather than opening a public issue. Issues that exist in upstream HashiCorp Boundary CE should
also be treated as security-sensitive.
### Bug Fixes
If you believe you found a bug with Boundary, please:
If you believe you found a bug with Threshold, please:
1. Build from the latest `main` HEAD commit to attempt to reproduce the issue. It's possible we've already fixed
the bug, and this is a first good step to ensuring that's not the case.
1. Take a look at the [Boundary Discuss](https://discuss.hashicorp.com/c/boundary/50) to see if other folks have had
similar issues.
1. Ensure a similar ticket is not already opened by searching our opened issues on GitHub.
1. Build from the latest `main` HEAD commit to attempt to reproduce the issue. It's possible it has already been fixed.
1. Ensure a similar issue is not already opened by searching the open issues in the repository.
Once you've verified the above, feel free to open a bug fix issue template type from our [issue selector](https://github.com/hashicorp/boundary/issues/new/choose)
and we'll do our best to triage it as quickly as possible.
Once you've verified the above, open an issue in the repository describing how to reproduce the problem.
## Pull Requests
### New Features & Improvements
Before writing a line of code, please ask us about a potential improvement or feature that you want to write into Boundary. We may already be working on it; even if we aren't, we need to ensure that both the feature and its proposed implementation is aligned with our road map, vision, and standards for the project. We're happy to help walk through that via a [feature request issue](https://github.com/hashicorp/boundary/issues/new/choose).
You can see a public [road map for Boundary](https://github.com/hashicorp/boundary/issues/new/choose) on our docs site and we encourage
everyone to look this over to understand at a high level what we're working on with Boundary.
Before writing a line of code, please open an issue to discuss a potential improvement or feature. Threshold is
focused on maintaining the Community Edition code base, so changes that stay close to upstream behavior and
compatibility are the easiest to accept.
### Submitting a New Pull Request
When submitting a pull request, please ensure:
1. You've added a changelog line clearly describing the new addition under the correct changelog sub-section.
1. You've followed the above guidelines for contributing to Boundary.
Once you open your PR, our auto-labeling will add labels to help us triage and prioritize your contribution. Please
allow us a couple of days to comment, request changes, or approve your PR. Thank you for your contribution!
1. You've followed the above guidelines for contributing to Threshold.
## Changelog
The changelog is updated by PR contributors. Each contribution to Boundary should include a changelog update at the contributor or reviewer discretion.
The changelog is updated by PR contributors. Each contribution to Threshold should include a changelog update at the contributor or reviewer discretion.
The changelog should be updated when the contribution is large enough to warrant it being called out in the larger release cycle. Enhancements, bug fixes,
and other contributions that practitioners might want to be aware of should exist in the changelog.
@@ -72,7 +65,7 @@ Any bug fixes fall into this section.
Most tests require a postgres database instance to successfully run.
This is provided via docker
by running a customized postgres image that is optimized for boundary tests.
by running a customized postgres image that is optimized for Threshold tests.
Before running the test suite, this docker container must be started:
@@ -109,7 +102,7 @@ once the test database is ready:
$ make test
```
Before running any test please ensure that Docker is started. Boundary uses a Docker container to initiate a database for testing.
Before running any test please ensure that Docker is started. Threshold uses a Docker container to initiate a database for testing.
If a test is interrupted check to make certain that all Docker containers have been properly destroyed.
### Running individual tests
+42 -83
View File
@@ -13,108 +13,60 @@
# For local dev and testing purposes, please build and use the `dev` docker image.
# Development docker image
FROM docker.mirror.hashicorp.services/alpine:3.21 as dev
# Development docker image (built from the locally built ./bin/threshold)
FROM alpine:3.21 as dev
RUN set -eux && \
addgroup boundary && \
adduser -s /bin/sh -S -G boundary boundary && \
addgroup threshold && \
adduser -s /bin/sh -S -G threshold threshold && \
apk add --no-cache wget ca-certificates dumb-init gnupg libcap openssl su-exec iputils libc6-compat iptables
ADD bin/boundary /bin/boundary
RUN setcap cap_ipc_lock=+ep /bin/boundary
ADD bin/threshold /bin/threshold
RUN setcap cap_ipc_lock=+ep /bin/threshold
RUN mkdir /boundary/
ADD .release/docker/config.hcl /boundary/config.hcl
RUN chown -R boundary:boundary /boundary/
RUN chmod -R 640 /boundary/*
RUN mkdir /threshold/
ADD .release/docker/config.hcl /threshold/config.hcl
RUN chown -R threshold:threshold /threshold/
RUN chmod -R 640 /threshold/*
# Legacy HashiCorp Boundary compatibility: /boundary -> /threshold and a
# "boundary" command alias (prints a deprecation notice on stderr).
RUN mkdir -p /usr/share/threshold && \
cp /threshold/config.hcl /usr/share/threshold/config.hcl.default && \
ln -s /threshold /boundary && \
ln -s threshold /bin/boundary
EXPOSE 9200 9201 9202
VOLUME /boundary/
VOLUME /threshold/
LABEL org.opencontainers.image.licenses="BUSL-1.1"
COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
COPY bin/LICENSE.txt /usr/share/doc/boundary/LICENSE.txt
COPY bin/LICENSE.txt /usr/share/doc/threshold/LICENSE.txt
USER boundary
USER threshold
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["server", "-config", "/boundary/config.hcl"]
# Official docker image that uses binaries from releases.hashicorp.com
FROM docker.mirror.hashicorp.services/alpine:3.21 as official
ARG PRODUCT_VERSION
LABEL name="Boundary" \
maintainer="HashiCorp Boundary Team <boundary@hashicorp.com>" \
vendor="HashiCorp" \
version=$PRODUCT_VERSION \
release=$PRODUCT_VERSION \
summary="Boundary provides simple and secure access to hosts and services" \
description="The Boundary Docker image is designed to enable practitioners to run Boundary in server mode on a container scheduler" \
org.opencontainers.image.licenses="BUSL-1.1"
RUN set -eux && \
addgroup boundary && \
adduser -s /bin/sh -S -G boundary boundary && \
apk add --no-cache wget ca-certificates dumb-init gnupg libcap openssl su-exec iputils libc6-compat iptables && \
gpg --keyserver keyserver.ubuntu.com --recv-keys C874011F0AB405110D02105534365D9472D7468F && \
cd /tmp && \
apkArch="$(apk --print-arch)" && \
case "${apkArch}" in \
aarch64) boundaryArch='arm64' ;; \
armhf) boundaryArch='armhfv6' ;; \
x86) boundaryArch='386' ;; \
x86_64) boundaryArch='amd64' ;; \
*) echo >&2 "error: unsupported architecture: ${apkArch} (see https://releases.hashicorp.com/boundary/${PRODUCT_VERSION}/ )" && exit 1 ;; \
esac && \
wget https://releases.hashicorp.com/boundary/${PRODUCT_VERSION}/boundary_${PRODUCT_VERSION}_linux_${boundaryArch}.zip && \
wget https://releases.hashicorp.com/boundary/${PRODUCT_VERSION}/boundary_${PRODUCT_VERSION}_SHA256SUMS && \
wget https://releases.hashicorp.com/boundary/${PRODUCT_VERSION}/boundary_${PRODUCT_VERSION}_SHA256SUMS.sig && \
gpg --batch --verify boundary_${PRODUCT_VERSION}_SHA256SUMS.sig boundary_${PRODUCT_VERSION}_SHA256SUMS && \
grep boundary_${PRODUCT_VERSION}_linux_${boundaryArch}.zip boundary_${PRODUCT_VERSION}_SHA256SUMS | sha256sum -c && \
unzip -d /bin boundary_${PRODUCT_VERSION}_linux_${boundaryArch}.zip && \
rm boundary_${PRODUCT_VERSION}_linux_${boundaryArch}.zip boundary_${PRODUCT_VERSION}_SHA256SUMS boundary_${PRODUCT_VERSION}_SHA256SUMS.sig && \
setcap cap_ipc_lock=+ep /bin/boundary && \
cp /bin/LICENSE.txt /usr/share/doc/boundary/LICENSE.txt && \
mkdir /boundary
COPY .release/docker/config.hcl /boundary/config.hcl
RUN chown -R boundary:boundary /boundary/
RUN chmod -R 640 /boundary/*
EXPOSE 9200 9201 9202
VOLUME /boundary/
COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
USER boundary
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["server", "-config", "/boundary/config.hcl"]
CMD ["server", "-config", "/threshold/config.hcl"]
# Production docker image
# Remember, this cannot be built locally
FROM docker.mirror.hashicorp.services/alpine:3.21 as default
FROM alpine:3.21 as default
ARG BIN_NAME
# NAME and PRODUCT_VERSION are the name of the software in releases.hashicorp.com
# and the version to download. Example: NAME=boundary PRODUCT_VERSION=1.2.3.
ARG NAME=boundary
# NAME is the name of the software (and of the user/group created in the image);
# PRODUCT_VERSION is the version. Example: NAME=threshold PRODUCT_VERSION=1.2.3.
ARG NAME=threshold
ARG PRODUCT_VERSION
# TARGETARCH and TARGETOS are set automatically when --platform is provided.
ARG TARGETOS TARGETARCH
LABEL name="Boundary" \
maintainer="HashiCorp Boundary Team <boundary@hashicorp.com>" \
vendor="HashiCorp" \
LABEL name="Threshold" \
vendor="Threshold (fork of HashiCorp Boundary CE)" \
version=$PRODUCT_VERSION \
release=$PRODUCT_VERSION \
summary="Boundary provides simple and secure access to hosts and services" \
description="The Boundary Docker image is designed to enable practitioners to run Boundary in server mode on a container scheduler" \
summary="Threshold provides simple and secure access to hosts and services" \
description="The Threshold Docker image is designed to enable practitioners to run Threshold, a community fork of HashiCorp Boundary Community Edition, in server mode on a container scheduler. Not affiliated with or endorsed by HashiCorp or IBM." \
org.opencontainers.image.licenses="BUSL-1.1"
# Set ARGs as ENV so that they can be used in ENTRYPOINT/CMD
@@ -126,20 +78,27 @@ RUN addgroup ${NAME} && adduser -s /bin/sh -S -G ${NAME} ${NAME}
RUN apk add --no-cache wget ca-certificates dumb-init gnupg libcap openssl su-exec iputils libc6-compat iptables
COPY .release/docker/config.hcl /boundary/config.hcl
COPY .release/docker/config.hcl /threshold/config.hcl
COPY dist/$TARGETOS/$TARGETARCH/$BIN_NAME /bin/
COPY dist/$TARGETOS/$TARGETARCH/LICENSE.txt /usr/share/doc/boundary/LICENSE.txt
COPY dist/$TARGETOS/$TARGETARCH/LICENSE.txt /usr/share/doc/threshold/LICENSE.txt
RUN setcap cap_ipc_lock=+ep /bin/$BIN_NAME
RUN chown -R ${NAME}:${NAME} /boundary
RUN chmod -R 640 /boundary/*
RUN chown -R ${NAME}:${NAME} /threshold
RUN chmod -R 640 /threshold/*
# Legacy HashiCorp Boundary compatibility: /boundary -> /threshold and a
# "boundary" command alias (prints a deprecation notice on stderr).
RUN mkdir -p /usr/share/threshold && \
cp /threshold/config.hcl /usr/share/threshold/config.hcl.default && \
ln -s /threshold /boundary && \
ln -s ${BIN_NAME} /bin/boundary
EXPOSE 9200 9201 9202
VOLUME /boundary/
VOLUME /threshold/
COPY .release/docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
USER ${NAME}
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["server", "-config", "/boundary/config.hcl"]
CMD ["server", "-config", "/threshold/config.hcl"]
+12 -33
View File
@@ -4,7 +4,7 @@ THIS_FILE := $(lastword $(MAKEFILE_LIST))
THIS_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
TMP_DIR := $(shell mktemp -d)
REPO_PATH := github.com/hashicorp/boundary
REPO_PATH := repo.anhonesthost.net/CyberCoveLLC/threshold
TEST_PACKAGE ?= $(shell go list ./... | grep -v '/e2e')
TEST_TIMEOUT ?= 30m
@@ -55,16 +55,16 @@ dev:
.PHONY: build
build: BUILD_TAGS+=ui
build: build-ui-ifne
@echo "==> Building Boundary with UI features enabled"
@echo "==> Building Threshold with UI features enabled"
@CGO_ENABLED=$(CGO_ENABLED) BUILD_TAGS='$(BUILD_TAGS)' sh -c "'$(CURDIR)/scripts/build.sh'"
.PHONY: build-no-ui
build-no-ui:
@echo "==> Building Boundary without UI features"
@echo "==> Building Threshold without UI features"
@CGO_ENABLED=$(CGO_ENABLED) BUILD_TAGS='$(BUILD_TAGS)' sh -c "'$(CURDIR)/scripts/build.sh'"
.PHONY: install
install: export BOUNDARY_INSTALL_BINARY=1
install: export THRESHOLD_INSTALL_BINARY=1
install: build
.PHONY: install-no-plugins
@@ -74,7 +74,7 @@ install-no-plugins: install
.PHONY: build-memprof
build-memprof: BUILD_TAGS+=memprofiler
build-memprof:
@echo "==> Building Boundary with memory profiling enabled"
@echo "==> Building Threshold with memory profiling enabled"
@CGO_ENABLED=$(CGO_ENABLED) BUILD_TAGS='$(BUILD_TAGS)' sh -c "'$(CURDIR)/scripts/build.sh'"
# Format Go files, ignoring files marked as generated through the header defined at
@@ -363,35 +363,14 @@ install-go:
./ci/goinstall.sh
# Docker build and publish variables and targets
REGISTRY_NAME?=docker.io/hashicorp
IMAGE_NAME=boundary
REGISTRY_NAME?=repo.anhonesthost.net/cybercovellc
IMAGE_NAME=threshold
VERSION?=0.7.4
IMAGE_TAG=$(REGISTRY_NAME)/$(IMAGE_NAME):$(VERSION)
IMAGE_TAG_DEV?=$(REGISTRY_NAME)/$(IMAGE_NAME):latest-$(shell git rev-parse --short HEAD)
.PHONY: docker
docker: docker-build
.PHONY: docker-build
# Builds from the releases.hashicorp.com official binary
docker-build:
docker build \
--tag $(IMAGE_TAG) \
--tag hashicorp/boundary:latest \
--target=official \
--build-arg VERSION=$(VERSION) \
.
.PHONY: docker-multiarch-build
# Builds multiarch from the releases.hashicorp.com official binary
docker-multiarch-build:
docker buildx build \
--tag $(IMAGE_TAG) \
--tag hashicorp/boundary:latest \
--target=official \
--build-arg VERSION=$(VERSION) \
--platform linux/amd64,linux/arm64 \
.
docker: docker-build-dev
DEV_DOCKER_GOOS ?= linux
DEV_DOCKER_GOARCH ?= amd64
@@ -406,7 +385,7 @@ docker-build-dev: build
--platform $(DEV_DOCKER_GOOS)/$(DEV_DOCKER_GOARCH) \
--tag $(IMAGE_TAG_DEV) \
--target=dev \
--build-arg=boundary \
--build-arg=threshold \
.
@echo "Successfully built $(IMAGE_TAG_DEV)"
@@ -416,8 +395,8 @@ docker-build-dev: build
# This is used for release builds by .github/workflows/build.yml
version:
@go run \
-ldflags "-X 'github.com/hashicorp/boundary/version.Version=$(shell cat version/VERSION)'" \
./cmd/boundary version \
-ldflags "-X 'repo.anhonesthost.net/CyberCoveLLC/threshold/version.Version=$(shell cat version/VERSION)'" \
./cmd/threshold version \
| awk '/Version Number:/ { print $$3 }'
EDITION?=
@@ -425,7 +404,7 @@ EDITION?=
# This is used for release builds by .github/workflows/build.yml
edition:
@if [ -z "$(EDITION)" ]; then \
go run ./cmd/boundary version -format=json | jq -r '.version_metadata // "oss"'; \
go run ./cmd/threshold version -format=json | jq -r '.version_metadata // "oss"'; \
else \
echo $(EDITION); \
fi; \
+26
View File
@@ -0,0 +1,26 @@
Threshold
=========
Threshold is a community fork of HashiCorp Boundary Community Edition (CE),
originally developed by HashiCorp, Inc. (an IBM company):
https://github.com/hashicorp/boundary
The upstream repository was archived on 2026-10-09. Threshold continues
maintenance of that code base.
Original work:
Copyright (c) HashiCorp, Inc.
Copyright IBM Corp. 2020, 2026
Licensed under the Business Source License 1.1 (see LICENSE).
All existing copyright headers and the LICENSE file are preserved unchanged.
Threshold is distributed under the same license terms as the upstream project.
Threshold is not affiliated with, endorsed by, or sponsored by HashiCorp,
Inc. or IBM. "Boundary", "HashiCorp", "HCP Boundary" and related marks are
the property of their respective owners and are referenced here solely to
identify the origin of this software.
Portions of this repository (for example the api and sdk modules) carry their
own license files, which apply to those portions.
+190 -6
View File
@@ -1,10 +1,194 @@
<img alt="Boundary" src="boundary.png" alt="Image" width="500px"/>
# Threshold
Boundary Community Edition (CE) is no longer under active development, and this repository has been archived as of October 8, 2026. Future Boundary development will focus on HCP Boundary and Boundary Enterprise, where we can provide enterprise grade human and agentic access capabilities.
Threshold provides simple and secure access to hosts and services. It is a
community-maintained fork of HashiCorp Boundary Community Edition (CE).
This repository is now read-only and no longer accepts new issues, pull requests, or community contributions. Existing source code and previously released binaries remain available for reference and existing self-managed use.
## About this fork
No new Boundary CE releases, maintenance updates, bug fixes, or security patches are currently planned.
Threshold is a community fork of [HashiCorp Boundary Community Edition](https://github.com/hashicorp/boundary).
HashiCorp (an IBM company) archived the upstream Boundary CE repository on
2026-10-09 and announced that no further CE releases, maintenance updates, bug
fixes or security patches are planned. Threshold continues maintenance of the
Community Edition code base so that existing self-managed deployments can keep
receiving fixes.
Teams continuing to use Boundary CE should evaluate whether it meets their operational, security, and compliance requirements.
For supported Boundary capabilities, including production-scale governance, compliance, session recording, enterprise support, and future Boundary development, please evaluate HCP Boundary or Boundary Enterprise.
- Threshold is licensed under the [Business Source License 1.1](LICENSE), the
same license as the upstream code. The original license text and all
copyright headers are preserved. See [NOTICE](NOTICE) for attribution.
- **Threshold is not affiliated with, endorsed by, or sponsored by HashiCorp or
IBM.** "Boundary", "HashiCorp" and "HCP Boundary" are trademarks of their
respective owners and are used here only to describe the origin of this
project.
- Upstream project: <https://github.com/hashicorp/boundary>
- This repository: <https://repo.anhonesthost.net/CyberCoveLLC/threshold>
### Compatibility with Boundary CE
This is the first phase of the rebrand and is designed to keep existing
Boundary CE deployments working:
- The command-line binary is now `threshold` (built from `cmd/threshold`).
- The wire protocol, HTTP API paths (`/v1`), database schema, plugin protocol
and configuration file format are unchanged.
- The Go module path is `repo.anhonesthost.net/CyberCoveLLC/threshold` (with `/api` and `/sdk`
submodules); protobuf code has been regenerated for it.
- Release versions are still reported on the wire with the upstream
`Boundary v` prefix so mixed clusters keep working. `Threshold v` is also
accepted when parsing.
### Environment variable and path fallbacks
Threshold prefers `THRESHOLD_*` environment variables, and transparently falls
back to the legacy `BOUNDARY_*` name when the `THRESHOLD_*` variable is not set.
For example `THRESHOLD_ADDR`, `THRESHOLD_TOKEN`, `THRESHOLD_SCOPE_ID`,
`THRESHOLD_KEYRING_TYPE`, `THRESHOLD_TOKEN_NAME`, `THRESHOLD_CONNECT_*`,
`THRESHOLD_SKIP_CACHE_DAEMON` and the other CLI and server variables are read
first, then `BOUNDARY_ADDR`, `BOUNDARY_TOKEN`, and so on. A `THRESHOLD_*` variable that is
set to a non-empty value always wins. Existing scripts and deployments that
only set `BOUNDARY_*` variables do not need to change.
Notes:
- `env://VAR` references inside configuration files and flags (for example
`url = "env://BOUNDARY_POSTGRES_URL"` or `url = "env://THRESHOLD_POSTGRES_URL"`
as used by the bundled container config) name an environment variable
literally and are not rewritten; keep using whichever variable name you export.
- `threshold connect -exec` exports both `THRESHOLD_PROXIED_{PORT,IP,ADDR}` and
the legacy `BOUNDARY_PROXIED_{PORT,IP,ADDR}` variables to the child process.
- The container image entrypoint mirrors any `BOUNDARY_*` variables to the
matching `THRESHOLD_*` variable when it is unset.
Other fallbacks:
| Item | New | Legacy fallback |
|------|-----|-----------------|
| Client cache directory | `~/.threshold` | `~/.boundary` is used if it exists and `~/.threshold` does not |
| Keyring entry (macOS Keychain / Windows Credential Manager) | `Threshold Auth Token` | `HashiCorp Boundary Auth Token` is read if the new entry is not found, and removed on `threshold logout` |
| Keyring prefix (`pass`, libsecret) | `Threshold` | `HashiCorp_Boundary` is read if the new entry is not found, and removed on `threshold logout` |
Tokens are always written using the new names.
## Upgrading from Boundary
Threshold is designed as an in-place replacement for HashiCorp Boundary CE:
the same database, the same configuration files, and a binary that can still be
invoked as `boundary`.
### Compatibility guarantees
These are unchanged from upstream Boundary CE, so a mixed fleet of Boundary and
Threshold controllers and workers interoperates, and you can upgrade (and roll
back) one node at a time:
- **Database schema**: the schema migrations are untouched and the
`boundary_schema_version` table keeps its name. Threshold runs against an
existing Boundary database as-is (`threshold database migrate` applies the
same migrations Boundary would).
- **Wire protocol**: protobuf packages, gRPC service names and the `/v1` HTTP
API paths are unchanged (only Go import paths were renamed). Versions are
still reported to peers with the `Boundary v` prefix.
- **Plugin protocol**: the plugin magic cookie
(`HASHICORP_BOUNDARY_PLUGIN` / `boundary-plugin`) is unchanged, so existing
`boundary-plugin-*` binaries keep working.
- **Configuration file format** (HCL) is unchanged.
Do not run `database migrate` from a newer Threshold than your other nodes
understand; as with Boundary, upgrade controllers before workers and follow the
usual rolling-upgrade guidance for schema migrations.
### Linux packages (deb/rpm)
1. Back up `/etc/boundary.d` and take a database backup.
2. Install the Threshold package. Do not `purge` the old `boundary` package
(removal is fine); purging runs its scripts, which may delete the `boundary`
user that Threshold will reuse. Installing Threshold while the old package is
still installed is supported.
3. The package scripts then, automatically:
- **copy** `/etc/boundary.d` to `/etc/threshold.d` (`boundary.hcl` becomes
`threshold.hcl`, `boundary.env` becomes `threshold.env`; subdirectories such
as TLS material are copied as-is). Existing files in `/etc/threshold.d` are
never overwritten and the originals are never modified or deleted;
- keep reading `/etc/boundary.d/boundary.env` as a fallback environment file
(`threshold.env` takes precedence), so `BOUNDARY_*` variables keep working;
- reuse the existing `boundary` service user and group instead of creating a
`threshold` user (through a managed systemd drop-in,
`/etc/systemd/system/threshold.service.d/10-legacy-boundary-user.conf`), so
ownership of your data, log and key directories keeps working;
- if `boundary.service` was enabled and/or running, stop and disable it,
enable `threshold.service`, and start it if the old service was running.
If `threshold.service` fails to start, the old service is restored;
- make `systemctl restart boundary` (and `status`, `stop`, ...) address
`threshold.service` via a `boundary.service` alias symlink in
`/etc/systemd/system`, and provide `/usr/bin/boundary` as a symlink to
`threshold` if no such file exists. The `boundary` command prints a
one-line deprecation notice to **stderr** only (silence it with
`THRESHOLD_NO_DEPRECATION_NOTICE=1`); stdout, flags and exit codes are
identical to `threshold`.
4. Verify: `systemctl status threshold`, `threshold version`.
What is **not** migrated automatically:
- Paths *inside* your configuration files are not rewritten. A config that
refers to `/etc/boundary.d/...` or `/var/lib/boundary` keeps working because
those locations are left in place; update them at your own pace.
- A custom `/etc/systemd/system/boundary.service` unit (a regular file) is left
alone and the legacy service is not touched; migrate it by hand.
- If `/usr/bin/boundary` is still the old binary from the Boundary package, it is
left alone. After removing the old package: `ln -s threshold /usr/bin/boundary`.
- Distribution-specific package-manager behavior such as `--force-confnew` (dpkg)
can replace `/etc/threshold.d` defaults; your originals remain in
`/etc/boundary.d`.
- Data directories, the database, KMS keys and the client cache are not moved
(the client cache directory is covered by the table above).
Rollback: stop `threshold.service`, remove the `boundary.service` alias
symlink (`/etc/systemd/system/boundary.service`) and the drop-in, reinstall the
old Boundary package, and `systemctl enable --now boundary`. Because the
database schema is unchanged and `/etc/boundary.d` was never modified, nothing
else needs to be restored. If you ran a Threshold release that applied schema
migrations newer than your Boundary version, restore the database backup
instead.
### Container image
The image's configuration directory moved from `/boundary` to `/threshold`
(default command: `threshold server -config /threshold/config.hcl`). For
compatibility the image:
- contains `/boundary` as a symlink to `/threshold`, so existing
`-v "$(pwd)":/boundary/` mounts land in the right place;
- falls back to `/boundary/config.hcl` (printing a deprecation warning) when
`-config /boundary/config.hcl` is requested, or when the stock demo config is
still in place and a config exists at `/boundary/config.hcl`;
- accepts `boundary ...` as the command and `BOUNDARY_*` environment variables
(mirrored to `THRESHOLD_*`).
Plan to switch your mounts, `-config` arguments and environment variables to
the `/threshold` and `THRESHOLD_*` names; the compatibility paths print
warnings and may be removed in a future major release.
### Other installs (binary / zip)
Replace the `boundary` binary with `threshold` (or keep the file name
`boundary`, which behaves identically). Existing `BOUNDARY_*` variables,
`~/.boundary` and stored credentials are picked up as described above.
### Development mode
`threshold dev` creates the `ssh.threshold.dev` and `postgres.threshold.dev`
aliases and, for compatibility, the legacy `ssh.boundary.dev` and
`postgres.boundary.dev` aliases pointing at the same targets.
## Building
```
make build # builds bin/threshold (requires the embedded UI, see Makefile)
make build-no-ui # builds bin/threshold without the embedded admin UI
```
The embedded admin UI is built from the upstream `boundary-ui` project and is
not part of this repository.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Account struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"errors"
"fmt"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
func (c *Client) ChangePassword(ctx context.Context, accountId, currentPassword, newPassword string, version uint32, opt ...Option) (*AccountUpdateResult, error) {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"errors"
"fmt"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
func (c *Client) SetPassword(ctx context.Context, accountId, password string, version uint32, opt ...Option) (*AccountUpdateResult, error) {
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Alias struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"errors"
"fmt"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authtokens"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/authtokens"
)
type AuthenticateResult struct {
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type AuthMethod struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"errors"
"fmt"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
const (
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -13,8 +13,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type AuthToken struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+1 -1
View File
@@ -7,7 +7,7 @@ package billing
import (
"time"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type ActiveUsers struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"fmt"
"net/url"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type MonthlyActiveUsersResult struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+36 -37
View File
@@ -15,7 +15,6 @@ import (
"net"
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
@@ -23,7 +22,7 @@ import (
"time"
"unicode"
"github.com/hashicorp/boundary/api/recovery"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/recovery"
cleanhttp "github.com/hashicorp/go-cleanhttp"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
retryablehttp "github.com/hashicorp/go-retryablehttp"
@@ -53,14 +52,14 @@ const (
// Config is used to configure the creation of the client
type Config struct {
// Addr is the address of the Boundary controller. This should be a
// complete URL such as "http://boundary.example.com". If you need a custom
// Addr is the address of the Threshold controller. This should be a
// complete URL such as "http://threshold.example.com". If you need a custom
// SSL cert or want to enable insecure mode, you need to specify a custom
// HttpClient.
Addr string
// Token is the client token that reuslts from authentication and can be
// used to make calls into Boundary
// used to make calls into Threshold
Token string
// RecoveryKmsWrapper is a wrapper used in the recovery KMS authentication
@@ -68,9 +67,9 @@ type Config struct {
// per-call, regardless of any value set in Token.
RecoveryKmsWrapper wrapping.Wrapper
// HttpClient is the HTTP client to use. Boundary sets sane defaults for the
// HttpClient is the HTTP client to use. Threshold sets sane defaults for the
// http.Client and its associated http.Transport created in DefaultConfig.
// If you must modify Boundary's defaults, it is suggested that you start
// If you must modify Threshold's defaults, it is suggested that you start
// with that client and modify as needed rather than start with an empty
// client (or http.DefaultClient). Currently if the client is cloned the
// same HttpClient is used.
@@ -114,20 +113,20 @@ type Config struct {
}
// TLSConfig contains the parameters needed to configure TLS on the HTTP client
// used to communicate with Boundary.
// used to communicate with Threshold.
type TLSConfig struct {
// CACert is the path to a PEM-encoded CA cert file to use to verify the
// Boundary server SSL certificate.
// Threshold server SSL certificate.
CACert string
// CAPath is the path to a directory of PEM-encoded CA cert files to verify
// the Boundary server SSL certificate.
// the Threshold server SSL certificate.
CAPath string
// ClientCert is the path to the certificate for Boundary communication
// ClientCert is the path to the certificate for Threshold communication
ClientCert string
// ClientKey is the path to the private key for Boundary communication
// ClientKey is the path to the private key for Threshold communication
ClientKey string
// ServerName, if set, is used to set the SNI host when connecting via
@@ -162,7 +161,7 @@ func RateLimitLinearJitterBackoff(min, max time.Duration, attemptNum int, resp *
// safe to modify the return value of this function.
//
// The default Addr is http://127.0.0.1:9200, but this can be overridden by
// setting the `BOUNDARY_ADDR` environment variable.
// setting the `THRESHOLD_ADDR` environment variable.
//
// If an error is encountered, this will return nil.
func DefaultConfig() (*Config, error) {
@@ -270,7 +269,7 @@ func (c *Config) setAddr(addr string) error {
// Remove trailing or leading slashes
path := strings.Trim(u.Path, "/")
// Remove v1 in front or back (e.g. they could have
// https://boundary.example.com/myinstall/v1 which would put it at the
// https://threshold.example.com/myinstall/v1 which would put it at the
// back)
path = strings.TrimPrefix(path, "v1")
path = strings.TrimSuffix(path, "v1")
@@ -296,15 +295,15 @@ func (c *Config) ReadEnvironment() error {
var envServerName string
// Parse the environment variables
if v := os.Getenv(EnvBoundaryAddr); v != "" {
if v := Getenv(EnvBoundaryAddr); v != "" {
c.Addr = v
}
if v := os.Getenv(EnvBoundaryToken); v != "" {
if v := Getenv(EnvBoundaryToken); v != "" {
c.Token = v
}
if v := os.Getenv(EnvBoundaryMaxRetries); v != "" {
if v := Getenv(EnvBoundaryMaxRetries); v != "" {
maxRetries, err := strconv.ParseUint(v, 10, 32)
if err != nil {
return err
@@ -318,7 +317,7 @@ func (c *Config) ReadEnvironment() error {
c.MaxRetries = int(maxRetries)
}
if v := os.Getenv(EnvBoundarySRVLookup); v != "" {
if v := Getenv(EnvBoundarySRVLookup); v != "" {
var err error
lookup, err := strconv.ParseBool(v)
if err != nil {
@@ -327,7 +326,7 @@ func (c *Config) ReadEnvironment() error {
c.SRVLookup = lookup
}
if t := os.Getenv(EnvBoundaryClientTimeout); t != "" {
if t := Getenv(EnvBoundaryClientTimeout); t != "" {
clientTimeout, err := parseutil.ParseDurationSecond(t)
if err != nil {
return fmt.Errorf("could not parse %q", EnvBoundaryClientTimeout)
@@ -335,7 +334,7 @@ func (c *Config) ReadEnvironment() error {
c.Timeout = clientTimeout
}
if v := os.Getenv(EnvBoundaryRateLimit); v != "" {
if v := Getenv(EnvBoundaryRateLimit); v != "" {
rateLimit, burstLimit, err := parseRateLimit(v)
if err != nil {
return err
@@ -346,31 +345,31 @@ func (c *Config) ReadEnvironment() error {
// TLS Config
{
var foundTLSConfig bool
if v := os.Getenv(EnvBoundaryCACert); v != "" {
if v := Getenv(EnvBoundaryCACert); v != "" {
foundTLSConfig = true
envCACert = v
}
if v := os.Getenv(EnvBoundaryCAPath); v != "" {
if v := Getenv(EnvBoundaryCAPath); v != "" {
foundTLSConfig = true
envCAPath = v
}
if v := os.Getenv(EnvBoundaryClientCert); v != "" {
if v := Getenv(EnvBoundaryClientCert); v != "" {
foundTLSConfig = true
envClientCert = v
}
if v := os.Getenv(EnvBoundaryClientKey); v != "" {
if v := Getenv(EnvBoundaryClientKey); v != "" {
foundTLSConfig = true
envClientKey = v
}
if v := os.Getenv(EnvBoundaryTLSInsecure); v != "" {
if v := Getenv(EnvBoundaryTLSInsecure); v != "" {
foundTLSConfig = true
var err error
envInsecure, err = strconv.ParseBool(v)
if err != nil {
return fmt.Errorf("could not parse BOUNDARY_TLS_INSECURE")
return fmt.Errorf("could not parse THRESHOLD_TLS_INSECURE")
}
}
if v := os.Getenv(EnvBoundaryTLSServerName); v != "" {
if v := Getenv(EnvBoundaryTLSServerName); v != "" {
foundTLSConfig = true
envServerName = v
}
@@ -405,7 +404,7 @@ func parseRateLimit(val string) (rate float64, burst int, err error) {
return rate, burst, err
}
// Client is the client to the Boundary API. Create a client with NewClient.
// Client is the client to the Threshold API. Create a client with NewClient.
type Client struct {
modifyLock sync.RWMutex
config *Config
@@ -413,10 +412,10 @@ type Client struct {
// NewClient returns a new client for the given configuration.
//
// If the configuration is nil, Boundary will use configuration from
// If the configuration is nil, Threshold will use configuration from
// DefaultConfig(), which is the recommended starting configuration.
//
// If the environment variable `BOUNDARY_TOKEN` is present, the token will be
// If the environment variable `THRESHOLD_TOKEN` is present, the token will be
// automatically added to the client. Otherwise, you must manually call
// `SetToken()`.
func NewClient(c *Config) (*Client, error) {
@@ -465,9 +464,9 @@ func (c *Client) Addr() string {
return c.config.Addr
}
// Sets the address of Boundary in the client. The format of address should
// Sets the address of Threshold in the client. The format of address should
// be "<Scheme>://<Host>:<Port>". Setting this on a client will override the
// value of the BOUNDARY_ADDR environment variable.
// value of the THRESHOLD_ADDR environment variable.
func (c *Client) SetAddr(addr string) error {
c.modifyLock.Lock()
defer c.modifyLock.Unlock()
@@ -624,7 +623,7 @@ func copyHeaders(in http.Header) http.Header {
return ret
}
// NewRequest creates a new raw request object to query the Boundary controller
// NewRequest creates a new raw request object to query the Threshold controller
// configured for this client. This is an advanced method and generally
// doesn't need to be called externally.
func (c *Client) NewRequest(ctx context.Context, method, requestPath string, body any, opt ...Option) (*retryablehttp.Request, error) {
@@ -762,7 +761,7 @@ func (c *Client) Do(r *retryablehttp.Request, opt ...Option) (*Response, error)
return !unicode.IsPrint(c)
})
if idx != -1 {
return nil, fmt.Errorf("configured Boundary token contains non-printable characters and cannot be used")
return nil, fmt.Errorf("configured Threshold token contains non-printable characters and cannot be used")
}
if outputCurlString {
@@ -848,9 +847,9 @@ func (c *Client) Do(r *retryablehttp.Request, opt ...Option) (*Response, error)
"but the client is configured to use TLS. Please either enable TLS\n"+
"on the server or run the client with -address set to an address\n"+
"that uses the http protocol:\n\n"+
" boundary <command> -address http://<address>\n\n"+
"You can also set the BOUNDARY_ADDR environment variable:\n\n\n"+
" BOUNDARY_ADDR=http://<address> boundary <command>\n\n"+
" threshold <command> -address http://<address>\n\n"+
"You can also set the THRESHOLD_ADDR environment variable:\n\n\n"+
" THRESHOLD_ADDR=http://<address> threshold <command>\n\n"+
"where <address> is replaced by the actual address to the controller.",
err)
}
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type CredentialLibrary struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Credential struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type CredentialStore struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+56
View File
@@ -0,0 +1,56 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package api
import (
"os"
"strings"
)
const (
// legacyEnvPrefix is the environment variable prefix used by upstream
// HashiCorp Boundary. It is still honored as a fallback.
legacyEnvPrefix = "BOUNDARY_"
// envPrefix is the preferred environment variable prefix for Threshold.
envPrefix = "THRESHOLD_"
)
// PreferredEnvName returns the Threshold (THRESHOLD_*) form of an environment
// variable name. Names that do not use the legacy BOUNDARY_ prefix are
// returned unchanged.
func PreferredEnvName(name string) string {
if strings.HasPrefix(name, legacyEnvPrefix) {
return envPrefix + strings.TrimPrefix(name, legacyEnvPrefix)
}
return name
}
// LegacyEnvName returns the legacy (BOUNDARY_*) form of an environment
// variable name. Names that do not use the THRESHOLD_ prefix are returned
// unchanged.
func LegacyEnvName(name string) string {
if strings.HasPrefix(name, envPrefix) {
return legacyEnvPrefix + strings.TrimPrefix(name, envPrefix)
}
return name
}
// LookupEnv looks up an environment variable, preferring the THRESHOLD_*
// name and falling back to the legacy BOUNDARY_* name. The name may be given
// with either prefix; names with neither prefix are looked up as-is.
func LookupEnv(name string) (string, bool) {
if v, ok := os.LookupEnv(PreferredEnvName(LegacyEnvName(name))); ok {
return v, true
}
return os.LookupEnv(LegacyEnvName(name))
}
// Getenv is like os.Getenv but follows the LookupEnv precedence. A set but
// empty THRESHOLD_* variable falls through to the legacy BOUNDARY_* variable.
func Getenv(name string) string {
if v := os.Getenv(PreferredEnvName(LegacyEnvName(name))); v != "" {
return v
}
return os.Getenv(LegacyEnvName(name))
}
+24
View File
@@ -0,0 +1,24 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package api
import "testing"
func TestEnvFallback(t *testing.T) {
t.Setenv("THRESHOLD_ZZ_TEST", "")
t.Setenv("BOUNDARY_ZZ_TEST", "old")
if got := Getenv("BOUNDARY_ZZ_TEST"); got != "old" {
t.Fatalf("want old, got %q", got)
}
t.Setenv("THRESHOLD_ZZ_TEST", "new")
if got := Getenv("BOUNDARY_ZZ_TEST"); got != "new" {
t.Fatalf("want new, got %q", got)
}
if got, ok := LookupEnv("THRESHOLD_ZZ_TEST"); !ok || got != "new" {
t.Fatalf("want new, got %q %v", got, ok)
}
if PreferredEnvName("BOUNDARY_ADDR") != "THRESHOLD_ADDR" || LegacyEnvName("THRESHOLD_ADDR") != "BOUNDARY_ADDR" {
t.Fatal("name mapping")
}
}
+4 -4
View File
@@ -1,11 +1,10 @@
module github.com/hashicorp/boundary/api
module repo.anhonesthost.net/CyberCoveLLC/threshold/api
go 1.26.9
require (
github.com/coder/websocket v1.8.14
github.com/google/go-cmp v0.7.0
github.com/hashicorp/boundary/sdk v0.0.56
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-kms-wrapping/v2 v2.0.20
github.com/hashicorp/go-retryablehttp v0.7.8
@@ -22,6 +21,7 @@ require (
golang.org/x/time v0.14.0
google.golang.org/grpc v1.85.0-dev.0.20260825072537-93e31b48545e
google.golang.org/protobuf v1.36.12
repo.anhonesthost.net/CyberCoveLLC/threshold/sdk v0.1.0
)
require (
@@ -38,8 +38,8 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.56.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/crypto v0.57.0 // indirect
golang.org/x/sys v0.48.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260817212433-ac3dfec99bb1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+10 -10
View File
@@ -23,8 +23,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/boundary/sdk v0.0.56 h1:A/Wdd1A4qENjdnkvWQ20Igahs/3BSdbTPPL+A09BGMc=
github.com/hashicorp/boundary/sdk v0.0.56/go.mod h1:cnudX5/Su+aPPcsK5vrQ6Y2t0OsERgT5oweQ7x0wNTs=
github.com/hashicorp/cli v1.1.7 h1:/fZJ+hNdwfTSfsxMBa9WWMlfjUZbX8/LnUxgAd7lCVU=
github.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -124,14 +122,14 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y=
golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU=
golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
google.golang.org/genproto/googleapis/api v0.0.0-20260817212433-ac3dfec99bb1 h1:lrupDmKL3p5kEX1M92oan027eCKcouzjuPbH6YBK+Rs=
@@ -147,3 +145,5 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
repo.anhonesthost.net/CyberCoveLLC/threshold/sdk v0.1.0 h1:ExuSGqE1pA/1DnS5xrSK7kEhD+4g5hIJC5TgmwH5LAU=
repo.anhonesthost.net/CyberCoveLLC/threshold/sdk v0.1.0/go.mod h1:cWxYF3tEkYEKTY76ub8kL+vdGmopO0YfJqJGGQJov7k=
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Group struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/plugins"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/plugins"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type HostCatalog struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/plugins"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/plugins"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Host struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/plugins"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/plugins"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type HostSet struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type ManagedGroup struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+4 -5
View File
@@ -5,7 +5,6 @@ package api
import (
"fmt"
"os"
"strings"
retryablehttp "github.com/hashicorp/go-retryablehttp"
@@ -60,15 +59,15 @@ func (d *OutputStringError) parseRequest() {
for k, v := range d.Request.Header {
for _, h := range v {
if strings.ToLower(k) == "authorization" {
tokenName := os.Getenv("BOUNDARY_TOKEN_NAME")
keyringType := os.Getenv("BOUNDARY_KEYRING_TYPE")
tokenName := Getenv("THRESHOLD_TOKEN_NAME")
keyringType := Getenv("THRESHOLD_KEYRING_TYPE")
switch {
case tokenName == "none" || keyringType == "none":
h = `Bearer <token>`
case tokenName == "" && keyringType == "":
h = `Bearer $(boundary config get-token)`
h = `Bearer $(threshold config get-token)`
default:
h = fmt.Sprintf("Bearer $(boundary config get-token -keyring-type %s -token-name %s)", keyringType, tokenName)
h = fmt.Sprintf("Bearer $(threshold config get-token -keyring-type %s -token-name %s)", keyringType, tokenName)
}
}
d.parsedCurlString = fmt.Sprintf("%s -H \"%s: %s\"", d.parsedCurlString, k, h)
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Policy struct {
+1 -1
View File
@@ -6,7 +6,7 @@ package proxy
import (
"errors"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
"github.com/mitchellh/mapstructure"
)
+1 -1
View File
@@ -6,7 +6,7 @@ package proxy
import (
"testing"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"net/netip"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
)
// getOpts iterates the inbound Options and returns a struct and any errors
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
+3 -3
View File
@@ -15,9 +15,9 @@ import (
"sync/atomic"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/sessions"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/sessions"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-secure-stdlib/base62"
"github.com/hashicorp/go-secure-stdlib/temperror"
+2 -2
View File
@@ -15,8 +15,8 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/boundary/api/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/targets"
"github.com/mitchellh/copystructure"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"sync"
"github.com/coder/websocket"
"github.com/hashicorp/boundary/api/consts"
pb "github.com/hashicorp/boundary/sdk/pbs/proxy"
"github.com/hashicorp/boundary/sdk/wspb"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/consts"
pb "repo.anhonesthost.net/CyberCoveLLC/threshold/sdk/pbs/proxy"
"repo.anhonesthost.net/CyberCoveLLC/threshold/sdk/wspb"
)
func (p *ClientProxy) getWsConn(ctx context.Context) (*websocket.Conn, error) {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Role struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"fmt"
"net/url"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type KeyListResult struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type Scope struct {
@@ -7,7 +7,7 @@ package sessionrecordings
import (
"time"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type ChannelRecording struct {
@@ -7,7 +7,7 @@ package sessionrecordings
import (
"time"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type ConnectionRecording struct {
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"slices"
"strconv"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Download makes a Boundary request to download the requested session recording
+2 -2
View File
@@ -7,8 +7,8 @@ package sessionrecordings
import (
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Export struct {
+1 -1
View File
@@ -5,7 +5,7 @@
package sessionrecordings
import (
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type HostCatalog struct {
+1 -1
View File
@@ -7,7 +7,7 @@ package sessionrecordings
import (
"strconv"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
@@ -13,8 +13,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type SessionRecording struct {
+1 -1
View File
@@ -5,7 +5,7 @@
package sessionrecordings
import (
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Target struct {
+1 -1
View File
@@ -5,7 +5,7 @@
package sessionrecordings
import (
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type User struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"fmt"
"net/url"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
func (c *Client) Cancel(ctx context.Context, sessionId string, version uint32, opt ...Option) (*SessionUpdateResult, error) {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -13,8 +13,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Session struct {
+1 -1
View File
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+3 -3
View File
@@ -14,9 +14,9 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/plugins"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/plugins"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type StorageBucket struct {
+3 -3
View File
@@ -10,9 +10,9 @@ import (
"fmt"
"net/url"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
targetspb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
targetspb "repo.anhonesthost.net/CyberCoveLLC/threshold/sdk/pbs/controller/api/resources/targets"
"github.com/mr-tron/base58"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+1 -1
View File
@@ -7,7 +7,7 @@ package targets
import (
"time"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type SessionAuthorization struct {
@@ -7,7 +7,7 @@ package targets
import (
"time"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type SessionAuthorizationData struct {
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type Target struct {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"fmt"
"net/url"
"github.com/hashicorp/boundary/api/aliases"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/aliases"
)
// ListResolvableAliases builds and sends a request to the API for listing
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
// Option is a func that sets optional attributes for a call. This does not need
+2 -2
View File
@@ -14,8 +14,8 @@ import (
"strconv"
"time"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api/scopes"
)
type User struct {
+1 -1
View File
@@ -5,7 +5,7 @@
package workers
import (
"github.com/hashicorp/boundary/api"
"repo.anhonesthost.net/CyberCoveLLC/threshold/api"
)
type CertificateAuthority struct {
Loaded 100 of 1938 files, more files were not shown because too many files have changed in this diff. Show more