archdaemon技術筆記
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # keyring usage [toc] ## 簡介keyring函式庫 The Python keyring library provides an easy way to access the system keyring service from python. It can be used in any application that needs safe password storage. These recommended keyring backends are supported: ## 設定keyring backend :::success PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring" poetry self add poetry-dynamic-versioning-plugin PYTHON_KEYRING_BACKEND="keyring.backends.null.Keyring" poetry self add poetry-dynamic-versioning-plugin ::: ## 安裝keyring On Linux, the KWallet backend relies on **dbus-python**, which does not always install correctly when using pip (compilation is needed). For best results, install dbus-python as a system package. ## 使用 Keyring get/set keyring.set_password and keyring.get_password: :::success import keyring keyring.set_password("system", "username", "password") keyring.get_password("system", "username") 'password' ::: ## Command-line Utility Keyring supplies a keyring command which is installed with the package. After installing keyring in most environments, the command should be available for setting, getting, and deleting passwords. For more usage information, invoke with no arguments or with --help as so: :::info $ keyring --help $ keyring set system username Password for 'username' in 'system': $ keyring get system username password ::: The command-line functionality is also exposed as an executable package, suitable for invoking from Python like so: $ python -m keyring --help $ python -m keyring set system username Password for 'username' in 'system': $ python -m keyring get system username password If installed via a package manager (apt, pacman, nix, homebrew, etc), these shell completions may already have been distributed with the package (no action required). Keyring provides tab completion if the completion extra is installed: $ pip install 'keyring[completion]' Then, generate shell completions, something like: ### Configuring The python keyring lib contains implementations for several backends. The library will attempt to automatically choose the most suitable backend for the current environment. Users may also specify the preferred keyring in a config file or by calling the set_keyring() function. #### Config file path The configuration is stored in a file named “keyringrc.cfg” found in a platform-specific location. To determine where the config file is stored, run the following: :::success python -c "import keyring.util.platform_; print(keyring.util.platform_.config_root())" Some keyrings also store the keyring data in the file system. To determine where the data files are stored, run: python -c "import keyring.util.platform_; print(keyring.util.platform_.data_root())" Config file content To specify a keyring backend, set the default-keyring option to the full path of the class for that backend, such as keyring.backends.OS_X.Keyring. ::: If keyring-path is indicated, keyring will add that path to the Python module search path before loading the backend. For example, this config might be used to load the SimpleKeyring from the simplekeyring module in the ./demo directory (not implemented): [backend] default-keyring=simplekeyring.SimpleKeyring keyring-path=demo Third-Party Backends In addition to the backends provided by the core keyring package for the most common and secure use cases, there are additional keyring backend implementations available for other use cases. Simply install them to make them available: keyrings.cryptfile - Encrypted text file storage. keyring_jeepney - a pure Python backend using the secret service DBus API for desktop Linux. keyrings.alt - “alternate”, possibly-insecure backends, originally part of the core package, but available for opt-in. gsheet-keyring - a backend that stores secrets in a Google Sheet. For use with ipython-secrets. bitwarden-keyring - a backend that stores secrets in the BitWarden password manager. sagecipher - an encryption backend which uses the ssh agent protocol’s signature operation to derive the cipher key. keyrings.osx_keychain_keys - OSX keychain key-management, for private, public, and symmetric keys. Write your own keyring backend The interface for the backend is defined by keyring.backend.KeyringBackend. Every backend should derive from that base class and define a priority attribute and three functions: get_password(), set_password(), and delete_password(). The get_credential() function may be defined if desired. See the backend module for more detail on the interface of this class. Keyring employs entry points to allow any third-party package to implement backends without any modification to the keyring itself. Those interested in creating new backends are encouraged to create new, third-party packages in the keyrings namespace, in a manner modeled by the keyrings.alt package. See the setup.cfg file in that project for hints on how to create the requisite entry points. Backends that prove essential may be considered for inclusion in the core library, although the ease of installing these third-party packages should mean that extensions may be readily available. To create an extension for Keyring, please submit a pull request to have your extension mentioned as an available extension. Runtime Configuration Keyring additionally allows programmatic configuration of the backend calling the api set_keyring(). The indicated backend will subsequently be used to store and retrieve passwords. To invoke set_keyring: # define a new keyring class which extends the KeyringBackend import keyring.backend class TestKeyring(keyring.backend.KeyringBackend): """A test keyring which always outputs the same password """ priority = 1 def set_password(self, servicename, username, password): pass def get_password(self, servicename, username): return "password from TestKeyring" def delete_password(self, servicename, username): pass # set the keyring for keyring lib keyring.set_keyring(TestKeyring()) # invoke the keyring lib try: keyring.set_password("demo-service", "tarek", "passexample") print("password stored successfully") except keyring.errors.PasswordSetError: print("failed to store password") print("password", keyring.get_password("demo-service", "tarek")) Disabling Keyring In many cases, uninstalling keyring will never be necessary. Especially on Windows and macOS, the behavior of keyring is usually degenerate, meaning it will return empty values to the caller, allowing the caller to fall back to some other behavior. In some cases, the default behavior of keyring is undesirable and it would be preferable to disable the keyring behavior altogether. There are several mechanisms to disable keyring: Uninstall keyring. Most applications are tolerant to keyring not being installed. Uninstalling keyring should cause those applications to fall back to the behavior without keyring. This approach affects the Python environment where keyring would otherwise have been installed. Configure the Null keyring in the environment. Set PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring in the environment, and the Null (degenerate) backend will be used. This approach affects all uses of Keyring where that variable is set. Permanently configure the Null keyring for the user by running keyring --disable or python -m keyring --disable. This approach affects all uses of keyring for that user. Altering Keyring Behavior Keyring provides a mechanism to alter the keyring’s behavior through environment variables. Each backend implements a KeyringBackend.set_properties_from_env, which when invoked will find all environment variables beginning with KEYRING_PROPERTY_{NAME} and will set a property for each {NAME.lower()} on the keyring. This method is invoked during initialization for the default/configured keyring. This mechanism may be used to set some useful values on various keyrings, including: keychain; macOS, path to an alternate keychain file appid; Linux/SecretService, alternate ID for the application Using Keyring on Ubuntu 16.04 The following is a complete transcript for installing keyring in a virtual environment on Ubuntu 16.04. No config file was used: $ sudo apt install python3-venv libdbus-glib-1-dev $ cd /tmp $ pyvenv py3 $ source py3/bin/activate $ pip install -U pip $ pip install secretstorage dbus-python $ pip install keyring $ python >>> import keyring >>> keyring.get_keyring() <keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8> >>> keyring.set_password("system", "username", "password") >>> keyring.get_password("system", "username") 'password' Using Keyring on headless Linux systems It is possible to use the SecretService backend on Linux systems without X11 server available (only D-Bus is required). In this case: Install the GNOME Keyring daemon. Start a D-Bus session, e.g. run dbus-run-session -- sh and run the following commands inside that shell. Run gnome-keyring-daemon with --unlock option. The description of that option says: Read a password from stdin, and use it to unlock the login keyring or create it if the login keyring does not exist. When that command is started, enter a password into stdin and press Ctrl+D (end of data). After that, the daemon will fork into the background (use --foreground option to block). Now you can use the SecretService backend of Keyring. Remember to run your application in the same D-Bus session as the daemon. Using Keyring on headless Linux systems in a Docker container It is possible to use keyring with the SecretService backend in Docker containers as well. All you need to do is install the necessary dependencies and add the –privileged flag to avoid any Operation not permitted errors when attempting to unlock the system’s keyring. The following is a complete transcript for installing keyring on a Ubuntu 18:04 container: docker run -it -d --privileged ubuntu:18.04 $ apt-get update $ apt install -y gnome-keyring python3-venv python3-dev $ python3 -m venv venv $ source venv/bin/activate # source a virtual environment to avoid polluting your system $ pip3 install --upgrade pip $ pip3 install keyring $ dbus-run-session -- sh # this will drop you into a new D-bus shell $ echo 'somecredstorepass' | gnome-keyring-daemon --unlock # unlock the system's keyring $ python >>> import keyring >>> keyring.get_keyring() <keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8> >>> keyring.set_password("system", "username", "password") >>> keyring.get_password("system", "username") 'password' Integration API The keyring lib has a few functions: get_keyring(): Return the currently-loaded keyring implementation. get_password(service, username): Returns the password stored in the active keyring. If the password does not exist, it will return None. get_credential(service, username): Return a credential object stored in the active keyring. This object contains at least username and password attributes for the specified service, where the returned username may be different from the argument. set_password(service, username, password): Store the password in the keyring. delete_password(service, username): Delete the password stored in keyring. If the password does not exist, it will raise an exception. In all cases, the parameters (service, username, password) should be Unicode text. Exceptions The keyring lib raises the following exceptions: keyring.errors.KeyringError: Base Error class for all exceptions in keyring lib. keyring.errors.InitError: Raised when the keyring cannot be initialized. keyring.errors.PasswordSetError: Raised when the password cannot be set in the keyring. keyring.errors.PasswordDeleteError: Raised when the password cannot be deleted in the keyring. Get Involved Python keyring lib is an open community project and eagerly welcomes contributors. Repository: https://github.com/jaraco/keyring/ Bug Tracker: https://github.com/jaraco/keyring/issues/ Mailing list: http://groups.google.com/group/python-keyring For Enterprise Available as part of the Tidelift Subscription. This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. Learn more. Security Contact To report a security vulnerability, please use the Tidelift security contact. Tidelift will coordinate the fix and disclosure. Security Considerations Each built-in backend may have security considerations to understand before using this library. Authors of tools or libraries utilizing keyring are encouraged to consider these concerns. As with any list of known security concerns, this list is not exhaustive. Additional issues can be added as needed. macOS Keychain Any Python script or application can access secrets created by keyring from that same Python executable without the operating system prompting the user for a password. To cause any specific secret to prompt for a password every time it is accessed, locate the credential using the Keychain Access application, and in the Access Control settings, remove Python from the list of allowed applications. Freedesktop Secret Service No analysis has been performed KDE4 & KDE5 KWallet No analysis has been performed Windows Credential Locker No analysis has been performed Making Releases This project makes use of automated releases and continuous integration. The simple workflow is to tag a commit and push it to Github. If it passes tests in CI, it will be automatically deployed to PyPI. Other things to consider when making a release: Check that the changelog is current for the intended release. Running Tests Tests are continuously run in Github Actions. To run the tests locally, install and invoke tox. Background The project was based on Tarek Ziade’s idea in this post. Kang Zhang initially carried it out as a Google Summer of Code project, and Tarek mentored Kang on this project. History For Enterprise Tidelift Professional support for keyring is available as part of the Tidelift Subscription. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. LEARN MORE REQUEST A DEMO keyring.delete_password(service_name: str, username: str) → None Delete the password for the user in the specified service. keyring.get_credential(service_name: str, username: str | None) → Credential | None Get a Credential for the specified service. keyring.get_keyring() → KeyringBackend Get current keyring backend. keyring.get_password(service_name: str, username: str) → str | None Get password from the specified service. keyring.set_keyring(keyring) Set current keyring backend. keyring.set_password(service_name: str, username: str, password: str) → None Set password for the user in the specified service. Keyring implementation support class keyring.backend.Crypter Bases: object Base class providing encryption and decryption abstract decrypt(value) Decrypt the value. abstract encrypt(value) Encrypt the value. class keyring.backend.KeyringBackend Bases: object The abstract base class of the keyring, every backend must implement this interface. delete_password(service: str, username: str) → None Delete the password for the username of the service. If the backend cannot delete passwords, raise PasswordDeleteError. get_credential(service: str, username: str | None) → Credential | None Gets the username and password for the service. Returns a Credential instance. The username argument is optional and may be omitted by the caller or ignored by the backend. Callers must use the returned username. abstract get_password(service: str, username: str) → str | None Get password of the username for the service classmethod get_viable_backends() Return all subclasses deemed viable. name = 'backend KeyringBackend' priority() Each backend class must supply a priority, a number (float or integer) indicating the priority of the backend relative to all other backends. The priority need not be static – it may (and should) vary based attributes of the environment in which is runs (platform, available packages, etc.). A higher number indicates a higher priority. The priority should raise a RuntimeError with a message indicating the underlying cause if the backend is not suitable for the current environment. As a rule of thumb, a priority between zero but less than one is suitable, but a priority of one or greater is recommended. abstract set_password(service: str, username: str, password: str) → None Set password for the username of the service. If the backend cannot store passwords, raise PasswordSetError. set_properties_from_env() For all KEYRING_PROPERTY_* env var, set that property. viable = True with_properties(**kwargs) class keyring.backend.KeyringBackendMeta(name, bases, namespace, /, **kwargs) Bases: ABCMeta A metaclass that’s both an ABCMeta and a type that keeps a registry of all (non-abstract) types. class keyring.backend.NullCrypter Bases: Crypter A crypter that does nothing decrypt(value) Decrypt the value. encrypt(value) Encrypt the value. class keyring.backend.SchemeSelectable Bases: object Allow a backend to select different “schemes” for the username and service. backend = SchemeSelectable() backend._query('contoso', 'alice') {'username': 'alice', 'service': 'contoso'} backend._query('contoso') {'service': 'contoso'} backend.scheme = 'KeePassXC' backend._query('contoso', 'alice') {'UserName': 'alice', 'Title': 'contoso'} backend._query('contoso', 'alice', foo='bar') {'UserName': 'alice', 'Title': 'contoso', 'foo': 'bar'} scheme = 'default' schemes = {'KeePassXC': {'service': 'Title', 'username': 'UserName'}, 'default': {'service': 'service', 'username': 'username'}} keyring.backend.get_all_keyring() Return a list of all implemented keyrings that can be constructed without parameters. Core API functions and initialization routines. keyring.core.delete_password(service_name: str, username: str) → None Delete the password for the user in the specified service. keyring.core.disable() Configure the null keyring as the default. keyring.core.get_credential(service_name: str, username: str | None) → Credential | None Get a Credential for the specified service. keyring.core.get_keyring() → KeyringBackend Get current keyring backend. keyring.core.get_password(service_name: str, username: str) → str | None Get password from the specified service. keyring.core.init_backend(limit=None) Load a detected backend. keyring.core.load_config() Load a keyring using the config file in the config root. keyring.core.load_env() Load a keyring configured in the environment variable. keyring.core.load_keyring(keyring_name) Load the specified keyring by name (a fully-qualified name to the keyring, such as ‘keyring.backends.file.PlaintextKeyring’) keyring.core.recommended(backend) keyring.core.set_keyring(keyring) Set current keyring backend. keyring.core.set_password(service_name: str, username: str, password: str) → None Set password for the user in the specified service. class keyring.credentials.Credential Bases: object Abstract class to manage credentials abstract property password abstract property username class keyring.credentials.EnvironCredential(user_env_var, pwd_env_var) Bases: Credential Source credentials from environment variables. Actual sourcing is deferred until requested. Supports comparison by equality. e1 = EnvironCredential('a', 'b') e2 = EnvironCredential('a', 'b') e3 = EnvironCredential('a', 'c') e1 == e2 True e2 == e3 False property password property username class keyring.credentials.SimpleCredential(username, password) Bases: Credential Simple credentials implementation property password property username

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully