I would like to know if providing temporary url to access AWS bucket objects are secured in a sense that it discloses the AWS Access Key.
From my knowing if using IAM user's access key for accessing AWS bucket rather than root Access key can be highly secured if the IAM user is only permitted to read/write S3 services.
Are there any disadvantages of providing temporary url to the public using IAM user's access key?
Regards.
Presigning a URL doesn't give away your private key (secret), so there is no risk. An attacker couldn't take a signed URL and alter it to do something else, as the signature verifies the original payload.
You are correct: it's considered good practice to lock down IAM profiles to specific tasks, such as a specific application environment.
According to the official AWS docs:
We strongly recommend that you do not use the root user for your
everyday tasks, even the administrative ones. Instead, adhere to the
best practice of using the root user only to create your first IAM
user. Then securely lock away the root user credentials and use them
to perform only a few account and service management tasks.
Your disadvantages question isn't clear to me, so I'll answer two ways I think you might have meant it:
Tailored IAM profiles over root:
No disadvantage. Requires a bit more time and awareness to plan your policy / permission requirements, but that's a good thing.
Pre-signed URLs over conventional uploads / downloads
This depends on your use-case. Generally speaking, there are no extra security considerations when using presigned URLs. Just set a realistic expire time and don't give it to the wrong person. It's a lot like a session / bearer token that way.
In terms of advantages, they open up doors to make your application more scalable, and removes the need for your application to waste cycles "watching" an authorized upload or download. Vapor (Laravel 6 on Lambda) promotes presigned URLs as a feature for file uploads.
Related
I want to use the Direct Mail SDK(Java) directly within client application which is distributed across. The way to authenticate users within the application, I need to provide access keys as below,
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<your accessKey>", "<your accessSecret>");
How can I prevent user to know the Access Keys and still prevent the need of third-party API? Is it possible?
First, it is bad practice to code an application that requires secrets that runs on the client. You should manage everything on the server and provide an API that the client software interfaces with.
Second, there is no way to hide those credentials once passed to the client. You could encrypt the credentials but at some point the client application will need to decrypt them. Even amateur programmers can figure out how you are processing your credentials.
Ignoring the above advice, Alibaba Cloud supports STS which provides temporary access keys. Using your Alibaba credentials, you would call AssumeRole which creates temporary access keys giving the user permission call DirectMail. You can limit the time that the credentials are valid. The range is 900 to 3600 seconds. After that duration the keys become invalid.
Keep in mind that 900 seconds is a long time. A bad actor getting access to those keys could send thousands of emails using your account. Therefore implement strong user authentication, STS and temporary access keys.
If you think that just keeping your interface secret is enough, don't. There are millions of script kiddies on the Internet poking at every IP address. Launch a new ECS instance and you will see attacks within hours.
As you said since it is a Java Web Application(assuming), currently I think of something using similar to JBOSS Vault to store the access keys securely.
If it is some standalone client application still you can use some encryption methodologies to store the data. But this will only prevent easy access to the data/keys. But it is not impossible. The best bet would be creating another third-party API
Getting a bit lost in the diverse documentation endpoints (here, here, to name a few…)
This one is pretty usable for a given account by providing a json key as an environment variable.
The thing is, I just don't see how commands can be run on the behalf of a user authenticated via oauth — practically speaking, where do you specify the oauth user token ?
Thanks for sharing this insight
Best
google-cloud-ruby (which you linked in your question) is designed to provide access via service account credentials, as you noted. For help with "lower-level" access in which you managing your own OAuth tokens, you might consider google-auth-library-ruby. However, if you can use a service account instead of a user account to use the higher-level access provided by google-cloud-ruby, I believe it's probably the best approach, as recommended in Google Cloud Storage Authentication:
Due to the complexity of managing and refreshing access tokens and the security risk when dealing directly with cryptographic applications, we strongly encourage you to use a verified client library.
Normally I would add the secret key as an environment variable, but what is the best way to do it in Parse?
The Parse config functionality doesn't solve my problem because the secret key would be available on the client side. There are not security mechanisms to prevent access to specific config variables.
The only solution I can think of, is creating a class to store this really sensitive information and add security so it can not be accessed from a client application (or by certain users).
I don't love this solution because it adds extra requests each time the secret key is needed, which is bad in terms of response time and request usage limits/cost.
In AWS ..
You can use role based authentication using AWS SDK, where it get the role of you resource (ECS, EC2) and retrieve access and secret key from resource registry.
which is a similar implementation you mentioned in your post. That is quite helpful to provide security for your access key and secret, where you don't have to parse or get it from ENV as that can be compromise any time.
Also resource registry based key keep on changing over time so if anybody gets that also can't use it.
You can try to check the implementation how AWS resource / role based authentication works for AWS SDK.
They don't want to give me their Amazon username and password because it has their complete purchase history.
Is there anyway for them to authorize me as a user?
Amazon has AWS Identity and Access Management, that should help with what your asking. http://aws.amazon.com/iam/
It's easy enough to create new accounts on Amazon, and it's also reasonable to keep corporate and personal accounts separate for expense purposes. I'd recommend doing that for simplicity, but I understand that it could be a concern regarding potential misuse on the rest of the Amazon site.
The use of access keys (as suggested by #KristianGlass) may be adequate, as well, allowing you to create and kill instances, but not allowing you access to the main AWS console. Elasticfox also works with the EC2 keys, so you could use that as a surrogate for the console.
Depending on what you're looking for, they might just be able to create you an Access Key and have you use that.
If they look under "Security Credentials" in their Account page (this should be a link to it) they can easily "Create a new Access Key" (they will of course need to give you both the Access Key ID and the Secret Access Key).
To paraphrase Amazon's documentation about Access Keys, you can use them for making requests to REST or Query APIs - specifically this includes EC2.
We are working on a service that will have website access for stats and other tasks, but the majority of use will be through a client gem and rake tasks. What is the best way to handle authentication for both pieces.
It looks like fiveruns_tuneup, getexceptional, New Relic and others have websites with username and pass, but use API keys stored in ./config/serviceName.yml Any reasons it is better to have API keys opposed to user/pass in the config (do they use keys because often the key is checked into SCM and used across the project, where ours would not be checked in and would be a per user setting)
GitHub has you put your public key on the github servers and uses that, but I think git supports public/private key by default.
Would it be preferred to keep a ./config/serviceName.yml or since we have to create a subdirectory with other information have ./serviceName/config.yml? (does the per user, not stored in SCM mean it is better to keep it all in one excluded directory?)
Just looking for some thoughts and ideas on best practices before starting implementation.
I recommend that you use username/password combos for website accounts, and API keys for any web services. Here are the advantages of this technique:
By linking API keys to an account, you could have many API keys for the same user. Perhaps this could be used for many remote web servers that consume this data service, or to perform unique tracking.
Attaching API keys to an account also lets you keep the user's username and password uncompromised since an API key will not contain them. Many users use the same username and password on many services, so you are helping to protect them.
You could limit access to portions of functionality for each API key, but give their username access to everything their account should have access to. Additionally, you can even give them the ability to limit how much access an API key might have.
Most of the major services (Yahoo! API, Flickr, Google API, etc) use accounts with a username and password to login to the web account, and API keys for integration points.
Never use user/pass when you can help it. The security issues are horrible. If the user/pass leaks out, you have to change your password or they get access to your whole account.
API keys are better because they're easier to change and can be limited to only the part you need access to with the APIs (ie, if someone has your password they can change your password. They can't if they just have an API key).
Different API key per client or secure token exchange (such as OAuth) is the best solution if you'll have more than just your client on the API.
The github approach is bootstrapping on top of existing git practices, however it's not a bad idea since presumably each user will have their own private key to match a published public one in the central authority. Since key-agent's already furnish a means of safe authentication this seems like a very safe approach. Public/private keys are a well thought out authentication scheme, which has unfortunately been reinvented many times to limited success.
The problem with the API key is that anyone who gets a copy of the API key can do whatever that authorizes. Storing the API key somewhere in the project begs the users to share a key. If you are associating public keys with a user, it is possible to grant rights to the client on a per user basis, and a proper key-agent approach suggests that those will not be stored in an SCM anywhere.
I'm not sure I follow what the distinction between config/serviceName.yml, or serviceName/config.yml is. It doesn't seem as if it would be pertinent if you have public/private keys as an authentication method for the client.