unable to get credentials and initialize API ... read /home/opuser/.op/1password-credentials.json:

I am trying to spin up a basic 1password connect server. I have created my Access Token and Credentials file, spun up a fresh server, loaded the 1password-credentials.json file onto the directory ~/1pass, and placed the example docker-compose.yml file there, then ran docker-compose up (leaving off the -d to see logs). The result is that the API server begins advertizing, but gives a 500 error when we try to perform a basic GET, and the sync server gives the following errors on repeat:

1pass-op-connect-sync-1 | {"log_message":"(I) ### syncer credentials bootstrap ### ","timestamp":"2021-10-22T01:38:10.855503326Z","level":3}
1pass-op-connect-sync-1 | {"log_message":"(E) Server: (unable to get credentials and initialize API, retrying in 30s), Wrapped: (failed to FindCredentialsUniqueKey), Wrapped: (failed to loadCredentialsFile), Wrapped: (LoadLocalAuthV2 failed to credentialsDataFromDisk), read /home/opuser/.op/1password-credentials.json: is a directory","timestamp":"2021-10-22T01:38:10.855634306Z","level":1}

I have seen an error like this before, it appears to think this file is a directory if I'm interpreting it correctly. Looks like that is the directory inside of the container. I have not seen this behavior when searching google for errors pertaining to 1Password Connect server. Any ideas? It's also strange to me that the API server wouldn't be giving similar logs regarding the same file. Here is the docker-compose.yml example provided to me by the getting started page:

version: "3.4"

services:
  op-connect-api:
    image: 1password/connect-api:latest
    ports:
      - "8080:8080"
    volumes:
      - "./1password-credentials.json:/home/opuser/.op/1password-credentials.json"
      - "data:/home/opuser/.op/data"
  op-connect-sync:
    image: 1password/connect-sync:latest
    ports:
      - "8081:8080"
    volumes:
      - "./1password-credentials.json:/home/opuser/.op/1password-credentials.json"
      - "data:/home/opuser/.op/data"

volumes:
  data:

Indeed, I executed into the container and see that this IS a directory. Why is the example container configuration written this way?

opuser@963a30dfde8c:~/.op$ ls -l
total 0
drwxr-xr-x 2 root root 6 Oct 22 00:53 1password-credentials.json
drwx------ 3 opuser root 99 Oct 22 00:53 data

I got the file from this page https://support.1password.com/connect-deploy-docker/#step-2-deploy-a-1password-connect-server
specifically this link https://i.1password.com/media/1password-connect/docker-compose.yaml

These docker volume configurations will mount the file, not the directory, to a path called /home/opuser/.op/1password-credentials.json/ inside the container. There is no file inside of /home/opuser/.op/1password-credentials.json/

On https://github.com/1Password/connect/blob/main/README.md, the docker-compose instructions point to an empty file.

I am getting very lost. Someone please explain why the container is configured to mount a file as a directory, and what a legitimate docker-compose.yml would look like in order to properly build this container, or otherwise where I have gone astray.


1Password Version: Not Provided
Extension Version: Not Provided
OS Version: Amazon_Linux

Comments

  • andy_sks
    andy_sks
    Community Member

    I had 2 more ideas this morning.
    1. Check the GitHub for any other docker-compose.yml examples. None are maintained here...
    2. Try to lower the directory target of the volume (container side). Doing so resulted in this error for both containers:

    Error: Server: (failed to OpenDefault), Wrapped: (failed to defaultPath), failed to ConfigDir: Can't continue. We can't safely access "/home/opuser/.op" because it's not owned by the current user. Change the owner or logged in user and try again.
    

    So, I haven't gotten any further than the original post.

  • andy_sks
    andy_sks
    Community Member
    edited October 2021

    Oh, I found docker-compose.yaml on github. Man, I still will never understand why we settled on 2 file extensions for the same language.

    Anyway, there's no commit history so it's been this way for ages and somehow I don't see others having the same issue deploying a similar config, so still wondering if others have any idea what's causing the problem.

  • andy_sks
    andy_sks
    Community Member

    For kicks and giggles I spun this up on Docker Desktop for Windows, and quickly got the configuration working. So, something must be wrong with my Amazon_Linux configuration. I can try rebuilding this machine to see if the error occurs again. In the meantime, I'll post my configs in case someone else would like to try replicating the issue.

    Terraform Config:

    # Terraform HCL
    
    provider "aws" {
      region = "us-east-1"
      shared_credentials_file = "~/.aws/credentials"
      profile = "default"
    }
    
    resource "aws_security_group" "onepassword_connect_api" {
      name        = "onepassword_connect_api"
      description = "Allow 8080 traffic into 1password API"
    
      ingress = [
        {
          description      = "API"
          from_port        = 8080
          to_port          = 8080
          protocol         = "tcp"
          cidr_blocks      = ["<redacted_ip_address>/32"]
          ipv6_cidr_blocks = []
          prefix_list_ids  = []
          self             = false
          security_groups  = []
        }
      ]
    
      egress = [
        {
          description      = "any"
          from_port        = 0
          to_port          = 0
          protocol         = "-1"
          cidr_blocks      = ["0.0.0.0/0"]
          ipv6_cidr_blocks = []
          prefix_list_ids  = []
          self             = false
          security_groups  = []
        }
      ]
    
      tags = {
        Name = "onepassword_connect_api"
        name = "onepassword_connect_api"
      }
    }
    
    
    resource "aws_instance" "use1vl1pc" {
      ami           = "ami-087c17d1fe0178315"
      instance_type = "t2.micro"
      availability_zone = "us-east-1d"
      key_name = "<redacted_key_name>"
    
      vpc_security_group_ids = [
        "<redacted_security_group_id>",
        "${aws_security_group.onepassword_connect_api.id}"
      ]
    
      tags = {
        name = "use1vl1pc"
        description = "1Password Connect server, allows our applications to use 1Password Vaults"
        Name = "use1vl1pc"
        project = "internal"
      }
    }
    
    resource "aws_eip" "use1vl1pc_EIP" {
      instance = "${aws_instance.use1vl1pc.id}"
      vpc = true
      tags = {
        name = "use1vl1pc_EIP"
        ec2Target = "use1vl1pc"
        project = "internal"
      }
    }
    

    There you can see the AMI I'm using if you just want to build it manually. Then I run a shell script because I'm still working on Configuration Management for this company.

    1password_connect_setup.sh

    #!/bin/bash
    sudo yum update -y
    
    sudo yum install -y tmux yum-utils git
    
    # install Docker Engine, Amazon Linux 2
    sudo amazon-linux-extras install -y docker
    sudo systemctl enable docker && sudo systemctl start docker
    if groups | grep -q docker; then
        echo "ec2-user is already part of the docker group"
    else
        echo "adding ec2-user to docker group"
        sudo usermod -aG docker ec2-user && sudo su - ec2-user #enable ec2-user to use docker without sudo
    fi
    #sudo docker run hello-world  #test if docker runs ok
    
    # install docker-compose Amazon Linux 2
    sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    docker-compose version
    
    # install 1password connect
    mkdir -p ~/1pass
    cd ~/1pass
      # add something here to download the repository
    docker-compose up -d
    
  • In the Docker Compose example config that we've published, we're using the Docker Compose feature to specify files as volumes (i.e. the 1password-credentials.json file). There's a small downside of that approach though, and is that if the file is not present or can't be found for whatever reason, Docker Compose won't fail, but will just continue and interpret the specified file as a directory instead.

    So you'll have to make sure the 1password-credentials.json file is in the very same directory where you're running docker-compose up from. (And I don't see anything in your script around the credentials file, but maybe that's in the part you left out?)

This discussion has been closed.