Skip to content

Commit 5f45ff1

Browse files
authored
build(docker): init openbao (#1844)
it is now possible to select the authentication mechanism for openbao (for now only token is supported) when using a token as authentication method with openbao, this token is added by default to client requests, unless another token is specified Signed-off-by: Francesco Noacco <francesco.noacco@secomind.com>
1 parent c98b9ad commit 5f45ff1

File tree

7 files changed

+161
-2
lines changed

7 files changed

+161
-2
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ VERNEMQ_ENABLE_SSL_LISTENER=true
1919

2020
CLUSTERING_STRATEGY=docker-compose
2121
RELEASE_COOKIE=astarte-docker-compose
22+
23+
ASTARTE_OPENBAO_AUTHENTICATION_MECHANISM="token"
24+
ASTARTE_OPENBAO_TOKEN="astarte_token"

apps/astarte_pairing/config/test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,7 @@ config :astarte_pairing, :base_url_port, 4003
103103
config :astarte_pairing, :base_url_protocol, :http
104104
config :astarte_pairing, :enable_credential_reuse, true
105105

106+
config :astarte_pairing, bao_authentication_mechanism: :token, bao_token: ""
107+
106108
config :bcrypt_elixir,
107109
log_rounds: 4

apps/astarte_pairing/lib/astarte_pairing/config.ex

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ defmodule Astarte.Pairing.Config do
2727
alias Astarte.Pairing.Config
2828
alias Astarte.Pairing.Config.BaseURLProtocol
2929
alias Astarte.Pairing.Config.CQExNodes
30+
alias Astarte.Pairing.Config.OpenBaoAuthenticationMechanism
3031

3132
@envdoc "The external broker URL which should be used by devices."
3233
app_env :broker_url, :astarte_pairing, :broker_url,
@@ -81,12 +82,26 @@ defmodule Astarte.Pairing.Config do
8182
type: :binary,
8283
default: "http://rendezvous:8041"
8384

84-
# TODO: properly set default value once available in docker-compose
8585
@envdoc "The URL to access OpenBao."
8686
app_env :bao_url, :astarte_pairing, :bao_url,
8787
os_env: "ASTARTE_OPENBAO_URL",
8888
type: :binary,
89-
default: ""
89+
default: "http://localhost:8200"
90+
91+
@envdoc "Internal variable used to store bao authentication"
92+
app_env :bao_authentication, :astarte_pairing, :bao_authentication,
93+
binding_skip: [:system],
94+
type: :any
95+
96+
@envdoc "The mechanism to use for authenticating with OpenBao"
97+
app_env :bao_authentication_mechanism, :astarte_pairing, :bao_authentication_mechanism,
98+
os_env: "ASTARTE_OPENBAO_AUTHENTICATION_MECHANISM",
99+
type: OpenBaoAuthenticationMechanism
100+
101+
@envdoc "Token to authenticate with OpenBao"
102+
app_env :bao_token, :astarte_pairing, :bao_token,
103+
os_env: "ASTARTE_OPENBAO_TOKEN",
104+
type: :binary
90105

91106
@envdoc "Enable SSL for the OpenBao connection. If not specified, SSL is disabled."
92107
app_env :bao_ssl_enabled, :astarte_housekeeping, :bao_ssl_enabled,
@@ -169,6 +184,9 @@ defmodule Astarte.Pairing.Config do
169184
if !Enum.all?(variables_to_check, &variable_set?(&1)) do
170185
raise "FDO feature is enabled but not all its parameters are configured"
171186
end
187+
188+
parse_bao_authentication!()
189+
|> put_bao_authentication()
172190
end
173191
end
174192

@@ -226,4 +244,17 @@ defmodule Astarte.Pairing.Config do
226244
false
227245
end
228246
end
247+
248+
defp parse_bao_authentication! do
249+
case Config.bao_authentication_mechanism!() do
250+
nil ->
251+
raise "OpenBao authentication method not set"
252+
253+
:token ->
254+
case Config.bao_token!() do
255+
nil -> raise "OpenBao token not set"
256+
token -> {:token, token}
257+
end
258+
end
259+
end
229260
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2026 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# SPDX-License-Identifier: Apache-2.0
19+
#
20+
21+
defmodule Astarte.Pairing.Config.OpenBaoAuthenticationMechanism do
22+
@moduledoc """
23+
The mechanism to use to authenticate with OpenBao
24+
"""
25+
26+
use Skogsra.Type
27+
28+
@methods [:token]
29+
@methods_map Map.new(@methods, &{Atom.to_string(&1), &1})
30+
31+
@impl Skogsra.Type
32+
def cast(value) when is_binary(value) do
33+
Map.fetch(@methods_map, value)
34+
end
35+
36+
@impl Skogsra.Type
37+
def cast(value) when value in @methods, do: {:ok, value}
38+
39+
@impl Skogsra.Type
40+
def cast(_), do: :error
41+
end

apps/astarte_pairing/lib/astarte_pairing/fdo/open_bao/client.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,26 @@ defmodule Astarte.Pairing.FDO.OpenBao.Client do
3838

3939
Keyword.merge(auth_opts, options)
4040
end
41+
42+
@impl true
43+
def process_request_headers(headers) do
44+
case Config.bao_authentication() do
45+
{:ok, {:token, token}} ->
46+
maybe_add_default_token(headers, token)
47+
48+
_ ->
49+
headers
50+
end
51+
end
52+
53+
defp maybe_add_default_token(headers, token) do
54+
# If the token is not already set, add the default token
55+
case Enum.find(headers, &authentication_header?/1) do
56+
nil -> [{"X-Vault-Token", token} | headers]
57+
_ -> headers
58+
end
59+
end
60+
61+
defp authentication_header?({header, _value}),
62+
do: String.downcase(header, :ascii) in ["x-vault-token", "authorization"]
4163
end

apps/astarte_pairing/test/astarte_pairing/fdo/open_bao/client_test.exs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,54 @@ defmodule Astarte.Pairing.FDO.OpenBao.ClientTest do
9595
end
9696
end
9797

98+
describe "using token authentication" do
99+
setup :token_authentication
100+
101+
test "the token header is not added if the 'Authorization' header exists" do
102+
path = "/example"
103+
new_token = UUID.uuid4()
104+
bearer = "Bearer " <> new_token
105+
106+
validate_request(fn _method, _url, headers, _body, _opts ->
107+
assert [bearer] == get_header(headers, "authorization")
108+
assert [] == get_header(headers, "x-vault-token")
109+
end)
110+
111+
Client.get(path, [{"Authorization", bearer}])
112+
end
113+
114+
test "the token header is not added if the 'X-Vault-Token' header exists" do
115+
path = "/example"
116+
new_token = UUID.uuid4()
117+
118+
validate_request(fn _method, _url, headers, _body, _opts ->
119+
assert [] == get_header(headers, "authorization")
120+
assert [new_token] == get_header(headers, "x-vault-token")
121+
end)
122+
123+
Client.get(path, [{"X-Vault-Token", new_token}])
124+
end
125+
126+
test "adds the vault token if no other token is specified", %{token: token} do
127+
path = "/example"
128+
129+
validate_request(fn _method, _url, headers, _body, _opts ->
130+
assert [] == get_header(headers, "authorization")
131+
assert [token] == get_header(headers, "x-vault-token")
132+
end)
133+
134+
Client.get(path)
135+
end
136+
end
137+
138+
defp token_authentication(_context) do
139+
token = UUID.uuid4()
140+
stub(Config, :bao_authentication, fn -> {:ok, {:token, token}} end)
141+
stub(Config, :bao_authentication!, fn -> {:token, token} end)
142+
143+
%{token: token}
144+
end
145+
98146
defp enable_ssl(_context) do
99147
stub(Config, :bao_ssl_enabled!, fn -> true end)
100148
:ok
@@ -106,4 +154,11 @@ defmodule Astarte.Pairing.FDO.OpenBao.ClientTest do
106154
{:ok, 200, []}
107155
end)
108156
end
157+
158+
defp get_header(headers, header) do
159+
Enum.filter(headers, fn {header_name, _} ->
160+
String.downcase(header_name) == header
161+
end)
162+
|> Enum.map(fn {_header, value} -> value end)
163+
end
109164
end

docker-compose.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ services:
6868
ASTARTE_BASE_URL_PROTOCOL: "http"
6969
PAIRING_FDO_RENDEZVOUS_URL: "http://rendezvous:8041"
7070
PAIRING_FDO_ENABLE_CREDENTIAL_REUSE: true
71+
ASTARTE_OPENBAO_URL: "http://openbao:8200"
7172
restart: on-failure
7273
depends_on:
7374
- "rabbitmq"
@@ -216,6 +217,10 @@ services:
216217
- broker.${DOCKER_COMPOSE_ASTARTE_BASE_DOMAIN}
217218
- ${FDO_REALM:-test}.api.${DOCKER_COMPOSE_ASTARTE_BASE_DOMAIN}
218219

220+
openbao:
221+
image: openbao/openbao:2
222+
command: server -dev -dev-root-token-id="${ASTARTE_OPENBAO_TOKEN}"
223+
219224
rendezvous:
220225
image: astarte/go-fdo-server:ade68cda47-20251128
221226
restart: on-failure

0 commit comments

Comments
 (0)