Skip to content

Commit

Permalink
Service Account support (#54)
Browse files Browse the repository at this point in the history
* Adding service account support

* TRIVIAL: checking service account filled
  • Loading branch information
dtpryce authored Dec 22, 2023
1 parent f72efab commit d8b00bb
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 18 deletions.
43 changes: 33 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ The library is split into two parts: installation and client in which we are slo
systems as possible the following table should ensure users understand what this library can and can't do at time of
install.

| | MacOS | Linux |
|-----------------|-------|-------|
| Fully supported | Y | Y |
| CLI install | Y | Y |
| SSO login | Y | Y |
| Login via App | Y | Y |
| Biometrics auth | Y | Y |
| Password auth | Y | Y |
| CLI client | Y | Y |
| | MacOS | Linux |
|------------------|-------|-------|
| Fully supported | Y | Y |
| CLI install | Y | Y |
| SSO login | Y | Y |
| Login via App | Y | Y |
| Biometrics auth | Y | Y |
| Password auth | Y | Y |
| CLI client | Y | Y |
| Service account | Y | Y |

## Installation
```bash
Expand Down Expand Up @@ -106,7 +107,29 @@ op.get_item(uuid="example", fields="username")
op.get_item(uuid="example", fields=["username", "password"])

```
##
### Service Accounts
We also support authentication using Service accounts, however these are not interchangeable with other auth routes and
hence other accounts i.e. this token based authentication will take precedence over any other method.
If you wish to use multiple account types, for now you will need to design this workflow yourself
by clearing out the OP_SERVICE_ACCOUNT_TOKEN using `unset OP_SERVICE_ACCOUNT_TOKEN` before re-authenticating with
your preferred account.

To use a service account make sure to fulfil the requirements here:
https://developer.1password.com/docs/service-accounts/use-with-1password-cli
and note that not all of the CLI commands are supported at this time.

Also note that your service account will only have access to certain vaults. In particular it will not be able to see
the `Shared` or `Private` vaults in any account. In our client this means you must always use the `vault` option.

Once you have fulfilled all the requirements, namely `export OP_SERVICE_ACCOUNT_TOKEN=<your token>`, you can then use
our client with:

```python
from onepassword import OnePassword

op = OnePassword()
op.list_vaults()
```

### Input formats
To be sure what you are using is of the right format
Expand Down
37 changes: 29 additions & 8 deletions onepassword/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
_spawn_signin
from onepassword.exceptions import OnePasswordForgottenPassword

SERVICE_ACCOUNT_TOKEN = "OP_SERVICE_ACCOUNT_TOKEN"


class SignIn:
"""
Expand All @@ -32,7 +34,8 @@ def get_account(self, bash_profile: BashProfile | None = None) -> str:

@staticmethod
def _input_account() -> str:
account = input("Please input your 1Password account name e.g. wandera from wandera.1password.com: ")
account = input("Please input your 1Password personal or business acount name e.g. company from "
"company.1password.com: ")
return account

def _get_account_bash(self, bash_profile: BashProfile) -> str:
Expand Down Expand Up @@ -250,6 +253,22 @@ def signin(self, account: str | None = None) -> None:
self._update_bash_account(account, bash_profile)


class ServiceSignIn(SignIn):
def __init__(self):
self.signin()

def signin(self):
if os.environ['OP_SERVICE_ACCOUNT_TOKEN'] != "":
print("Using service account, for supported commands see: "
"https://developer.1password.com/docs/service-accounts/use-with-1password-cli#supported-commands")
self.account_details = yaml.safe_load(read_bash_return("op user get --me", single=False))
self.account = self.account_details["Name"]
else:
print("No service account found, please setup on the web version of 1Password for more information go here:"
" https://developer.1password.com/docs/service-accounts/use-with-1password-cli")



class OnePassword:
"""
Class for integrating with a OnePassword password manager
Expand All @@ -260,14 +279,16 @@ class OnePassword:
"""
def __init__(self, signin_method: str = "app", account: str | None = None, password: str | None = None) -> None:
# pragma: no cover

if signin_method == "app":
self.signin_strategy = AppSignIn(account)
elif signin_method == "manual":
self.signin_strategy = ManualSignIn(account, password)
if SERVICE_ACCOUNT_TOKEN in os.environ.keys():
self.signin_strategy = ServiceSignIn()
else:
raise ValueError("Unrecognised 'signin_method', options are: 'app' or 'manual'. "
"See: https://developer.1password.com/docs/cli/verify")
if signin_method == "app":
self.signin_strategy = AppSignIn(account)
elif signin_method == "manual":
self.signin_strategy = ManualSignIn(account, password)
else:
raise ValueError("Unrecognised 'signin_method', options are: 'app' or 'manual'. "
"See: https://developer.1password.com/docs/cli/verify")

def get_uuid(self, docname: str, vault: str = "Private") -> str: # pragma: no cover
"""
Expand Down

0 comments on commit d8b00bb

Please sign in to comment.