Repository navigation
connections: folder default credentials for entries without their own - #269
jseifeddine wants to merge 1 commit into
Conversation
8a8b09b to
574c4df
Compare
|
I like the idea, a few things before it can go in:
Also, since the PRs are stacked, could you rebase this onto main on its own so it can be taken separately? |
574c4df to
195e15c
Compare
|
Thanks Dave, all four addressed and the PR is now on its own on main (one commit, nothing from #268). The defaults walk now follows the same rule as the access check: it only continues past a folder whose config has inherit_from_parent: true, so a key set on a parent never reaches an isolated subfolder, while that folder's own .defaults still apply to its entries; there's a unit test for exactly that boundary. vault-migrate copies .defaults beside .config (the dry run lists them). Both connect paths, the Connections endpoint and /api/connect, now go through a single lend_folder_defaults helper, with a direct test on it. The docs have a new "Folder default credentials" section in credential-variables.md, including a plain warning that a web entry using a default password has it typed into a page the user can read. The CI audit failure on this branch is the new quinn-proto advisories, not this change; #283 bumps the lockfile and the run goes green once that is in. |
195e15c to
55b8497
Compare
A folder can lend a username, password, private key and domain per session type to entries that have no password or private key of their own, so an entry created without secrets (a NetBox webhook, a bulk import) connects the moment it exists. The defaults live at `<folder>/.defaults` beside `.config`, are reserved like it (never listed, not a valid entry name) and are removed with the folder. `GET/PUT/DELETE .../defaults` manage them (secrets write-only, audited as update_folder_defaults / delete_folder_defaults) and the folder dialog gains a Default credentials section. Listings report such entries as `has_credentials: true` with `inherited_credentials: true`. An entry's own credentials always win and an entry set to prompt still prompts. A subfolder without its own `.defaults` takes its nearest ancestor's, per type, but the walk follows the access rule: it only continues past a folder whose `.config` has `inherit_from_parent: true`. That flag is how a folder is isolated for access, so a key set on a parent must not reach a subfolder shared with someone else through `allowed_users`. The isolated folder's own `.defaults` still apply to its entries. A folder with no `.config`, or one written before the flag existed, counts as not inheriting, exactly as `resolve_folder_access` treats it. The walk is `resolve_effective_defaults` over a small `DefaultsSource` trait so it is tested without a Vault. Both connect paths resolve defaults through one helper, `lend_folder_defaults`: the Connections endpoint (`POST .../entries/:entry/connect`) and `/api/connect` quick links, so an entry that works from the page works from a link. `rustguac vault-migrate` copies each folder's `.defaults` alongside its `.config`, so a DR split keeps them (the dry run lists them as `[defaults]`). Docs cover the storage layout, the inheritance rule and its boundary, the migrate behaviour, and the warning that a web entry using a default password has that password typed into a page the user can read. Part 2/3 of sol1#253.
55b8497 to
cc01469
Compare
|
Merged into main as ccd2bad thanks Jad. One thing still open from my first comment, fixed our side in b7596be: access is a union, so a subfolder that inherits but also has its own allowed_groups/allowed_users admits people the parent doesn't, and the walk only stopped at inherit_from_parent: false. A contractor added to corp/partner via allowed_users could connect with corp's key. Defaults now only flow into a subfolder that inherits and grants nobody of its own. Same commit: prompt entries no longer show as [folder], PUT defaults on a missing folder is a 404, RDP domain field in the dialog, and a docs line on $variables in defaults. Live tested on our canary. |
Based on current
mainon its own: one commit, nothing from any other open PR. Rebased over #252's table wrap rules (adjacent CSS inconnections.html, no functional change).Part 2/3 of #253.
What it does
A folder can lend a username / password / private key / domain per session type to entries that have no password or private key of their own, so an entry created without secrets (a NetBox webhook, a bulk import) connects the moment it exists. The defaults live at
<folder>/.defaultsbeside.config, are reserved like it (never listed as an entry, not a valid entry name) and are removed with the folder.GET/PUT/DELETE /api/addressbook/folders/:scope/:folder/defaults(admin): secrets are write-only, changes are audited asupdate_folder_defaults/delete_folder_defaults.has_credentials: truewithinherited_credentials: true; the table shows a[folder]marker.prompt_credentialsstill prompts..defaultstake their nearest ancestor's, per type, bounded byinherit_from_parent(below).Review changes
How each point of the review is handled:
inherit_from_parent: false. The walk (resolve_effective_defaultsinsrc/vault.rs) applies a folder's own.defaults, then continues to the parent only while the folder just visited hasinherit_from_parent: true, the same ruleresolve_folder_accessuses. A key set on a parent never reaches a subfolder isolated with that flag, so it cannot be used in a subfolder shared with someone else throughallowed_users; the isolated folder's own.defaultsstill apply to its entries. A folder with no.config, or one written before the flag existed, counts as not inheriting, exactly as the access check treats it. Tested ineffective_defaults_stop_at_a_folder_that_does_not_inherit.vault-migratecopies.defaults.src/migrate.rsreads each folder's.defaultsafter its.configand writes it to the destination (the dry run lists it as[defaults] <folder>); the module doc anddocs/migration.mdsay so. Talks to two live Vaults, so no unit test; it is the same shape as the.configcopy beside it./api/connectapplies the defaults. Both connect paths now go through one helper,lend_folder_defaultsinsrc/api.rs:ab_connect_entry(Connections page) andquick_connect(links). The helper is generic over the sameDefaultsSourcethe walk uses, solend_folder_defaults_fills_a_bare_entry_and_respects_the_boundaryexercises it directly, including the isolated-subfolder case and the prompt case.docs/credential-variables.md: where.defaultslives, how it applies, the inheritance rule and theinherit_from_parentboundary, the migrate behaviour, and Web entries: the password is visible to the user, which says outright that a web entry using a default password has it typed into a page the user can read. Cross-references fromdocs/roles-and-access-control.md(Inheritance),docs/api.md(quick connect and the defaults endpoints) anddocs/migration.md; the folder dialog hint says the same in one line.And the PR is rebased onto
mainon its own, as asked.Tests
folder_defaults_fill_only_entries_without_secrets(now also: an entry set to prompt takes nothing)entry_info_marks_inherited_credentialseffective_defaults_merge_nearest_first_through_inheriting_folderseffective_defaults_stop_at_a_folder_that_does_not_inheriteffective_defaults_propagate_read_errorslend_folder_defaults_fills_a_bare_entry_and_respects_the_boundarylend_folder_defaults_leaves_the_entry_alone_when_vault_failsManual, earlier revision: set an SSH default on a tenant folder, create an entry with no password: it shows Connect immediately and connects with the folder's key; a subfolder entry inherits;
GETnever returns the secret.