geofront.server
— Key management service¶
Although Geofront provides geofront-server, a CLI to run the server, it also provides an interface as a WSGI application as well. Note that there might some limitations like lack of periodical master key renewal.
First of all, the server need a configuration, there are several ways to configure it.
app.config.from_pyfile()
If you can freely execute arbitrary Python code before start the server, the method is the most straightforward way to configure the server. Note that the argument should be an absolute path, because it interprets paths relative to the path of Geofront program, not the current working directory (CWD).
There also are other methods as well:
GEOFRONT_CONFIG
If you can’t execute any arbitrary Python code, set the
GEOFRONT_CONFIG
environment variable. It’s useful when to use a CLI frontend of the WSGI server e.g. gunicorn, waitress-serve.$ GEOFRONT_CONFIG="/etc/geofront.cfg.py" gunicorn geofront.server:app
Then you can run a Geofront server using your favorite WSGI server. Pass the following WSGI application object to the server. It’s a documented endpoint for WSGI:
-
geofront.server.
AUTHORIZATION_TIMEOUT
= datetime.timedelta(0, 60)¶ (
datetime.timedelta
) How long does each temporary authorization keep alive after it’s issued. A minute.
-
class
geofront.server.
FingerprintConverter
(*args, **kwargs)¶ Werkzeug custom converter which accepts valid public key fingerprints.
-
class
geofront.server.
Token
(identity, expires_at)¶ The named tuple type that stores a token.
-
expires_at
¶ Alias for field number 1
-
identity
¶ Alias for field number 0
-
-
class
geofront.server.
TokenIdConverter
(*args, **kwargs)¶ Werkzeug custom converter which accepts valid token ids.
-
geofront.server.
add_public_key
(token_id: str)¶ Register a public key to the token. It takes an OpenSSH public key line through the request content body.
POST /tokens/0123456789abcdef/keys/ HTTP/1.1 Accept: application/json Content-Type: text/plain ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q==
HTTP/1.1 201 Created Content-Type: text/plain Location: /tokens/0123456789abcdef/keys/50:5a:9a:12:75:8b:b0:88:7d:7a:8d:66:29:63:d0:47 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q==
Parameters: token_id ( str
) – the token id that holds the identityStatus 201: when key registration is successful Status 400: ( unsupported-key-type
) when the key type is unsupported, or (invalid-key
) the key format is invalid, or (deuplicate-key
) the key is already usedStatus 415: ( unsupported-content-type
) when the Content-Type is not text/plain
-
geofront.server.
app
= <Flask 'geofront.server'>¶ (
flask.Flask
) The WSGI application of the server.
-
geofront.server.
authenticate
(token_id: str)¶ Finalize the authentication process. It will be shown on web browser.
Parameters: token_id ( str
) – token id created bycreate_access_token()
Status 400: when authentication is failed Status 404: when the given token_id
doesn’t existStatus 403: when the token_id
is already finalizedStatus 200: when authentication is successfully done
Temporarily authorize the token owner to access a remote. A made authorization keeps alive in a minute, and then will be expired.
POST /tokens/0123456789abcdef/remotes/web-1/ HTTP/1.1 Accept: application/json Content-Length: 0
HTTP/1.1 200 OK Content-Type: application/json { "success": "authorized", "remote": {"user": "ubuntu", "host": "192.168.0.5", "port": 22}, "expires_at": "2014-04-14T14:57:49.822844+00:00" }
Parameters: Status 200: when successfully granted a temporary authorization
Status 404: (
not-found
) when there’s no such remote
-
geofront.server.
create_access_token
(token_id: str)¶ Create a new access token.
PUT /tokens/0123456789abcdef/ HTTP/1.1 Accept: application/json Content-Length: 0
HTTP/1.1 202 Accepted Content-Type: application/json Date: Tue, 15 Apr 2014 03:44:43 GMT Expires: Tue, 15 Apr 2014 04:14:43 GMT Link: <https://example.com/login/page/?redirect_uri=...>; rel=next { "next_url": "https://example.com/login/page/?redirect_uri=..." }
Parameters: token_id ( str
) – an arbitrary token id to create. it should be enough random to avoid duplicationStatus 202: when the access token is prepared Resheader Link: the link owner’s browser should redirect to
-
geofront.server.
delete_public_key
(token_id: str, fingerprint: bytes)¶ Delete a public key.
DELETE /tokens/0123456789abcdef/keys/50:5a:9a:12:75:8b:b0:88:7d:7a:8d:66:29:63:d0:47/ HTTP/1.1 Accept: application/json
HTTP/1.1 200 OK Content-Type: application/json { "72:00:60:24:66:e8:2d:4d:2a:2a:a2:0e:7b:7f:fc:af": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCom2CDLekY...5CeYsvSdrTWA5 ", "78:8a:09:c8:c1:24:5c:89:76:92:b0:1e:93:95:5d:48": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA16iSKKjFHOgj...kD62SYXNKY9c= ", "ab:3a:fb:30:44:e3:5e:1e:10:a0:c9:9a:86:f4:67:59": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzzF8c07pzgKk...r+b6Q9VnWWQ== " }
Parameters: Status 200: when the public key is successfully deleted
Status 404: (
not-found
) when there’s no such public key
-
geofront.server.
get_identity
(token_id: str) → geofront.identity.Identity¶ Get the identity object from the given
token_id
.Parameters: token_id ( str
) – the token id to get the identity it holdsReturns: the identity the token holds Return type: Identity
Raises: werkzeug.exceptions.HTTPException – 404 Not Found ( token-not-found
) when the token does not exist. 412 Precondition Failed (unfinished-authentication
) when the authentication process is not finished yet. 410 Gone (expired-token
) when the token was expired. 403 Forbidden (not-authorized
) when the token is not unauthorized.
-
geofront.server.
get_key_store
() → geofront.keystore.KeyStore¶ Get the configured key store implementation.
Returns: the configured key store Return type: KeyStore
Raises: RuntimeError – when 'KEY_STORE'
is not configured, or it’s not an instance ofKeyStore
-
geofront.server.
get_master_key_store
() → geofront.masterkey.MasterKeyStore¶ Get the configured master key store implementation.
Returns: the configured master key store Return type: MasterKeyStore
Raises: RuntimeError – when 'MASTER_KEY_STORE'
is not configured, or it’s not an instance ofMasterKeyStore
-
geofront.server.
get_permission_policy
() → geofront.remote.PermissionPolicy¶ Get the configured permission policy.
Returns: the configured permission policy Return type: PermissionPolicy
Raises: RuntimeError – if 'PERMISSION_POLICY'
is not configured, or it’s not an instance ofPermissionPolicy
New in version 0.2.0.
-
geofront.server.
get_public_key
(token_id: str, fingerprint: bytes) → paramiko.pkey.PKey¶ Internal function to find the public key by its
fingerprint
.Parameters: Returns: the found public key
Return type: Raises: werkzeug.exceptions.HTTPException – (
not-found
) when there’s no such public key
-
geofront.server.
get_remote_set
() → typing.Mapping[str, geofront.remote.Remote]¶ Get the configured remote set.
Returns: the configured remote set Return type: RemoteSet
Raises: RuntimeError – if 'REMOTE_SET'
is not configured, or it’s not a mapping object
-
geofront.server.
get_team
() → geofront.team.Team¶ Get the configured team implementation, an instance of
team.Team
.It raises
RuntimeError
if'TEAM'
is not configured.
-
geofront.server.
get_token_store
() → werkzeug.contrib.cache.BaseCache¶ Get the configured token store, an instance of
werkzeug.contrib.cache.BaseCache
.It raises
RuntimeError
if'TOKEN_STORE'
is not configured, but it just warnsRuntimeWarning
when it comes to debug mode.Returns: the configured session store Return type: werkzeug.contrib.cache.BaseCache
Raises: RuntimeError – when 'TOKEN_STORE'
is not configured, or the value is not an instance ofwerkzeug.contrib.cache.BaseCache
-
geofront.server.
list_public_keys
(token_id: str)¶ List registered keys to the token owner.
GET /tokens/0123456789abcdef/keys/ HTTP/1.1 Accept: application/json
HTTP/1.1 200 OK Content-Type: application/json { "50:5a:9a:12:75:8b:b0:88:7d:7a:8d:66:29:63:d0:47": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q== ", "72:00:60:24:66:e8:2d:4d:2a:2a:a2:0e:7b:7f:fc:af": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCom2CDLekY...5CeYsvSdrTWA5 ", "78:8a:09:c8:c1:24:5c:89:76:92:b0:1e:93:95:5d:48": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA16iSKKjFHOgj...kD62SYXNKY9c= ", "ab:3a:fb:30:44:e3:5e:1e:10:a0:c9:9a:86:f4:67:59": "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzzF8c07pzgKk...r+b6Q9VnWWQ== " }
Parameters: token_id ( str
) – the token id that holds the identityStatus 200: when listing is successful, even if there are no keys
-
geofront.server.
main
()¶ The main function for geofront-server CLI program.
-
geofront.server.
main_parser
() → argparse.ArgumentParser¶ Create an
ArgumentParser
object for geofront-server CLI program. It also is used for documentation through sphinxcontrib-autoprogram.Returns: a properly configured ArgumentParser
Return type: argparse.ArgumentParser
-
geofront.server.
master_key
()¶ Public part of the master key in OpenSSH authorized_keys (public key) format.
GET /masterkey/ HTTP/1.1 Accept: text/plain
HTTP/1.1 200 OK Content-Type: text/plain ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q==
Status 200: when the master key is available Status 500: when the master key is unavailable
-
geofront.server.
public_key
(token_id: str, fingerprint: bytes)¶ Find the public key by its
fingerprint
if it’s registered.GET /tokens/0123456789abcdef/keys/50:5a:9a:12:75:8b:b0:88:7d:7a:8d:66:29:63:d0:47/ HTTP/1.1 Accept: text/plain
HTTP/1.1 200 OK Content-Type: text/plain ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q==
Parameters: Status 200: when the public key is registered
Status 404: (
not-found
) when there’s no such public key
-
geofront.server.
remote_dict
(remote: geofront.remote.Remote) → typing.Mapping[str, typing.Union[str, int]]¶ Convert a
remote
to a simple dictionary that can be serialized to JSON.Parameters: remote ( Remote
) – a remote instance to serializeReturns: the converted dictionary Return type: Mapping
[Union
[str
,int
]]
-
geofront.server.
server_endpoint
()¶ The endpoint of HTTP API which provide the url to create a new token.
GET / HTTP/1.1 Accept: application/json
HTTP/1.0 200 OK Content-Type: application/json Link: <https://example.com/tokens/>; rel=tokens Link: <https://example.com/masterkey/>; rel=masterkey { "master_key_url": "https://example.com/masterkey/", "tokens_url": "https://example.com/tokens/" }
Resheader Link: the url to create a new token. the equivalent to the response content Status 200: when the server is available New in version 0.4.0: Added
"master_key_url"
field in the result and Link header ofrel=masterkey
.New in version 0.2.0.
-
geofront.server.
server_version
(response: flask.wrappers.Response) → flask.wrappers.Response¶ Indicate the version of Geofront server using Server and X-Geofront-Version headers.
-
geofront.server.
token
(token_id: str)¶ The owner identity that the given token holds if the token is authenticated. Otherwise it responds 403 Forbidden, 404 Not Found, 410 Gone, or 412 Precondition Failed. See also
get_identity()
.GET /tokens/0123456789abcdef/ HTTP/1.1 Accept: application/json
HTTP/1.0 200 OK Content-Type: application/json Link: <https://example.com/tokens/0123456789abcdef/remo...>; rel=remotes Link: <https://example.com/tokens/0123456789abcdef/keys/>; rel=keys Link: <https://example.com/masterkey/>; rel=masterkey { "identifier": "dahlia", "team_type": "geofront.backends.github.GitHubOrganization", "remotes_url": "https://example.com/tokens/0123456789abcdef/remotes/", "keys_url": "https://example.com/tokens/0123456789abcdef/keys/", "master_key_url": "https://example.com/masterkey/" }
Parameters: token_id ( str
) – the token id that holds the identityResheader Link: the url to list remotes ( rel=remotes
), public keys (rel=keys
), and master key (rel=masterkey
)Status 200: when the token is authenticated Changed in version 0.2.0: The response contains
"remotes_url"
,"keys_url"
, and"master_key_url"
, and equivalent three Link headers.
-
geofront.server.
token_master_key
(token_id: str)¶ Public part of the master key in OpenSSH authorized_keys (public key) format.
GET /tokens/0123456789abcdef/masterkey/ HTTP/1.1 Accept: text/plain
HTTP/1.1 301 Moved Permanently Content-Type: text/plain ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAEMUvjBcX.../MuLLzC/m8Q==
Parameters: token_id ( str
) – the token id that holds the identityStatus 200: when the master key is available Status 500: when the master key is unavailable Deprecated since version 4.0.0: Use
GET /masterkey/
instead.Changed in version 4.0.0: It now responds with 301 Moved Permanently instead of 200 OK. It redirects to
GET /masterkey/
which is the new master key url.
-
geofront.server.
url_for
(endpoint, **kwargs)¶ The almost same to
flask.url_for()
except it’s sensitive toPREFERRED_URL_SCHEME
configuration.