Skip to content

Commit df136fd

Browse files
committed
more docs cleanup
1 parent 364538f commit df136fd

File tree

11 files changed

+187
-130
lines changed

11 files changed

+187
-130
lines changed

packages/varlock-website/src/content/docs/env-spec/reference.mdx

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ BAZ= # @dec # this is @ignored too
5757

5858
### Decorators
5959

60-
Decorators are used within comments to attach structured data to specific config items, or within a standalone comment blockto alter a group of items or the entire document and loading process.
60+
Decorators are used within comments to attach structured data to specific config items, or within a standalone comment block to alter a group of items or the entire document and loading process.
6161

6262
- Each decorator has a name and optional value (`@name=value`) or is a bare function call `@func()`
6363
- Decorators with values may only be used once per comment block, while function calls may be used multiple times
@@ -91,7 +91,7 @@ A divider is a comment that serves as a separator, like a `<hr/>` in HTML.
9191
# ---
9292
ITEM1=
9393
ITEM2=
94-
# --- another divider ---
94+
# --- another divider ---
9595
ITEM3=
9696
```
9797

@@ -100,9 +100,9 @@ ITEM3=
100100
### Config Item Comments
101101
Comment lines directly preceeding an item will be attached to that item, along with the decorators contained within.
102102

103-
- A blank line or a divider will break the above comments from being attached to the item
103+
- A blank line or a divider will break the above comments from being attached to the item below
104104
- Both decorator and regular comment lines may be interspersed
105-
- Post-value comments may also contain decorators, but is not recommended
105+
- Post-value comments may also contain decorators, but should be used sparingly
106106

107107
```env-spec
108108
# these comments are attached to ITEM1 below
@@ -162,6 +162,7 @@ Values are interpreted similarly for config item values, decorator values, and v
162162
- A value in quotes is _always_ treated as a string -- `@d1="with spaces"`, `@trueString="true"`, `@numStr="123"`
163163
- All quote styles ``[`'"]`` are ok -- ``@dq="c" @bt=`b` @sq='a'``
164164
- Escaped quotes matching the wrapping quote style are ok -- `@ok="escaped\"quote"`
165+
- Single quote wrapped strings do not support [expansion (see below)](#expansion)
165166
- In `"` or `` ` `` wrapped values, the string `\n` will be converted to an actual newline
166167
- Multi-line strings may be wrapped in ``(```|"""|"|')``
167168
- only available for config item values, not decorators or within function args
@@ -175,7 +176,7 @@ In each case, much of the handling is the same.
175176
- a value must not be wrapped in quotes to be interpreted as a function call
176177
- function names must start with a letter, and can then contain letters, numbers, and underscores `/[a-ZA-Z][a-ZA-Z0-9_]*/`
177178
- you can pass no args, a single arg, or multiple args
178-
- you may also pass key value pairs at the end of the list, and they will be combined into a single object at the end of the array
179+
- you may also pass key value pairs at the end of the list
179180
- each value will be interpreted using common value-handling rules (see above)
180181

181182
```env-spec
@@ -184,4 +185,28 @@ SINGLE_ARG=fn(asdf)
184185
MULTIPLE_ARGS=fn(one, "two", three, 123.456)
185186
KEY_VALUE_ARGS=fn(key1=v1, key2="v2", key3=true)
186187
MIXED_ARGS=fn(item1, item2, key1=v1, key2="v2", key3=true)
188+
NOT_FN_CALL="fn()" # treated as string
187189
```
190+
191+
### String expansion ||expansion||
192+
While the parser itself does not include any implemention of specific functions, it does handle _expansion_ of strings - and it uses several function calls under the hood to do so. This means a few basic function calls, while not implemented, have specific inherent meaning and must be implemented similarly across all tools that support this spec.
193+
194+
Expansion can be used within item values, decorator values, and function call arguments.
195+
196+
_Note that single quote wrapped strings are NOT expanded._
197+
198+
- `$ITEM_NAME` -> `ref(ITEM_NAME)`
199+
- `${ITEM_NAME}` -> `ref(ITEM_NAME)`
200+
- `pre${ITEM_NAME}post` -> `concat("pre", ref(ITEM_NAME), "post")`
201+
- `${ITEM_NAME:-defaultval}` -> `fallback(ref(ITEM_NAME), "defaultval")`
202+
- `${ITEM_NAME-defaultval}` -> `fallback(ref(ITEM_NAME), "defaultval")`
203+
- `$(my-cli arg --arg2)` -> `exec("my-cli arg --arg2")`
204+
205+
:::note[Keep it simple]
206+
We recommend using expansion only for simple refs `$ITEM`/`${ITEM}` and skipping the rest.
207+
208+
- Use bracketed version within a larger string - `fn("${ENV}_db")`
209+
- Skip the brackets otherwise - `fn($ENV)`
210+
211+
The rest is implemented to match other popular tools, but we do not recommend using them, as intent can be more clearly expressed using function calls directly.
212+
:::

packages/varlock-website/src/content/docs/guides/import.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ For now, all imported files must be `.env` files (and may contain @env-spec deco
2222

2323
### Single file
2424

25-
- Path must begin with `./` or `../`
25+
- Path must begin with `./` or `../` or `/`
2626
- Imported file name must be begin with `.env.`
2727

2828
```env-spec
@@ -31,7 +31,7 @@ For now, all imported files must be `.env` files (and may contain @env-spec deco
3131

3232
### Directory
3333

34-
- Path must begin with `./` or `../`
34+
- Path must begin with `./` or `../` or `/`
3535
- Path must end with a trailing `/`
3636
- Multiple `.env.*` files will be detected and loaded, based on the current environment flag, similar to what happens in the current directory (see [environments guide](/guides/environments#loading-environment-specific-env-files))
3737
- The environment flag value will be inherited, unless another `@currentEnv` is defined within the directory's `.env.schema`

packages/varlock-website/src/content/docs/guides/plugins.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ description: Using plugins with varlock
55

66
Plugins allow extending the functionality of Varlock. Specifically they may introduce new [root decorators](/reference/root-decorators/), [item decorators](/reference/item-decorators/), [data types](/reference/data-types/), and [resolver functions](/reference/functions/).
77

8-
```env-spec title="1Password plugin example" "@plugin" "@initOpVault" "opServiceAccountToken" /op\\(.*\\)/
8+
```env-spec title="1Password plugin example" "@plugin" "@initOp" "opServiceAccountToken" /op\\(.*\\)/
99
# @plugin(@varlock/1password-plugin) # load + install plugin
10-
# @initOpVault(allowAppAuth=true) # init via custom root decorator
10+
# @initOp(allowAppAuth=true) # init via custom root decorator
1111
# ---
1212
# @type=opServiceAccountToken # custom data type
1313
OP_TOKEN=
@@ -66,8 +66,8 @@ Plugins are initialized using custom root decorators that they introduce. In som
6666

6767
A plugin initialization root decorator is used to set IDs, toggle features, and wire up auth. Note that sensitive data should be passed in via references to config items within your schema.
6868

69-
```env-spec title="Plugin initialization example" "@initOpVault"
70-
# @initOpVault(account=acmeco, token=$OP_TOKEN, allowAppAuth=forEnv(dev))
69+
```env-spec title="Plugin initialization example" "@initOp"
70+
# @initOp(account=acmeco, token=$OP_TOKEN, allowAppAuth=forEnv(dev))
7171
# ---
7272
# @type=opServiceAccountToken @sensitive
7373
OP_TOKEN=
@@ -80,10 +80,10 @@ In secret storage tools, you should segment your data to follow the [_principle
8080
We cannot always assume that you won't need access to multiple segments at the same time. In these cases, a plugin may be designed to be initialized multiple times with some kind of id parameter. Resolver functions and decorators can then accept an additional parameter to specify which instance to use.
8181

8282

83-
```env-spec title=".env.schema" "@initOpVault" /id=[a-z]+/ /\\((dev),/
83+
```env-spec title=".env.schema" "@initOp" /id=[a-z]+/ /\\((dev),/
8484
# @plugin(@varlock/1password-plugin)
85-
# @initOpVault(id=dev, token=$OP_TOKEN_DEV, allowAppAuth=forEnv(dev))
86-
# @initOpVault(id=prod, token=$OP_TOKEN_PROD, allowAppAuth=false);
85+
# @initOp(id=dev, token=$OP_TOKEN_DEV, allowAppAuth=forEnv(dev))
86+
# @initOp(id=prod, token=$OP_TOKEN_PROD, allowAppAuth=false);
8787
# ---
8888
# @type=opServiceAccountToken @sensitive
8989
OP_TOKEN_DEV=

packages/varlock-website/src/content/docs/guides/schema.mdx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,30 +88,26 @@ Functions may be composed together to create more complex value resolution logic
8888

8989
```env-spec
9090
# @required=forEnv(prod)
91-
API_DOMAIN=if(eq($APP_ENV, prod), api.myapp.com, staging-api.myapp.com)
91+
API_DOMAIN=if(eq(ref(APP_ENV), prod), api.myapp.com, staging-api.myapp.com)
9292
```
9393

9494

95-
### Value Expansion ||expansion||
95+
### Referencing other values ||ref-expansion||
9696

97-
`varlock` supports _expansion_ like other .env tools - such as [dotenv-expand](https://github.com/motdotla/dotenv-expand). However unlike other tools, it uses [function calls](/reference/functions/) to implement this.
97+
Within values and function args, you often need to reference other env vars within your schema.
9898

99-
- `prefix-${OTHER}` -> `concat("prefix", ref("OTHER"))`
100-
- `$OTHER` -> `ref("OTHER")`
101-
- `${OTHER}` -> `ref("OTHER")`
102-
- `${OTHER:-defaultval}` -> `fallback(ref("OTHER"), "defaultval")`
103-
- `$(whoami)` -> `exec("whoami")`
99+
You may use [`ref()`](/reference/functions/#ref) but we support _expansion_ syntax (like many other .env tools) for convenience.
104100

105-
While you could call those functions directly, in many cases it will be more clear to use expansion, or a mix of function calls and expansion. For example:
101+
Both `$ITEM` and `${ITEM}` are equivalent to `ref(ITEM)`.
106102

107-
```env-spec
108-
OP_VAULT_NAME=api-config-prod
109-
MY_KEY=exec(`op read "op://${OP_VAULT_NAME}/service/api-key"`)
110-
```
111-
112-
More details:
103+
We recommend using the bracket version only when used within a larger string.
113104

105+
```env-spec /\\$\\{[^\\}]+\\}/ /\\$[A-Z]+/
106+
WITH_BRACKETS=exec(`op read "op://${OP_VAULT_NAME}/service/api-key"`)
107+
NO_BRACKETS=fallback($OTHERVAR, foo)
108+
```
114109

110+
Read more about string expansion in the [@env-spec reference](/env-spec/reference/#expansion).
115111

116112
## Decorator details
117113

packages/varlock-website/src/content/docs/plugins/1password.mdx

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,58 +21,73 @@ See the [plugins guide](/guides/plugins/#installation) for more instructions on
2121
# 1. Load the plugin
2222
# @plugin(@varlock/1password-plugin)
2323
#
24-
# 2. Initialize the plugin, wiring it up to a service account token (see step 3)
25-
# @initOpVault(token=$OP_TOKEN)
24+
# 2. Initialize the plugin - see below for more details on options
25+
# @initOp(token=$OP_TOKEN, allowAppAuth=forEnv(dev), account=acmeco)
2626
# ---
2727
28-
# 3. Add a service account token config item
28+
# 3. Add a service account token config item (if applicable)
2929
# @type=opServiceAccountToken @sensitive
3030
OP_TOKEN=
3131
```
3232

33-
### Vault & service account setup
33+
### Vault setup
3434

35-
If you already use 1Password and your secrets live in a vault that holds other sensitive data, you should create a new vault and move your secrets to it, because **the access system of 1Password is based on vaults, not individual items**.
35+
If your secrets are already stored in 1Password, you may not need to do anything. However, if secrets live in a vault that holds other sensitive data, you should create a new vault and move your secrets to it, because **the access system of 1Password is based on vaults, not individual items**.
3636

37-
<Steps>
37+
You can create multiple vaults to segment access to different environments, services, etc. This can be done using any 1Password app, the web app, or the CLI. [link](https://support.1password.com/create-share-vaults/#create-a-vault)
38+
39+
Remember to grant access to necessary team members, particularly if you plan on using the desktop app auth method during local development, as they will be authenticating as themselves.
40+
41+
:::tip[Vault organization best practices]
42+
Consider how you want to organize your vaults and service accounts, keeping in mind [best practices](https://support.1password.com/business-security-practices/#access-management-and-the-principle-of-least-privilege). At a minimum, we recommend having a vault for highly sensitive production secrets and another for everything else.
43+
:::
44+
45+
### Service account setup (for deployed environments)
46+
47+
If you plan on using data from 1Password in deployed environments (CI/CD, production, etc), you will need to create a [service account](https://developer.1password.com/docs/service-accounts/get-started/) to allow machine-to-machine authentication. You could also use a service account for local development, although we recommend using the desktop app auth method described below for convenience.
3848

39-
1. **Create a vault** in your 1Password account which will be used to hold your secrets. You can create multiple vaults to segment access to different environments, services, etc. This can be done using any 1Password app, the web app, or the CLI. [link](https://support.1password.com/create-share-vaults/#create-a-vault)
49+
This service account token will now serve as your _secret-zero_ - which grants access to the rest of your sensitive data stored in 1Password.
4050

41-
2. **Create a new service account** and grant access to necessary vault(s). This is a special account used for machine-to-machine communication. This can only be done in the 1Password web interface. Be sure to save the new service account token in another vault so you can find it later. [link](https://developer.1password.com/docs/service-accounts/get-started/)
51+
<Steps>
52+
1. **Create a new service account** and grant access to necessary vault(s). This is a special account used for machine-to-machine communication. This can only be done in the 1Password web interface. Be sure to save the new service account token in another vault so you can find it later. [link](https://developer.1password.com/docs/service-accounts/get-started/)
4253
:::note[Vault access is set during creation only]
4354
Vault access rules cannot be edited after creation, so if your vault setup changes, you will need to create new service account(s) and update the tokens.
4455
:::
4556

46-
3. **Grant vault access to users/teams (optional)**. Your developers may need access to at least some of your vaults, especially if using the app based auth mentioned below. [link](https://support.1password.com/create-share-vaults-teams/#share-a-vault)
47-
48-
4. **Ensure vault service account access is enabled (optional)**. Each vault has a toggle to disable service account access _in general_. It is on by default, so you will likely not need to do anything. [link](https://developer.1password.com/docs/service-accounts/manage-service-accounts/#manage-access)
57+
2. **Wire up the service account token in your config**. Add a config item of type `opServiceAccountToken` to hold the token value, and reference it when initializing the plugin.
4958

59+
```diff lang="env-spec" title=".env.schema" add="token=$OP_TOKEN"
60+
# @plugin(@varlock/1password-plugin)
61+
# @initOp(token=$OP_TOKEN)
62+
# ---
63+
+# @type=opServiceAccountToken @sensitive
64+
+OP_TOKEN=
65+
```
66+
3. **Set your service account token in deployed environments**. Copy the token value from where you saved it earlier, and set it in deployed environments using your platform's env var management UI. Be sure to use the same name as you defined in your schema (e.g. `OP_TOKEN`).
5067
</Steps>
5168

52-
This service account token will now serve as your _secret-zero_ - which grants access to the rest of your sensitive data stored in 1Password. It must be set locally (unless relying on app-based auth) and in any deployed environments, usually as an environment variable with your platform's env var management UI.
53-
54-
:::tip[Vault organization best practices]
55-
Consider how you want to organize your vaults and service accounts, keeping in mind [best practices](https://support.1password.com/business-security-practices/#access-management-and-the-principle-of-least-privilege). At a minimum, we recommend having a vault for highly sensitive production secrets and another for everything else.
69+
:::caution[Ensure service account access is enabled]
70+
Each vault has a toggle to disable service account access _in general_. It is on by default, so you will likely not need to do anything. [link](https://developer.1password.com/docs/service-accounts/manage-service-accounts/#manage-access)
5671
:::
5772

5873

59-
### Desktop app auth (optional)
74+
### Desktop app auth (for local dev)
6075

6176
During local development, you may find it convenient to skip the service account tokens and instead rely on your local 1Password desktop app (via the [CLI integration](https://developer.1password.com/docs/cli/get-started/#step-2-turn-on-the-1password-desktop-app-integration)), including using its biometric unlocking features.
6277

6378
<Steps>
6479
1. **Opt-in while initializing the plugin**
6580
```diff lang="env-spec" title='.env.schema' add="allowAppAuth=true"
6681
# @plugin(@varlock/1password-plugin)
67-
# @initOpVault(token=$OP_TOKEN, allowAppAuth=true)
82+
# @initOp(token=$OP_TOKEN, allowAppAuth=true)
6883
```
6984

7085
You may use other functions to conditionally enable this, for example `forEnv(dev)`.
7186

7287
2. **Specify 1Password account (optional)**
7388
```diff lang="env-spec" title='.env.schema' add="account=acmeco"
7489
# @plugin(@varlock/1password-plugin)
75-
# @initOpVault(token=$OP_TOKEN, allowAppAuth=true, account=acmeco)
90+
# @initOp(token=$OP_TOKEN, allowAppAuth=true, account=acmeco)
7691
```
7792

7893
This value is passed through under the `--account` flag to the `op` CLI, and accepts account shorthand, sign-in address, account ID, or user ID.
@@ -111,8 +126,8 @@ The secret reference for invidivual fields within an item can be found by clicki
111126
If you used the `id` param during initialization and have multiple instances, the `op()` function accepts an optional first parameter to specify which instance id to use.
112127

113128
```env-spec /dev|prod/
114-
# @initOpVault(id=dev, token=$OP_TOKEN_DEV, allowAppAuth=forEnv(dev))
115-
# @initOpVault(id=prod, token=$OP_TOKEN_PROD, allowAppAuth=false)
129+
# @initOp(id=dev, token=$OP_TOKEN_DEV, allowAppAuth=forEnv(dev))
130+
# @initOp(id=prod, token=$OP_TOKEN_PROD, allowAppAuth=false)
116131
# ---
117132
DEV_ITEM=op(dev, op://vault-name/item-name/field-name)
118133
PROD_ITEM=op(prod, op://vault-name/item-name/field-name)
@@ -130,18 +145,18 @@ PROD_ITEM=op(prod, op://vault-name/item-name/field-name)
130145
### Root decorators
131146
<div class="reference-docs">
132147
<div>
133-
#### `@initOpVault()`
148+
#### `@initOp()`
134149

135150
Initializes an instance of the 1Password plugin - setting up options and authentication. Can be called multiple times to set up different instances.
136151

137152
**Key/value args:**
138153
- `id` (optional): identifier for this instance, used when multiple instances are needed
139-
- `token`: service account token. Should be a reference to a config item of type `opServiceAccountToken`.
154+
- `token` (optional): service account token. Should be a reference to a config item of type `opServiceAccountToken`.
140155
- `allowAppAuth` (optional): boolean flag to enable authenticating using the local desktop app
141156
- `account` (optional): limits the `op` cli to connect to specific 1Password account (shorthand, sign-in address, account ID, or user ID)
142157

143-
```env-spec "@initOpVault"
144-
# @initOpVault(id=notProd, token=$OP_TOKEN, allowAppAuth=forEnv(dev), account=acmeco)
158+
```env-spec "@initOp"
159+
# @initOp(id=notProd, token=$OP_TOKEN, allowAppAuth=forEnv(dev), account=acmeco)
145160
# ---
146161
# @type=opServiceAccountToken
147162
OP_TOKEN=

0 commit comments

Comments
 (0)