Skip to content

Commit 973c1a0

Browse files
committed
add shared_secret parameter to provider that creates a token for the bootstrap service account
1 parent c4c57d3 commit 973c1a0

File tree

7 files changed

+88
-27
lines changed

7 files changed

+88
-27
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ go.work.sum
2424
# env file
2525
.env
2626
.DS_Store
27+
bin

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ lint:
44
@echo "@==> $@"
55
@VERSION=$$(go run github.com/mikefarah/yq/[email protected] '.jobs.lint.steps[] | select(.uses == "golangci/golangci-lint-action*") | .with.version' .github/workflows/test.yml) && \
66
go run github.com/golangci/golangci-lint/cmd/golangci-lint@$$VERSION run --fix --timeout=20m ./...
7+
8+
.PHONY: build
9+
build:
10+
@echo "@==> $@"
11+
@go build -o bin/terraform-provider-pomerium

example/main.tf

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
terraform {
2-
required_providers {
3-
pomerium = {
4-
source = "github.com/pomerium/enterprise-terraform-provider"
5-
version = "0.0.1"
6-
}
2+
required_providers {
3+
pomerium = {
4+
source = "pomerium/pomerium"
5+
version = "0.0.1"
76
}
8-
}
9-
10-
variable "pomerium_service_account_token" {
11-
type = string
12-
sensitive = true
7+
}
138
}
149

1510
provider "pomerium" {
16-
api_url = "https://console-api.localhost.pomerium.io"
17-
tls_insecure_skip_verify = true
18-
service_account_token = var.pomerium_service_account_token
11+
api_url = "https://console-api.localhost.pomerium.io"
12+
tls_insecure_skip_verify = true
13+
# service_account_token = var.pomerium_service_account_token
14+
shared_secret_b64 = "9OkZR6hwfmVD3a7Sfmgq58lUbFJGGz4hl/R9xbHFCAg="
1915
}
2016

21-
resource "pomerium_namespace" "test_namespace" {
22-
name = "test-namespace"
23-
parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
17+
# resource "pomerium_namespace" "test_namespace" {
18+
# name = "test-namespace"
19+
# parent_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
20+
# }
21+
22+
locals {
23+
namespace_id = "9d8dbd2c-8cce-4e66-9c1f-c490b4a07243"
2424
}
2525

2626
resource "pomerium_policy" "test_policy" {
2727
name = "test-policy"
28-
namespace_id = pomerium_namespace.test_namespace.id
28+
namespace_id = local.namespace_id
2929
ppl = <<EOF
3030
- allow:
3131
and:
@@ -35,7 +35,7 @@ EOF
3535

3636
resource "pomerium_route" "test_route" {
3737
name = "test-route"
38-
namespace_id = pomerium_namespace.test_namespace.id
38+
namespace_id = local.namespace_id
3939
from = "https://verify-tf.localhost.pomerium.io"
4040
to = ["https://verify.pomerium.com"]
4141
policies = [pomerium_policy.test_policy.id]

go.mod

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/pomerium/enterprise-terraform-provider
33
go 1.23.0
44

55
require (
6-
github.com/docker/cli v26.1.4+incompatible
6+
github.com/go-jose/go-jose/v3 v3.0.3
77
github.com/hashicorp/terraform-plugin-framework v1.11.0
88
github.com/hashicorp/terraform-plugin-log v0.9.0
99
github.com/pomerium/enterprise-client-go v0.18.1-0.20240903154554-9b855ec72cfd
@@ -22,7 +22,6 @@ require (
2222
github.com/envoyproxy/go-control-plane v0.13.0 // indirect
2323
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
2424
github.com/fatih/color v1.13.0 // indirect
25-
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
2625
github.com/golang/protobuf v1.5.4 // indirect
2726
github.com/google/btree v1.1.3 // indirect
2827
github.com/google/uuid v1.6.0 // indirect
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package provider
2+
3+
import (
4+
"encoding/base64"
5+
"fmt"
6+
"time"
7+
8+
"github.com/go-jose/go-jose/v3"
9+
"github.com/go-jose/go-jose/v3/jwt"
10+
"google.golang.org/grpc/codes"
11+
"google.golang.org/grpc/status"
12+
)
13+
14+
func generateBootstrapServiceAccountToken(
15+
sharedSecretB64 string,
16+
) (string, error) {
17+
sharedSecret, err := base64.StdEncoding.DecodeString(sharedSecretB64)
18+
if err != nil {
19+
return "", fmt.Errorf("shared_secret is invalid: %w", err)
20+
}
21+
22+
sig, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: sharedSecret},
23+
(&jose.SignerOptions{}).WithType("JWT"))
24+
if err != nil {
25+
return "", status.Errorf(codes.Internal, "signing JWT: %s", err.Error())
26+
}
27+
28+
var claims struct {
29+
jwt.Claims
30+
}
31+
claims.ID = "014e587b-3f4b-4fcf-90a9-f6ecdf8154af"
32+
claims.Subject = "bootstrap-014e587b-3f4b-4fcf-90a9-f6ecdf8154af.pomerium"
33+
now := time.Now()
34+
claims.IssuedAt = jwt.NewNumericDate(now)
35+
claims.NotBefore = jwt.NewNumericDate(now)
36+
37+
rawJWT, err := jwt.Signed(sig).Claims(claims).CompactSerialize()
38+
if err != nil {
39+
return "", status.Errorf(codes.Internal, "signing JWT: %s", err.Error())
40+
}
41+
return rawJWT, nil
42+
}

internal/provider/namespace.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (r *NamespaceResource) Schema(_ context.Context, _ resource.SchemaRequest,
6262
},
6363
"parent_id": schema.StringAttribute{
6464
Description: "ID of the parent namespace (optional).",
65-
Optional: false,
65+
Optional: true,
6666
},
6767
},
6868
}

internal/provider/provider.go

+20-6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type PomeriumProvider struct {
3232
type PomeriumProviderModel struct {
3333
APIURL types.String `tfsdk:"api_url"`
3434
ServiceAccountToken types.String `tfsdk:"service_account_token"`
35+
SharedSecretB64 types.String `tfsdk:"shared_secret_b64"`
3536
TLSInsecureSkipVerify types.Bool `tfsdk:"tls_insecure_skip_verify"`
3637
}
3738

@@ -49,7 +50,12 @@ func (p *PomeriumProvider) Schema(_ context.Context, _ provider.SchemaRequest, r
4950
},
5051
"service_account_token": schema.StringAttribute{
5152
MarkdownDescription: "Pomerium Enterprise Service Account Token",
52-
Required: true,
53+
Optional: true,
54+
Sensitive: true,
55+
},
56+
"shared_secret_b64": schema.StringAttribute{
57+
MarkdownDescription: "Pomerium Shared Secret (base64 encoded)",
58+
Optional: true,
5359
Sensitive: true,
5460
},
5561
"tls_insecure_skip_verify": schema.BoolAttribute{
@@ -88,13 +94,21 @@ func (p *PomeriumProvider) Configure(ctx context.Context, req provider.Configure
8894
port = "443"
8995
}
9096

91-
if data.ServiceAccountToken.IsNull() {
92-
resp.Diagnostics.AddError("service_account_token is required", "service_account_token is required")
97+
tlsConfig := &tls.Config{InsecureSkipVerify: data.TLSInsecureSkipVerify.ValueBool()}
98+
var token string
99+
if !data.ServiceAccountToken.IsNull() {
100+
token = data.ServiceAccountToken.ValueString()
101+
} else if !data.SharedSecretB64.IsNull() {
102+
token, err = generateBootstrapServiceAccountToken(data.SharedSecretB64.ValueString())
103+
if err != nil {
104+
resp.Diagnostics.AddError("failed to decode shared_secret_b64", err.Error())
105+
return
106+
}
107+
} else {
108+
resp.Diagnostics.AddError("service_account_token or shared_secret_b64 is required", "service_account_token or shared_secret_b64 is required")
93109
return
94110
}
95-
96-
tlsConfig := &tls.Config{InsecureSkipVerify: data.TLSInsecureSkipVerify.ValueBool()}
97-
c, err := client.NewClient(ctx, net.JoinHostPort(host, port), data.ServiceAccountToken.ValueString(), client.WithTlsConfig(tlsConfig))
111+
c, err := client.NewClient(ctx, net.JoinHostPort(host, port), token, client.WithTlsConfig(tlsConfig))
98112
if err != nil {
99113
resp.Diagnostics.AddError("failed to create Pomerium Enterprise API client", err.Error())
100114
return

0 commit comments

Comments
 (0)