{"id":28194266,"url":"https://github.com/monkey-projects/oci-vault","last_synced_at":"2026-02-17T20:34:59.931Z","repository":{"id":266285814,"uuid":"822592645","full_name":"monkey-projects/oci-vault","owner":"monkey-projects","description":"Access the OCI vault api using Clojure","archived":false,"fork":false,"pushed_at":"2025-01-22T15:03:50.000Z","size":65,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-28T23:16:30.684Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monkey-projects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-01T12:45:23.000Z","updated_at":"2025-04-07T13:28:33.000Z","dependencies_parsed_at":"2024-12-03T14:32:28.739Z","dependency_job_id":"f85fa880-7a77-46f2-9a5f-07f9b1bb0ba2","html_url":"https://github.com/monkey-projects/oci-vault","commit_stats":null,"previous_names":["monkey-projects/oci-vault"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/monkey-projects/oci-vault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Foci-vault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Foci-vault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Foci-vault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Foci-vault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monkey-projects","download_url":"https://codeload.github.com/monkey-projects/oci-vault/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Foci-vault/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29557384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T20:14:27.083Z","status":"ssl_error","status_checked_at":"2026-02-17T20:14:26.018Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-16T13:11:46.650Z","updated_at":"2026-02-17T20:34:54.916Z","avatar_url":"https://github.com/monkey-projects.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OCI Vault API\n\nThis is a Clojure lib to natively access the [OCI Vault\nAPI](https://docs.oracle.com/en-us/iaas/Content/KeyManagement/home.htm).\n\n## Why?\n\nYou could of course use the Oracle-provided Java libs, but I find it cumbersome\nto convert to and from Java POJO's all the time.  Also, they pull in lots of\ntransitive dependencies which I want to avoid.  This library is more Clojure-esque\nand uses [HttpKit](https://github.com/http-kit/http-kit) instead for a lower\nfootprint.\n\n## Usage\n\nFirst include the lib in your project:\n```clojure\n;; Leiningen\n:dependencies [[com.monkeyprojects/oci-vault \"\u003cversion\u003e\"]]\n```\nOr with `deps.edn`:\n```clojure\n{:deps\n {com.monkeyprojects/oci-vault {:mvn/version \"\u003cversion\u003e\"}}}\n```\n\nThe functionality can be found in `monkey.oci.vault` ns.  First create a client,\nusing your OCI configuration, then you can start invoking endpoints.\n```clojure\n(require '[monkey.oci.vault :as v])\n\n(def config\n  {:tenancy-ocid \"your-tenancy-ocid\"\n   :user-ocid \"your-user-ocid\"\n   :private-key \u003cprivate-key\u003e\n   :key-fingerprint \"key-fingerprint\"\n   :region \"oci-region\"})\n\n;; Create a client\n(def client (v/make-client config))\n(def cid \"\u003ccompartment-ocid\u003e\")\n\n;; The client can be used to do general calls\n(def vault (v/get-vault client {:vault-id \"vault-ocid\" :compartment-id cid}))\n(def vault-keys (v/list-keys client {:vault-id (:id vault) :compartment-id cid}))\n\n;; Encryption\n(def key-id (-\u003e vault-keys first :id))\n\n;; Note that the text must be base64-encoded\n(require '[monkey.oci.vault.b64 :as b])\n(def enc (v/encrypt client {:key-id key-id :plaintext (b/-\u003eb64 \"secret message\")}))\n;; =\u003e {:ciphertext \"\u003cbase64-encoded cipher\u003e\" ...}\n\n;; Decrypt it back\n(def msg (-\u003e (v/decrypt client {:key-id key-id :ciphertext (:ciphertext enc)})\n             :plaintext\n\t     (b/b64-\u003estr)))  ; Make sure to decode back from base64\n;; =\u003e \"secret message\"\n```\n\nThe lib actually uses [Martian](https://github.com/oliyh/martian) to do the\nHTTP calls.  This means all functions take an options map which is actually the\narguments expected by the Martian call. This can be a combination of path params,\nquery args and a request body.  Check the [Oracle API docs](https://docs.oracle.com/en-us/iaas/api/]\nfor more on which request requires which parameters.\n\nThe high-level calls declared in the `vault` ns hide the complexities of working\nwith the Martian responses.  Instead, they automatically check if the response is\nsuccessful, and if so, they unwrap the body of the response.  Otherwise an exception\nis thrown.  If you need more control over how the requests are handled, check the\nlow-level calls below.  Pagination is also handled by the wrapper functions for\n`list-` calls.\n\n## Available calls\n\nCurrently, these calls are exposed by the vault library:\n\n - `get-vault`\n - `list-vaults`\n - `list-keys`\n - `encrypt`\n - `decrypt`\n - `generate-data-encryption-key`\n - `list-secrets`\n - `create-secret`\n - `update-secret`\n - `get-secret`\n - `get-secret-bundle`\n - `get-secret-bundle-by-name`\n\nMore will be added as needed, or you can add some yourself.  PR's are welcome!\n\n## Low-level calls\n\nIf you need more control over how the calls are processed, including using\nthem in an async fashion, you can invoke the lower-level calls directly.  These\nreside in several namespaces, depending on which kind of category you need.\n\nThe raw response of each call is returned, as a `future`.  This is intended\nto allow the maximum flexibility when using the lib.  You can inspect the http\nstatus code yourself.  The body is automatically parsed from `JSON`, depending\non the `Content-Type` header.\n\nNote also that pagination is not handled by these low-level calls, so you will\nhave to do that yourselves.\n\n### Encryption/Decryption\n\nIn order to do vault specific calls, you need to use the crypto endpoint of the\nvault itself.  The same goes for key-specific calls, where you need the management\nendpoint.  For this you have to create a special client, using either the vault id,\nor the endpoint itself.  If the vault id is specified, the vault details will be\nfetched first in order to obtain the actual http endpoint.\n\n```clojure\n(require '[monkey.oci.vault.crypto :as vc])\n(require '[monkey.oci.vault.b64 :as b])\n\n;; This will look up the endpoint\n(def crypto-client (vc/make-crypto-client (assoc config :vault-id \"vault-ocid\")))\n;; Alternatively you can add the endpoint directly\n(def crypto-client (vc/make-crypto-client (assoc config :crypto-endpoint \"http://crypto\")))\n\n;; Encryption expects a base64 string.  There are utility functions for this.\n(def enc (-\u003e (vc/encrypt crypto-client {:key-id \"key-ocid\"\n                                        :key-version-id \"version-ocid\"\n\t\t  \t\t        :plaintext (b/-\u003eb64 \"very secret text to encrypt\")})\n\t     deref\n\t     :body\n\t     :ciphertext))\n\n;; Decryption returns base64 encoded plain text\n(def dec (-\u003e (vc/decrypt crypto-client {:key-id \"key-ocid\"\n                                        :key-version-id \"version-ocid\"\n\t\t\t\t        :ciphertext enc})\n\t     deref\n\t     :body\n\t     :plaintext\n\t     u/b64-\u003e\n\t     (String.)))\n```\n\nIn a similar fashion you can create a management client using `make-mgmt-client`.\nYou can specify a `:key-id` or `:mgmt-endpoint`.  See the `monkey.oci.vault.mgmt`\nnamespace for this.\n\nYou can also generate a data encryption key.  The [Oracle documentation](https://docs.oracle.com/en-us/iaas/Content/KeyManagement/Tasks/usingkeys_topic-To_generate_a_data_encryption_key_from_your_Vault_master_encryption_key.htm)\nis a bit sparse about this, but it returns an AES key that can be used to do encryption/decryption\nwithout having to go to the Vault API for every call.  For instance, using\n[buddy.core](https://funcool.github.io/buddy-core/latest/index.html):\n\n```clojure\n;; Generate key\n(def key (-\u003e (vc/generate-data-encryption-key client\n                                              {:key-details\n\t\t\t\t\t       {:key-id \"key-ocid\"\n\t\t\t\t\t        :include-plaintext-key true\n\t\t\t\t\t        :key-shape\n\t\t\t\t\t        {:algorithm \"AES\"\n\t\t\t\t\t         :length 32}}}) ; Must be 16, 24 or 32\n\t     (deref)\n\t     :body\n\t     :plaintext))\n\n(require '[buddy.core.codecs :as codecs])\n(require '[buddy.core.crypto :as bcc])\n(require '[buddy.core.nonce :as bcn])\n\n;; Generate initialization vector, must be 16 bytes long\n(def iv (bcn/random-nonce 16))\n;; Convert key to bytes\n(def key-bytes (codecs/b64-\u003ebytes key))\n;; Do some encryption\n(def enc (bcc/encrypt (codecs/str-\u003ebytes \"my secret message\")\n                      key-bytes\n\t\t      iv\n\t\t      {:algo :aes-256-gcm})) ; Algo depends on your AES key size\n```\n\n### Secrets\n\nYou can also create, update or retrieve secrets stored in the vault.  To this end, you first\nneed to create the appropriate client.  Then you can invoke the appropriate functions: `create-secret`,\n`update-secret` and `get-secret`.\n\n```clojure\n(require '[monkey.oci.vault.secrets :as vs])\n\n(def client (vs/make-secret-client config))\n\n;; Create new secret\n(def s (-\u003e (vs/create-secret client\n                             {:secret\n\t\t\t      {:compartment-id \"compartment-ocid\"\n                               :vault-id \"vault-ocid\"\n\t\t\t       :key-id \"key-ocid\"\n\t\t\t       :secret-name \"my-test-secret\"\n\t\t\t       :secret-content\n\t\t\t       {:content-type \"BASE64\"\n\t\t\t        :content \"\u003csome base64 string\u003e\"}}})\n\t   (deref)\n\t   :body)\n\n;; Update it\n@(vs/update-secret client {:secret-id (:id s)\n                           :secret {:description \"updated description\"}})\n\n;; Retrieve it\n(-\u003e (vs/get-secret client {:secret-id (:id s)})\n    (deref)\n    :body)\n```\n\nNote that `get-secret` **does not return the secret contents**!  For this you need to\ncreate *another* client (why, Oracle?) using `make-secret-retrieval-client`.  Then you\ncan use `get-secret-bundle` or `get-secret-bundle-by-name` to fetch the contents.\n\n```clojure\n(require '[monkey.oci.vault.secrets :as vs])\n\n(def client (vs/make-secret-retrieval-client config))\n\n(-\u003e (vs/get-secret-bundle client\n                          {:secret-id \"secret-ocid\"\n\t\t\t   :stage \"CURRENT\"})\n    (deref)\n    :body)\n```\n\n## Todo\n\n - Add more endpoints.\n - Add more documentation, especially on the required parameters for each call.\n - Integration tests\n\n## License\n\nCopyright (c) 2024 by [Monkey Projects BV](https://www.monkey-projects.be)\n\n[MIT License](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Foci-vault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonkey-projects%2Foci-vault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Foci-vault/lists"}