Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
9102d2e
A good start on HTTPS uploads, to simplify manifest transfers.
jeff-cohere Aug 31, 2026
21f813e
Troubleshooting https PUT method of Globus access.
jeff-cohere Sep 1, 2026
847525c
Separating transfer and HTTPS access token logic.
jeff-cohere Sep 2, 2026
2da7097
Implemented changes to support manifest transfers without a dedicated…
jeff-cohere Sep 2, 2026
84cecd8
Adding kbase_lakehouse package.
jeff-cohere Aug 26, 2026
b314752
Adding access token to user struct for conveyance downstream if/where…
jeff-cohere Aug 31, 2026
f5a1828
Starting to wrestle with lakehouse auth issues.
jeff-cohere Aug 28, 2026
d42563b
Worked up an MMS proxy.
jeff-cohere Sep 3, 2026
c726d3c
Closing the loop on credentials and the KBase MMS.
jeff-cohere Sep 4, 2026
fb66930
Reorganizing Globus requests, and adding logic to register ancillary …
jeff-cohere Sep 9, 2026
33c13c2
Rephrased interoperability interface.
jeff-cohere Sep 9, 2026
de13941
Interim commit. Factoring out Globus APIs for clarity.
jeff-cohere Sep 10, 2026
39f2bec
Factored out Globus logic to understand things better.
jeff-cohere Sep 10, 2026
fa723ca
Minor fixes and a version bump.
jeff-cohere Sep 11, 2026
aa11b2f
HTTPS uploads now work properly and have improved error checking.
jeff-cohere Sep 11, 2026
e65b1c2
Fixed static analysis errors caught by CI.
jeff-cohere Sep 11, 2026
5d1d52a
Removing stubbed kbase_lakehouse tests.
jeff-cohere Sep 11, 2026
c9c7a9c
Changed root: to base_path: in various configs.
jeff-cohere Sep 11, 2026
2aa7dc3
Patched up an endpoint test
jeff-cohere Sep 11, 2026
889dece
Addressed code review comments.
jeff-cohere Sep 11, 2026
dd23b56
DTS now checks for existing S3 credentials and updates as needed.
jeff-cohere Sep 14, 2026
4a76621
Addressed remaining code review comments.
jeff-cohere Sep 14, 2026
f6bff15
Addressing some additional feedback.
jeff-cohere Sep 14, 2026
42b95ab
Using storage gateway policies to determine Globus connector provider.
jeff-cohere Sep 15, 2026
241610a
Switching out MinIO GitHub action.
jeff-cohere Sep 15, 2026
e57b79d
Updating to tagged version of MinIO GitHub action.
jeff-cohere Sep 15, 2026
f8fbad6
Addressing static analysis errors.
jeff-cohere Sep 15, 2026
10e2730
Switching bucket to basepath from datapath for S3 endpoints.
jeff-cohere Sep 15, 2026
b3dfb55
Addressing some testing issues.
jeff-cohere Sep 15, 2026
8cdd7ec
Swapping S3 base/data path.
jeff-cohere Sep 15, 2026
90c198b
Changing some roots/base_paths to data_paths.
jeff-cohere Sep 15, 2026
0fedd83
A couple more test fixes.
jeff-cohere Sep 15, 2026
3e7cdef
A fix for a fix.
jeff-cohere Sep 15, 2026
d8e5098
A few more minor fixes.
jeff-cohere Sep 15, 2026
955a551
Fixed a glitch in setting source endpoints for new transfers.
jeff-cohere Sep 16, 2026
d4395f8
Fixing a mock test condition.
jeff-cohere Sep 16, 2026
ebbd669
Final fix for the mock test.
jeff-cohere Sep 16, 2026
5c181ae
One more final fix.
jeff-cohere Sep 16, 2026
8ae5bfd
Repurposed existing KBase user federation approach for Lakehouse.
jeff-cohere Sep 16, 2026
65a1ea4
Fixed an oversight in the deployment config file.
jeff-cohere Sep 17, 2026
368ace0
Registered kbase_lakehouse database with service.
jeff-cohere Sep 18, 2026
d9d3f66
Threading user credentials through transfer requests.
jeff-cohere Sep 21, 2026
db262a7
Some debugging text and some cleanup.
jeff-cohere Sep 21, 2026
15e40d4
Fixing an oversight in determination of endpoint provider.
jeff-cohere Sep 21, 2026
b142c4d
A bit more debugging info
jeff-cohere Sep 21, 2026
7bc0727
Typo fix
jeff-cohere Sep 21, 2026
c59d8c3
More debugging
jeff-cohere Sep 21, 2026
34c864f
More breadcrumbs
jeff-cohere Sep 21, 2026
8ad8346
One last try for today.
jeff-cohere Sep 22, 2026
4fb0ba8
Debugging.
jeff-cohere Sep 22, 2026
6359493
Improving error propagation
jeff-cohere Sep 22, 2026
a1cb94d
Whoopsy
jeff-cohere Sep 22, 2026
cf9300a
Scope experiment
jeff-cohere Sep 22, 2026
c4bc14e
Updating GCS manager auth scope
jeff-cohere Sep 22, 2026
9fea9b7
Simplifying mechanism to determine S3 capability
jeff-cohere Sep 22, 2026
a73d28d
More debugging.
jeff-cohere Sep 22, 2026
9551a4e
Minor tweak
jeff-cohere Sep 22, 2026
9213e32
Another experiment.
jeff-cohere Sep 22, 2026
29f738a
Flipping a bit.
jeff-cohere Sep 22, 2026
a2a1b1c
Again.
jeff-cohere Sep 22, 2026
0eda402
Trying another thing.
jeff-cohere Sep 22, 2026
5a5d4f4
Another.
jeff-cohere Sep 22, 2026
404cb98
Another permutation
jeff-cohere Sep 22, 2026
7aa5324
One more try.
jeff-cohere Sep 22, 2026
31ec0d2
A fix.
jeff-cohere Sep 22, 2026
3937d46
Trying something else.
jeff-cohere Sep 22, 2026
2a66b56
Moving forward.
jeff-cohere Sep 22, 2026
f523e3b
Debugging
jeff-cohere Sep 22, 2026
8b351db
And again
jeff-cohere Sep 22, 2026
ac28d7b
Printing stuff.
jeff-cohere Sep 22, 2026
64c0915
Re-establishing GCS manager API auth flow
jeff-cohere Sep 23, 2026
df69b12
Modifying GCS client auth scopes.
jeff-cohere Sep 24, 2026
759e32f
Trying 'nonfunctional endpoint' for GCS manager API access.
jeff-cohere Sep 24, 2026
045d863
Adding an error check.
jeff-cohere Sep 24, 2026
b8ebe52
Fixing some marshalling issues.
jeff-cohere Sep 24, 2026
52bd522
Addressing more GCS issues.
jeff-cohere Sep 24, 2026
204e90b
Addressing a few more issues.
jeff-cohere Sep 24, 2026
964a8f4
Instrumenting GCS errors with diagnostics.
jeff-cohere Sep 25, 2026
df70635
Attempting S3 cred registration on multiple gateways.
jeff-cohere Sep 25, 2026
e3977ec
Updating to community-maintained MinIO image.
jeff-cohere Sep 25, 2026
9242a4e
Adding a Globus ID column to the KBase user federation logic.
jeff-cohere Sep 29, 2026
6f36e16
Connecting the dots for KBase user Globus IDs.
jeff-cohere Sep 29, 2026
e8fb69d
Fixing a merge conflict.
jeff-cohere Sep 29, 2026
8e3ad8c
Eliminating an unused variable.
jeff-cohere Sep 29, 2026
901896c
Removing prints and fixing a bug.
jeff-cohere Sep 29, 2026
0f4fbff
Another try.
jeff-cohere Sep 30, 2026
aa84441
And again.
jeff-cohere Sep 30, 2026
9adc4cf
And again.
jeff-cohere Sep 30, 2026
33182c2
And again.
jeff-cohere Sep 30, 2026
d790073
Fixed.
jeff-cohere Sep 30, 2026
c9d8967
More debugging.
jeff-cohere Sep 30, 2026
70d7e8f
More debugging.
jeff-cohere Sep 30, 2026
c5dfd90
Disabling a test for NMDC data that went bad.
jeff-cohere Sep 30, 2026
fe64493
Again.
jeff-cohere Sep 30, 2026
c4fd773
Fixed a glitch in the new KBase ORCID spreadsheet parser.
jeff-cohere Sep 30, 2026
9792079
Loosening constraints on storage gateways.
jeff-cohere Sep 30, 2026
cff0f17
Trying another thing.
jeff-cohere Sep 30, 2026
358d2e7
Trying again.
jeff-cohere Sep 30, 2026
beb2e99
Trying again.
jeff-cohere Sep 30, 2026
6ef3553
Fixing an issue with mapped usernames.
jeff-cohere Sep 30, 2026
a88bcda
Fixed glitch in finding existing credentials.
jeff-cohere Sep 30, 2026
df8b54b
Trying with hard-wired storage gateway.
jeff-cohere Sep 30, 2026
7a727f5
Whoops.
jeff-cohere Sep 30, 2026
20a882d
Trying some other things.
jeff-cohere Sep 30, 2026
9b55be5
A bit of cleanup, and commenting on the error.
jeff-cohere Sep 30, 2026
4f58f94
Adding more debugging info.
jeff-cohere Sep 30, 2026
3b17352
More debugging info
jeff-cohere Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/autotest_prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
staticcheck ./...

- name: Set up MinIO
uses: infleet/minio-action@v0.0.1
uses: cohere-llc/minio-action@v0.0.3
with:
port: "9000"
version: "latest"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/irods.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@v4

- name: Set up MinIO
uses: infleet/minio-action@v0.0.1
uses: cohere-llc/minio-action@v0.0.3
with:
port: "9000"
version: "latest"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ require a Minio test instance to be running. You can start one with docker
or podman:

```
docker run -d -p 9000:9000 -p 9001:9001 -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin" minio/minio server /data --console-address ":9001"
docker run -d -p 9000:9000 -p 9001:9001 -e "MINIO_ROOT_USER=minioadmin" -e "MINIO_ROOT_PASSWORD=minioadmin" pgsty/minio server /data --console-address ":9001"
```

Then you can run these tests as you would any other Go project:
Expand Down Expand Up @@ -87,4 +87,4 @@ to do:
authenticate with the JGI Data Portal

Alternatively, you can run tests against mock services without the above
environment variables set by setting `DTS_TEST_WITH_MOCK_SERVICES=true`
environment variables set by setting `DTS_TEST_WITH_MOCK_SERVICES=true`
4 changes: 4 additions & 0 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ type User struct {
Organization string
// true if this user is a Superuser
IsSuper bool
// credentials for connections between endpoints with different providers (e.g. Globus <--> S3)
ConnectionCredentials map[string]Credential
Comment thread
jeff-cohere marked this conversation as resolved.
Comment thread
jeff-cohere marked this conversation as resolved.
}

// A credential used for authorization and authentication
type Credential struct {
// the username associated with this credential
Username string `yaml:"username"`
// the ID used for authorization (username or UUID)
Id string `yaml:"id"`
// the secret used for authentication (e.g. password)
Expand Down
11 changes: 6 additions & 5 deletions auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,12 @@ func (a *Authenticator) readAccessTokenFile() error {
}

userRecords[token] = User{
Name: record[0],
Email: record[1],
Orcid: record[2],
Organization: record[3],
IsSuper: isSuper,
Name: record[0],
Email: record[1],
Orcid: record[2],
Organization: record[3],
IsSuper: isSuper,
ConnectionCredentials: make(map[string]Credential),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file-based access-token auth path always creates User with an empty ConnectionCredentials map — it's never populated with S3/Polaris creds the way KBaseAuthServer.User() does. Any deployment relying on file-based tokens (rather than live KBase auth) will fail Globus→S3 bridging silently. Is that intentional (file-token users aren't expected to do Lakehouse transfers), or a gap?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. The KBase auth process is specific to KBase users with tokens, after all--there's no way for someone without a KBase dev token to access the MMS (right?).

}
}

Expand Down
32 changes: 25 additions & 7 deletions auth/kbase_auth_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ func NewKBaseAuthServer(accessToken string, options ...KBaseAuthServerOption) (*
}

// check our list of KBase auth server instances for this access token
if instances == nil {
instances = make(map[string]*KBaseAuthServer)
if instances_ == nil {
instances_ = make(map[string]*KBaseAuthServer)
}
if server, found := instances[accessToken]; found {
if server, found := instances_[accessToken]; found {
return server, nil
} else {
server := KBaseAuthServer{
Expand All @@ -91,7 +91,7 @@ func NewKBaseAuthServer(accessToken string, options ...KBaseAuthServerOption) (*
}

// register this instance of the auth server
instances[accessToken] = &server
instances_[accessToken] = &server
return &server, err
}
}
Expand All @@ -103,8 +103,9 @@ func (server KBaseAuthServer) User() (User, error) {
return User{}, err
}
user := User{
Name: kbUser.Display,
Email: kbUser.Email,
Name: kbUser.Display,
Email: kbUser.Email,
ConnectionCredentials: make(map[string]Credential),
}
for _, pid := range kbUser.Idents {
// grab the first ORCID associated with the user
Expand All @@ -113,6 +114,23 @@ func (server KBaseAuthServer) User() (User, error) {
break
}
}

// try to access the MMS in case we're talking to the KBase Lakehouse
mms := NewMMS()
record, err := mms.FetchRecord(server.AccessToken)
if err == nil {
user.ConnectionCredentials["s3"] = Credential{
Username: record.Username,
Id: record.S3AccessKey,
Secret: record.S3SecretKey,
}
user.ConnectionCredentials["polaris"] = Credential{
Username: record.Username,
Id: record.PolarisClientId,
Secret: record.PolarisClientSecret,
}
}

return user, nil
}

Expand Down Expand Up @@ -155,7 +173,7 @@ type kbaseAuthErrorResponse struct {

// here's a set of instances to the KBase auth server, mapped by OAuth2
// access token
var instances map[string]*KBaseAuthServer
var instances_ map[string]*KBaseAuthServer

// emits an error representing the error in a response to the auth server
func kbaseAuthError(response *http.Response) error {
Expand Down
85 changes: 85 additions & 0 deletions auth/kbase_mms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) 2023 The KBase Project and its Contributors
// Copyright (c) 2023 Cohere Consulting, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

package auth

import (
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)

// The Minio Management Service (MMS) provide authentication information for a user
// given a valid KBase token for that user

type MMSRecord struct {
Username string `json:"username"`
S3AccessKey string `json:"s3_access_key"`
S3SecretKey string `json:"s3_secret_key"`
PolarisClientId string `json:"polaris_client_id"`
PolarisClientSecret string `json:"polaris_client_secret"`
}

type MMS struct {
Client http.Client
}

func NewMMS() MMS {
return MMS{
Client: http.Client{
Timeout: 5 * time.Second,
},
}
}

// retrieves the MMS record associated with the given access token
func (mms MMS) FetchRecord(accessToken string) (MMSRecord, error) {
Comment thread
jeff-cohere marked this conversation as resolved.
resource := fmt.Sprintf("%s:%d", kbaseMMSUrl, kbaseMMSPort) + "/credentials/"
request, err := http.NewRequest(http.MethodGet, resource, http.NoBody)
if err != nil {
return MMSRecord{}, err
}
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))
resp, err := mms.Client.Do(request)
if err != nil {
return MMSRecord{}, err
}
defer resp.Body.Close()
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
return MMSRecord{}, fmt.Errorf("MMS returned HTTP %d", resp.StatusCode)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return MMSRecord{}, err
}

var record MMSRecord
err = json.Unmarshal(body, &record)
return record, err
}

const (
kbaseMMSUrl = "http://mms.dev"
kbaseMMSPort = 8000
)
4 changes: 2 additions & 2 deletions databases/kbase/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func NewDatabase(conf Config) (databases.Database, error) {
EndpointName: conf.Endpoint,
}
var err error
db.kbaseFed, err = newKBaseUserFederation(conf.KBaseUserFederationConfig)
db.kbaseFed, err = NewKBaseUserFederation(conf.KBaseUserFederationConfig)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -107,7 +107,7 @@ func (db *Database) Finalize(orcid string, id uuid.UUID) error {
}

func (db *Database) LocalUser(orcid string) (string, error) {
return db.kbaseFed.usernameForOrcid(orcid)
return db.kbaseFed.UsernameForOrcid(orcid)
}

func (db Database) Save() (databases.DatabaseSaveState, error) {
Expand Down
Loading
Loading