Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copy to .env and fill in. Required by markfluence.
# Then: chmod 600 .env -- it holds your API token, and markfluence warns if
# anyone else can read or write it.
# A template for your markfluence credentials file. Copy it to
# ~/.config/markfluence/credentials (or to a file you name with --env-file)
# and fill it in. Then chmod 600 the copy: it holds your API token, and
# markfluence warns if anyone else can read or write it.
CONFLUENCE_URL=https://your-org.atlassian.net
CONFLUENCE_USERNAME=you@example.com
CONFLUENCE_TOKEN=your-api-token
Expand Down
24 changes: 9 additions & 15 deletions CLAUDE.md

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ make test
Run `make` with no target to see the list of rules and their descriptions.
Remember `make check`. See the next section.

To use the binary with a real Confluence site, put a `.env` file in the working
directory. See [`.env.example`](.env.example) and the
[Configure](README.md#configure) section of the README.
To use the binary with a real Confluence site, create your credentials file at
`~/.config/markfluence/credentials`, or name a file with `--env-file`. See
[docs/credentials.md](docs/credentials.md) and
[`.env.example`](.env.example).

## Before you open a pull request

Expand Down
63 changes: 22 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ to use it. It also tells you where to find more documentation.
| [README.md](README.md), this file | installation, configuration, and use |
| [docs/commands/](docs/commands/) | the `--help` text of every command, as Markdown. It is the same text that `markfluence CMD --help` prints, and it comes from the binary |
| [docs/markdown-file.md](docs/markdown-file.md) | the page format: every frontmatter field, and what the converter does with each body construct |
| [docs/credentials.md](docs/credentials.md) | where markfluence reads credentials from, how to set up your credentials file, and what each credentials error means |
| [docs/root-model.md](docs/root-model.md) | the documentation root: how a tree of files maps to a tree of pages |
| [CONTRIBUTING.md](CONTRIBUTING.md) | how to contribute: the development setup, what to run before you open a pull request, the commit conventions, and how to file an issue |
| [docs/confluence/](docs/confluence/) | what we found out about Confluence by experiment: the API, the storage format, the scopes, and the traps that give you a confident wrong answer |
Expand Down Expand Up @@ -187,28 +188,16 @@ makes a network request.

## Configure

markfluence needs a Confluence site URL, a username, and an API token. It
resolves each one in this sequence: **the flag first, then the environment
variable, then the `.env` file**.
markfluence needs a Confluence site URL, a username, and an API token. Put them
in your credentials file one time on each computer:

| Setting | Flag | Environment variable or `.env` |
| --- | --- | --- |
| Site URL | `--url` | `CONFLUENCE_URL` |
| Username | `--username` | `CONFLUENCE_USERNAME` |
| API token | *none. It is never a flag* | `CONFLUENCE_TOKEN` |
| Cloud ID, optional | `--cloud-id` | `CONFLUENCE_CLOUD_ID` |

markfluence reads a `.env` file without help, so you do not need to `source`
it. It reads the file from the [documentation root](#the-documentation-root).
The documentation root is the directory that holds `markfluence.yaml`, and
markfluence finds it when it goes up from the working directory. If no
`markfluence.yaml` file is above the working directory, the root is the working
directory itself. You can also give an explicit path with `--env-file PATH`.
The `--root PATH` flag moves this path for the `create`, `update`, `diff`,
and `attachment-upload` commands. For those commands, and for `check`, `--root`
also moves the per-file root that they find by themselves.
```
mkdir -p ~/.config/markfluence
$EDITOR ~/.config/markfluence/credentials
chmod 600 ~/.config/markfluence/credentials
```

Copy `.env.example` to `.env` and fill it in:
The file holds these lines:

```
CONFLUENCE_URL=https://your-org.atlassian.net
Expand All @@ -218,32 +207,26 @@ CONFLUENCE_TOKEN=your-api-token
# CONFLUENCE_CLOUD_ID=
```

> [!NOTE]
> markfluence does not accept the API token as a command line flag. The token
> comes from the environment or from the `.env` file.

Then restrict the file, because it holds your API token:

```
chmod 600 .env
```
The environment variables of the same names override the file, and a file that
you name with `--env-file PATH` overrides both. There is no command-line flag
for any of these, so your API token cannot get into your shell history.
markfluence never reads credentials from the working directory or from a
project.

markfluence gives a warning when two conditions are both true. The first
condition is that the mode of the `.env` file gives a permission to a person who
is not you: read, write, or execute. The second condition is that the file holds
`CONFLUENCE_TOKEN`. The warning gives the name of the file, the fault in its
mode, and the `chmod` command that corrects it. If you run markfluence with
`--json`, markfluence does not print the warning. It puts the warning in the
`warnings` array of the output document, and in the error object on stderr.
stderr is a JSON document in that mode.
**[docs/credentials.md](docs/credentials.md) is the reference**: the places
that markfluence looks in, the two rules that stop it from sending a token to
the wrong site, how to use a different site for one command, the permission
warning, and what each credentials error means.

Optional: `alias mf=markfluence`

### Scoped tokens and service accounts

For a normal personal API token, do not set `CONFLUENCE_CLOUD_ID`.

You must set `CONFLUENCE_CLOUD_ID` for a **scoped** API token. An Atlassian
You must set `CONFLUENCE_CLOUD_ID` for a **scoped** API token, in the same place
as `CONFLUENCE_URL`. markfluence reads the cloud ID only from the place that
gives the URL, and warns about a cloud ID that it ignores. An Atlassian
[service account][svcacct] gets a scoped token, and you use it to publish from
CI. Atlassian refuses a scoped token with a **401** status against your site
domain. Thus markfluence must use the `api.atlassian.com` gateway of Atlassian,
Expand Down Expand Up @@ -671,9 +654,7 @@ directory of the file itself. The root bounds which images and which `parent:`
references a file can read. The recorded source path of an image is relative to
the root. markfluence reports the root that it used one time for each different
value in a run. The `--root PATH` flag overrides this search for the whole
command. For `create`, `update`, `diff`, and `attachment-upload`, it also moves
the directory that markfluence reads `.env` from. See
[Configure](#configure).
command.

For the reasons behind this model, what it corrects, and what it costs, see
[docs/root-model.md](docs/root-model.md) and
Expand Down
11 changes: 6 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ markfluence is an authenticated CLI: it holds a Confluence API token, reads loca
files to publish, and writes local files from what a Confluence site returns.
That gives it three security boundaries worth attacking.

**Leaking the API token.** The token is read only from `CONFLUENCE_TOKEN` or a
`.env` file, and is deliberately never accepted as a command-line flag, so it
can't end up in shell history, `ps` output, or a CI job log. Anything that gets
**Leaking the API token.** The token is read only from `CONFLUENCE_TOKEN`, the
user's credentials file, or a file named with `--env-file`, and is deliberately
never accepted as a command-line flag, so it can't end up in shell history,
`ps` output, or a CI job log. Anything that gets
it out anyway is a vulnerability: appearing in `--debug` output or an error
message, being written into a published page, or being sent to any host that
isn't your Confluence site or Atlassian's API gateway. A standing example of
Expand Down Expand Up @@ -74,5 +75,5 @@ page.
Dependabot already opens those weekly; a normal issue or PR is the right
channel. If you can show a way to actually reach it, that's a vulnerability —
please report it privately.
- **The permissions on your own `.env` file**, or credentials committed to your
own repository.
- **The permissions on your own credentials file**, or credentials committed to
your own repository.
Loading
Loading