credentialfs

module
Version: v0.0.0-...-27f28e5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2021 License: Apache-2.0

README

CredentialFS

CI Build PkgGoDev GoReportCard Coverage

Userspace filesystem daemon for credentials stored in password managers

workflow

Why this project?

Say you are using password manager (abbrv. pm) for your own credential management, but you always have to store some of the credentials locally for apps without the support for reading from system keychain (e.g. rclone, kubectl), that can be risky once you have your computer hacked and the hacker can read these local credentials without your permit.

One solution is to develop a plugin or a wrapper script for these apps to read from system keychain, so you can store these credentials locally and safely.

Another solution is to mount a custom filesystem, which integrates with your password manager, and doesn't store credentials to local disk, everytime there is a file read operation to your credential files, the filesystem daemon will request explicit user authorization using system security feature to allow or deny the read operation.

Suitable Use Cases

  • Sync credential files among your working computers with online password manager
  • Store credentials directly in config files (e.g. kubeconfig using client certificate for authentication)
    • Then you can manage your home directory using a private git repo safely
  • Authorized automation: store passwords in files (e.g. ssh password)
    • Then you can cat /path/to/password in your automation scripts, and run your scripts after authorization process.

How it works?

  • Firstly it will sync credentials from your password managers, keep those required (as configured in the config file) in memory.
  • Then it will start a FUSE server, with all your credentials mounted in a single directory, symlink them to their target paths.
  • When there is a open() request to your credential, it will prompt an authorization dialog with caller's User Name + uid, Process Name + pid, Parent Process Name + ppid through system's security api.
    • The authorization request decision is made based on the value of sha256sum(uid + "|" + pid + "|" + ppid + "|" + path)
      • NOTE: To reduce uncessary authorization for command line users, pid here is the executable name (if we can determine).
  • The mounted credentials (files) can only be read by the open() caller after a successful authorization.
    • You can configure how long a successful authorization will last to avoid frequent interruptions.

Features

  • Mount your credentials as in memory files for authorized automation
  • Continuous syncing with your own password manager
  • Encrypted in memory credential cache (see issue#4)

Support Matrix

  • Authorization Service
    • OS Native
      • macos (requires osxfuse)
      • windows (TODO)
      • linux (TODO)
    • External Device (TODO)
    • External Network Service (TODO)
      • webauthn (fido2)
  • Password Managers
  • Login Method
    • Simple username + password
    • 2FA (TODO)
      • username + password + one time password
      • username + password + U2F
    • Passwordless (TODO)

Config

Create a yaml config file like this:

app:
  log:
  - level: verbose
    file: stderr

  # configure authorization service
  auth_service:
    # name of the authorization service, one of [system, webhook]
    name: system
    # please refer to ./docs/authorization
    config: {}

  # use system keychain service
  keychain_service:
    name: system

fs:
  # global mountpoint, all your credentials will be mounted to this
  # directory, you can find all files listed in `fs.spec[*].mounts.from`
  # in this directory, however their names are hex encoded string of
  # sha256 hash of `fs.spec[*].mounts.to`
  #
  # leave it empty to use random temporary dir for mountpoint
  mountpoint: ""

  # show fuse debug log output
  debug: false

  # choose login interface
  # currently only supports `cli`
  login_interface: cli

  # NOTE: the authorization is process specific as noted in `How it works?`
  #       their penalty & permit durations are timed individually

  # duration to always deny access after authorization failed
  default_penalty_duration: 10s

  # duration to always allow access after authorization succeeded
  #
  # defaults to 0, which means always request authorization
  default_permit_duration: 0s

  # filesystem spec
  # list of password managers and their file mounts
  spec:
  - pm:
      # (required) unique name (among all local credentialfs config) of this password manager config
      name: my-pm
      # (required) currently only supports `bitwarden`
      driver: bitwarden
      # please read ./docs/pm/{driver}.md for config reference
      config: {}
    # mount credentials as files from the password manager above
    #
    # NOTE: The mount operation here actually creates symlinks for your
    #       `mounts[*].to` since we haven't found a reasonabley easy way
    #       to support file bind mount on all platforms, please let us
    #       know by creating a new issue if you have a good idea.
    mounts:
    - from: <Item Name>/<Item Key>
      # local mount path
      to: ${HOME}/.ssh/joe.doyle

      # override defaultPenaltyDuration
      penalty_duration: 5s

      # override defaultPermitDuration
      permit_duration: 5s

Build and Install

Clonse this repo and run

go build -o build/credentialfs ./cmd/credentialfs

in the repo root, you can find the built executable at ./build/credentialfs, move it to somewhere you can access.

Run

/path/to/credentialfs

By default, it will read your config file at ${HOME}/.config/credentiafs/config.yaml, you can also specify your custom config file with -c /path/to/your/config

LICENSE

Copyright 2020 The arhat.dev Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL