1password / connect-sdk-go Goto Github PK
View Code? Open in Web Editor NEWGo SDK for 1Password Connect
Home Page: https://developer.1password.com/docs/connect
License: MIT License
Go SDK for 1Password Connect
Home Page: https://developer.1password.com/docs/connect
License: MIT License
Currently, when making a password recipe, you need to specify the character sets that can be used when generating the password (e.g. SYMBOLS
, LETTERS
, DIGITS
). However, it can be tricky to know by heart the supported character sets.
Also, it would be nice to have a sort of validation of the recipe before sending the request to Connect. As a starting inspiration, you can check the validRecipe
function from Node SDK.
onepassword/items/go
. Please ensure that all constants are set by checking out this part of the Connect API documentationtype CharacterSets string
const (
Letters CharacterSets = "LETTERS"
Symbols CharacterSets = "SYMBOLS"
Digits CharacterSets = "DIGITS"
)
CharacterSets
property of the GeneratorRecipe
struct to use the new type. (line 132)
// GeneratorRecipe Representation of a "recipe" used to generate a field
type GeneratorRecipe struct {
Length int `json:"length,omitempty"`
CharacterSets []CharacterSets `json:"characterSets,omitempty"`
ExcludeCharacters string `json:"excludeCharacters,omitempty"`
}
Accounts on 1password.com recently gained the ability to create items with a category of API Credential. This SDK should include that as a supported Item Category.
This was a mistake, please ignore.
SDK Version: 1.2.0
Connect Server Version: 1.5.0
OS: MacOS
Go Version: 1.17.2
File.content
is not exported, so when calling Client.CreateItem(item)
on an item with File
s, the file's contents are left out by json.Marshal(item)
.
Here's how how I'm calling CreateItem
// TODO generate random IDs?
vaultID := "fdsasdkfjsdkfjhsd" // retrieved first
itemName := "my-item"
itemID := fmt.Sprintf("%s-id", itemName)
fileName := "my-file.txt"
fileID := fmt.Sprintf("%s-id", fileName)
contents, err := os.ReadFile(fileName)
if err != nil {
return err
}
contentPath := fmt.Sprintf("v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID)
file := &onepassword.File{
ID: fileID,
Name: fileName,
Size: len(contents),
ContentPath: contentPath,
}
file.SetContent(contents)
item := &onepassword.Item{
ID: itemID,
Title: itemName,
Vault: onepassword.ItemVault{ID: vaultID},
Category: onepassword.Document,
Files: []*onepassword.File{file},
}
_, err = client.CreateItem(item, vaultID)
if err != nil {
return err
}
SDK Version:
https://github.com/1Password/connect-sdk-go/tree/v1.0.1
Connect Server Version:
Any
OS:
Any
Go Version:
Any
When I click on the "copy" button next to the code at https://github.com/1Password/connect-sdk-go/tree/v1.0.1#installation and paste it into my terminal the next error occurs:
zsh: command not found: $
Package should be downloaded without issues.
Open https://github.com/1Password/connect-sdk-go/tree/v1.0.1#installation and click on "copy code" button next to the code example.
The $
sign should be removed from the code example to fix the issue.
Currently when making an Item, you need to specify a type for each field you create. (e.g. STRING
, CONCEALED
, OTP
, EMAIL
). However, it can be a bit tricky to know by heart what the right purpose is for each field.
Therefore, we want to add the constants for supported field purposes, according to the API spec.
onepassword/items.go
type ItemFieldType string
const (
FieldTypeAddress ItemFieldType = "ADDRESS"
FieldTypeConcealed ItemFieldType = "CONCEALED"
FieldTypeCreditCardNumber ItemFieldType = "CREDIT_CARD_NUMBER"
FieldTypeCreditCardType ItemFieldType = "CREDIT_CARD_TYPE"
FieldTypeDate ItemFieldType = "DATE"
FieldTypeEmail ItemFieldType = "EMAIL"
FieldTypeGender ItemFieldType = "GENDER"
FieldTypeMenu ItemFieldType = "MENU"
FieldTypeMonthYear ItemFieldType = "MONTH_YEAR"
FieldTypeOTP ItemFieldType = "OTP"
FieldTypePhone ItemFieldType = "PHONE"
FieldTypeReference ItemFieldType = "REFERENCE"
FieldTypeString ItemFieldType = "STRING"
FieldTypeURL ItemFieldType = "URL"
FieldTypeFile ItemFieldType = "FILE"
FieldTypeSSHKey ItemFieldType = "SSH_KEY"
FieldTypeUnknown ItemFieldType = "UNKNOWN"
)
Purpose
property of the ItemFiled
struct to have the new type. (line 108)
// ItemField Representation of a single field on an Item
type ItemField struct {
ID string `json:"id"`
Section *ItemSection `json:"section,omitempty"`
Type ItemFieldType `json:"type"`
Purpose string `json:"purpose,omitempty"`
Label string `json:"label,omitempty"`
Value string `json:"value,omitempty"`
Generate bool `json:"generate,omitempty"`
Recipe *GeneratorRecipe `json:"recipe,omitempty"`
Entropy float64 `json:"entropy,omitempty"`
TOTP string `json:"totp,omitempty"`
}
Among other reasons, a lack of a license prevents API documentation from being automatically published.
Add support for Service Account
Access to some vault using the new Service Account instead deploy connect server
Instead of always defaulting to http.DefaultClient
, allowing passing one during NewClient configuration
This would allow one to specify a custom roundtripper without mutating the http.DefaultClient
global variable, this could be useful for adding certificates for custom endpoints that use self-signed certificates or are missing intermediaries.
Simply allow passing an http client in the New*
constructors
Mutate the global http.DefaultClient
which is bad practice and has unintended side-effects for shared code
Nope
SDK Version: v1.2.0
Connect Server Version: 1.3.1
OS: Mac OS
Go Version: go1.17.2 darwin/amd64
If you use GetItemByTitle
, you get a pointer to an Item
which you can then run item.GetValue(field)
against. However if you use GetItemsByTitle
(plural) and loop over the results and run item.GetValue(field)
, you'll get empty results, because you haven't called client.GetItem(items[0].ID, items[0].Vault.ID)
. This makes it appear like the values don't exist when they actually do.
I expected to be able to loop over the results of GetItemsByTitle
and run item.GetValue(field)
. - Or some documentation to direct me to first run GetItem
on the results of GetItemsByTitle
.
Described in What Happened.
Happy to add any clarity I missed.
Hello,
I'm in the process of integrating 1Password for secret automation in go using this SDK and saw that what I consider one of the best features described in the documentation "LoadStruct" is not yet available through a release. For now I'm referencing this package by a commit hash, but it would be nice if you could create a new release of the sdk.
PS. Keep up the good work, really cool package.
Thanks in advance,
Daniel Fernandes
SDK Version: v1.2.0
Connect Server Version: 1.5.0
OS: Ubuntu 20.04.2 LTS
Go Version: go1.17.2 linux/amd64
I was trying to download all the documents of a particular vault using the sdk, I noticed that a few files were not downloaded and when I checked the docker logs for the connect API service I saw the error
log_message":"(W) Server: (failed to GetFileWithUUID), attempting to decrypt message with KID using KID , client used wrong Key","timestamp":"2022-02-21T07:23:18.570941261Z
I'm using the method client.GetFileContent() to get the file content
I also saw a old post for the cli : https://1password.community/discussion/87002/op-get-document-fails-with-a-500-error , I think it might be the same issue, I re-uploaded the file and the issue was solved but Is there a way I can gracefully handle this in code without the need to re-upload the file?
To get the file content without any issue
this only happens for a few files
A function for loading a Go struct from a tag, where only the opfield
tag has to be set.
Loading multiple similar configurations from different items while using the struct tags:
type Config struct {
Database string `opitem: item_id, opfield:".database"`
Username string `opitem: item_id, opfield:".username"`
Password string `opitem: item_id, opfield:".password"`
}
func main(){
// setup client
var config1 Config // should be loaded from item 1
var config2 Config // should be loaded from item 2
}
There is currently no way to dynamically set the opitem
in this case.
type Config struct {
Database string `opfield:".database"`
Username string `opfield:".username"`
Password string `opfield:".password"`
}
func main(){
// setup client
connect.LoadFromItem(client, &config1, "vault uuid", "item 1 uuid")
connect.LoadFromItem(client, &config2, "vault uuid", "item 2 uuid")
}
Some considerations here:
opvault
and/or opitem
struct tags override the value provided to LoadFromItem
?LoadFromItem
?Load()
)Without struct tags, it's possible to a struct from multiple items. By fetching the item with, for example, client.GetItemByTitle()
and setting the fields manually:
item, err := client.GetItemByTitle(itemName, vaultUUID)
if err != nil {
return nil, err
}
config := Config{
Database: item.Fields["database"].Value,
Username: item.Fields["username"].Value,
Password: item.Fields["password"].Value,
}
A token with additional newlines is not considered valid and results in a rather unhelpful error message: Failed to retrieve item: Get "http://onepassword-connect:8080/v1/vaults?filter=title+eq+%22engineering%22": net/http: invalid header field value for "Authorization".
Trimming newlines would resolve the problem.
This is not a bug, because headers shouldn't contain newlines, but trimming the token string would result in a better developer-experience. It's rather easy to create such an invalid token with kubectl create secret generic op-token --from-file=token=token.txt
because a lot of text editors are configured to add a trailing newline.
Can save a few hours of debugging for anyone that doesn't follow the getting started guide exactly. In my case I integrated it into an existing Kustomize setup. Kustomize emphasises a declarative approach and loading the secret from a file is therefore not a strange approach.
Please trim the token. I'd open up a PR but I'm not familiar with Go and its toolchain
Yes, remove newlines with some bash-fu
cat token.txt | tr -d "\n" > trimmed_token.txt
n/a
jaeger-client-go is depricated. The latest version is v.2.30.0
which was released in December 2021.
It might cause issues while using sdk.
Consider replacing it with a newer alternative OpenTelemetry or others. See this doc
onepassword/vaults.go
Vaults
typeContentVersoin
; this should say say ContentVersion
Hi Team, hopefully this is right place to ask, if not, I'd appreciate if you can direct me.
I'm the founder of cloudquery.io, a high performance open source ELT framework.
Our users are interested in a 1Password plugin, but as we cannot maintain all the plugins ourselves, I was curious if this would be an interesting collaboration, where we would help implement an initial source plugin, and you will help maintain it.
This will give your users the ability to sync 1Password APIs to any of their datalakes/data-warehouses/databases easily using any of the growing list of CQ destination plugins.
As a sidenote: this can also simplify/replace the following just by maintaing one plugin:
Best,
Yevgeny
We want to be able to create Document type Items with files in them via the Connect API.
With the growth of Automation Environments and, for example, Kubernetes Operators that use them, the need also grows to be able to automate the setup of a Vault with all the right items for an environment. Currently that can only be done for Password type Items, see #45.
I understand there's currently no backend endpoint to support this, and that it's in your backlog. ๐ This issue is just to track the need and allow people to give it a thumbs up.
Yes, we hire someone expensive to click a few hundred times through the desktop app to create Document type Items. ๐
As mentioned above, see #45, but also search for Scripting (Document type)
here: https://external-secrets.io/v0.5.3/provider-1password-automation/
SDK Version: 1.3.0
Connect Server Version: Will update once I find out (client issue, probably doesn't matter)
OS: MacOS 12.4
Go Version: 1.18.3
There was a HTTP 502 Bad Gateway error on http requests to the machine running the Connect server.
Instead of checking the http response code and returning an appropriate error, I received the following error:
import (
onePasswordConnect "github.com/1Password/connect-sdk-go/connect"
)
func reproduceError(url string, token string, vault string, item string) {
onePasswordClient := onePasswordConnect.NewClient(url, token)
onePasswordItem, err := onePasswordClient.GetItem(item, vault) // <-- returns decoding error
}
coding error response: invalid character '<' looking for beginning of value
goroutine 1 [running]:
/somepackage/onepassword.getFile({PARAMS OMITTED FOR PRIVACY})
...
This is caused by the following function, which expects all HTTP responses with a non-ok code to contain a json body, and returns a decoding error otherwise:
connect-sdk-go/connect/client.go
Line 841 in 327898c
Unexpected HTTP status codes return a descriptive error. Gracefully handle the http error response body not containing a JSON body.
connect.GetItem
If you'd like a PR to fix this, I can work on it.
Instead of only returning the status code to the user of the SDK, it would be helpful if the SDK also returned the error message returned by Connect, if available.
This makes it way easier to debug problems, especially validations issues.
If you currently try to create a new Item, but it does not adhere to the required structure, you only get this response:
Unable to create item. Receieved "400 Bad Request" for "/v1/vaults/UUID/items "
I propose two possible solutions:
Unable to create item. Receieved "400 Bad Request" for "/v1/vaults/UUID/items": Validation: (validateVaultItem failed to Validate), Couldn't validate the item: "[ItemValidator] has found 1 errors, 0 warnings: \nErrors:{1. details.sections[0].fields[0] has unsupported field type}"
The second option is a little more involved, but I think it's the most flexible to work with and is my preferred option.
Currently when making an Item, you need to specify a purpose for a field to make sure it is used in autofill (e.g. username and password fields). However, it can be a bit tricky to know by heart what the right purpose is for each field.
Therefore, we want to add the constants for supported field purposes, according to the API spec.
onepassword/items.go
type ItemFieldPurpose string
const (
FieldPurposeUsername ItemFieldPurpose = "USERNAME"
FieldPurposePassword ItemFieldPurpose = "PASSWORD"
FieldPurposeNotes ItemFieldPurpose = "NOTES"
)
Purpose
property of the ItemFiled
struct to have the new type. (line 109)
// ItemField Representation of a single field on an Item
type ItemField struct {
ID string `json:"id"`
Section *ItemSection `json:"section,omitempty"`
Type string `json:"type"`
Purpose ItemFieldPurpose `json:"purpose,omitempty"`
Label string `json:"label,omitempty"`
Value string `json:"value,omitempty"`
Generate bool `json:"generate,omitempty"`
Recipe *GeneratorRecipe `json:"recipe,omitempty"`
Entropy float64 `json:"entropy,omitempty"`
TOTP string `json:"totp,omitempty"`
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.